|
|
|
@ -1,15 +1,20 @@ |
|
|
|
using System; |
|
|
|
using System.Collections; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.ComponentModel; |
|
|
|
using System.Text.RegularExpressions; |
|
|
|
using Avalonia.Controls; |
|
|
|
using Avalonia.Controls.Selection; |
|
|
|
using Avalonia.VisualTree; |
|
|
|
|
|
|
|
namespace Avalonia.Diagnostics.ViewModels |
|
|
|
{ |
|
|
|
internal class TreePageViewModel : ViewModelBase, IDisposable |
|
|
|
internal class TreePageViewModel : ViewModelBase, IDisposable, INotifyDataErrorInfo |
|
|
|
{ |
|
|
|
private readonly Dictionary<string, string> _errors = new Dictionary<string, string>(); |
|
|
|
private TreeNode _selectedNode; |
|
|
|
private ControlDetailsViewModel _details; |
|
|
|
private string _propertyFilter; |
|
|
|
private string _propertyFilter = string.Empty; |
|
|
|
private bool _useRegexFilter; |
|
|
|
|
|
|
|
public TreePageViewModel(MainViewModel mainView, TreeNode[] nodes) |
|
|
|
{ |
|
|
|
@ -26,15 +31,10 @@ namespace Avalonia.Diagnostics.ViewModels |
|
|
|
get => _selectedNode; |
|
|
|
private set |
|
|
|
{ |
|
|
|
if (Details != null) |
|
|
|
{ |
|
|
|
_propertyFilter = Details.PropertyFilter; |
|
|
|
} |
|
|
|
|
|
|
|
if (RaiseAndSetIfChanged(ref _selectedNode, value)) |
|
|
|
{ |
|
|
|
Details = value != null ? |
|
|
|
new ControlDetailsViewModel(value.Visual, _propertyFilter) : |
|
|
|
new ControlDetailsViewModel(this, value.Visual) : |
|
|
|
null; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -54,6 +54,63 @@ namespace Avalonia.Diagnostics.ViewModels |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Regex FilterRegex { get; set; } |
|
|
|
|
|
|
|
private void UpdateFilterRegex() |
|
|
|
{ |
|
|
|
void ClearError() |
|
|
|
{ |
|
|
|
if (_errors.Remove(nameof(PropertyFilter))) |
|
|
|
{ |
|
|
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(PropertyFilter))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (UseRegexFilter) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
FilterRegex = new Regex(PropertyFilter, RegexOptions.Compiled); |
|
|
|
ClearError(); |
|
|
|
} |
|
|
|
catch (Exception exception) |
|
|
|
{ |
|
|
|
_errors[nameof(PropertyFilter)] = exception.Message; |
|
|
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(PropertyFilter))); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
ClearError(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public string PropertyFilter |
|
|
|
{ |
|
|
|
get => _propertyFilter; |
|
|
|
set |
|
|
|
{ |
|
|
|
if (RaiseAndSetIfChanged(ref _propertyFilter, value)) |
|
|
|
{ |
|
|
|
UpdateFilterRegex(); |
|
|
|
Details.PropertiesView.Refresh(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public bool UseRegexFilter |
|
|
|
{ |
|
|
|
get => _useRegexFilter; |
|
|
|
set |
|
|
|
{ |
|
|
|
if (RaiseAndSetIfChanged(ref _useRegexFilter, value)) |
|
|
|
{ |
|
|
|
UpdateFilterRegex(); |
|
|
|
Details.PropertiesView.Refresh(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void Dispose() |
|
|
|
{ |
|
|
|
foreach (var node in Nodes) |
|
|
|
@ -130,5 +187,17 @@ namespace Avalonia.Diagnostics.ViewModels |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
|
} |
|
|
|
|