3 changed files with 131 additions and 88 deletions
@ -0,0 +1,124 @@ |
|||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel; |
||||
|
using System.Text.RegularExpressions; |
||||
|
|
||||
|
namespace Avalonia.Diagnostics.ViewModels |
||||
|
{ |
||||
|
internal class FilterViewModel : ViewModelBase, INotifyDataErrorInfo |
||||
|
{ |
||||
|
private readonly Dictionary<string, string> _errors = new Dictionary<string, string>(); |
||||
|
private string _propertyFilter = string.Empty; |
||||
|
private bool _useRegexFilter, _useCaseSensitiveFilter, _useWholeWordFilter; |
||||
|
private string _processedFilter; |
||||
|
private Regex _filterRegex; |
||||
|
|
||||
|
public event EventHandler RefreshFilter; |
||||
|
|
||||
|
public bool Filter(string input) |
||||
|
{ |
||||
|
return _filterRegex?.IsMatch(input) ?? true; |
||||
|
} |
||||
|
|
||||
|
private void UpdateFilterRegex() |
||||
|
{ |
||||
|
void ClearError() |
||||
|
{ |
||||
|
if (_errors.Remove(nameof(PropertyFilter))) |
||||
|
{ |
||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(PropertyFilter))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_processedFilter = PropertyFilter.Trim(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
var options = RegexOptions.Compiled; |
||||
|
var pattern = UseRegexFilter |
||||
|
? _processedFilter : Regex.Escape(_processedFilter); |
||||
|
if (!UseCaseSensitiveFilter) |
||||
|
{ |
||||
|
options |= RegexOptions.IgnoreCase; |
||||
|
} |
||||
|
if (UseWholeWordFilter) |
||||
|
{ |
||||
|
pattern = $"\\b(?:{pattern})\\b"; |
||||
|
} |
||||
|
|
||||
|
_filterRegex = new Regex(pattern, options); |
||||
|
ClearError(); |
||||
|
} |
||||
|
catch (Exception exception) |
||||
|
{ |
||||
|
_errors[nameof(PropertyFilter)] = exception.Message; |
||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(PropertyFilter))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string PropertyFilter |
||||
|
{ |
||||
|
get => _propertyFilter; |
||||
|
set |
||||
|
{ |
||||
|
if (RaiseAndSetIfChanged(ref _propertyFilter, value)) |
||||
|
{ |
||||
|
UpdateFilterRegex(); |
||||
|
RefreshFilter?.Invoke(this, EventArgs.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public bool UseRegexFilter |
||||
|
{ |
||||
|
get => _useRegexFilter; |
||||
|
set |
||||
|
{ |
||||
|
if (RaiseAndSetIfChanged(ref _useRegexFilter, value)) |
||||
|
{ |
||||
|
UpdateFilterRegex(); |
||||
|
RefreshFilter?.Invoke(this, EventArgs.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public bool UseCaseSensitiveFilter |
||||
|
{ |
||||
|
get => _useCaseSensitiveFilter; |
||||
|
set |
||||
|
{ |
||||
|
if (RaiseAndSetIfChanged(ref _useCaseSensitiveFilter, value)) |
||||
|
{ |
||||
|
UpdateFilterRegex(); |
||||
|
RefreshFilter?.Invoke(this, EventArgs.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public bool UseWholeWordFilter |
||||
|
{ |
||||
|
get => _useWholeWordFilter; |
||||
|
set |
||||
|
{ |
||||
|
if (RaiseAndSetIfChanged(ref _useWholeWordFilter, value)) |
||||
|
{ |
||||
|
UpdateFilterRegex(); |
||||
|
RefreshFilter?.Invoke(this, EventArgs.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public IEnumerable GetErrors(string propertyName) |
||||
|
{ |
||||
|
if (_errors.TryGetValue(propertyName, out var error)) |
||||
|
{ |
||||
|
yield return error; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public bool HasErrors => _errors.Count > 0; |
||||
|
|
||||
|
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue