Browse Source

Merge branch 'master' into devtools-column-definitions

pull/4587/head
Luis v.d.Eltz 6 years ago
committed by GitHub
parent
commit
47b3b32d96
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  2. 87
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs
  3. 45
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml

29
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs

@ -12,12 +12,13 @@ namespace Avalonia.Diagnostics.ViewModels
private readonly IVisual _control; private readonly IVisual _control;
private readonly IDictionary<object, List<PropertyViewModel>> _propertyIndex; private readonly IDictionary<object, List<PropertyViewModel>> _propertyIndex;
private AvaloniaPropertyViewModel _selectedProperty; private AvaloniaPropertyViewModel _selectedProperty;
private string _propertyFilter;
public ControlDetailsViewModel(IVisual control, string propertyFilter) public ControlDetailsViewModel(TreePageViewModel treePage, IVisual control)
{ {
_control = control; _control = control;
TreePage = treePage;
var properties = GetAvaloniaProperties(control) var properties = GetAvaloniaProperties(control)
.Concat(GetClrProperties(control)) .Concat(GetClrProperties(control))
.OrderBy(x => x, PropertyComparer.Instance) .OrderBy(x => x, PropertyComparer.Instance)
@ -25,7 +26,6 @@ namespace Avalonia.Diagnostics.ViewModels
.ToList(); .ToList();
_propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToList()); _propertyIndex = properties.GroupBy(x => x.Key).ToDictionary(x => x.Key, x => x.ToList());
_propertyFilter = propertyFilter;
var view = new DataGridCollectionView(properties); var view = new DataGridCollectionView(properties);
view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group))); view.GroupDescriptions.Add(new DataGridPathGroupDescription(nameof(AvaloniaPropertyViewModel.Group)));
@ -43,19 +43,9 @@ namespace Avalonia.Diagnostics.ViewModels
} }
} }
public DataGridCollectionView PropertiesView { get; } public TreePageViewModel TreePage { get; }
public string PropertyFilter public DataGridCollectionView PropertiesView { get; }
{
get => _propertyFilter;
set
{
if (RaiseAndSetIfChanged(ref _propertyFilter, value))
{
PropertiesView.Refresh();
}
}
}
public AvaloniaPropertyViewModel SelectedProperty public AvaloniaPropertyViewModel SelectedProperty
{ {
@ -137,9 +127,14 @@ namespace Avalonia.Diagnostics.ViewModels
private bool FilterProperty(object arg) private bool FilterProperty(object arg)
{ {
if (!string.IsNullOrWhiteSpace(PropertyFilter) && arg is PropertyViewModel property) if (!string.IsNullOrWhiteSpace(TreePage.PropertyFilter) && arg is PropertyViewModel property)
{ {
return property.Name.IndexOf(PropertyFilter, StringComparison.OrdinalIgnoreCase) != -1; if (TreePage.UseRegexFilter)
{
return TreePage.FilterRegex?.IsMatch(property.Name) ?? true;
}
return property.Name.IndexOf(TreePage.PropertyFilter, StringComparison.OrdinalIgnoreCase) != -1;
} }
return true; return true;

87
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs

@ -1,15 +1,20 @@
using System; using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Selection;
using Avalonia.VisualTree; using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.ViewModels 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 TreeNode _selectedNode;
private ControlDetailsViewModel _details; private ControlDetailsViewModel _details;
private string _propertyFilter; private string _propertyFilter = string.Empty;
private bool _useRegexFilter;
public TreePageViewModel(MainViewModel mainView, TreeNode[] nodes) public TreePageViewModel(MainViewModel mainView, TreeNode[] nodes)
{ {
@ -26,15 +31,10 @@ namespace Avalonia.Diagnostics.ViewModels
get => _selectedNode; get => _selectedNode;
private set private set
{ {
if (Details != null)
{
_propertyFilter = Details.PropertyFilter;
}
if (RaiseAndSetIfChanged(ref _selectedNode, value)) if (RaiseAndSetIfChanged(ref _selectedNode, value))
{ {
Details = value != null ? Details = value != null ?
new ControlDetailsViewModel(value.Visual, _propertyFilter) : new ControlDetailsViewModel(this, value.Visual) :
null; 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() public void Dispose()
{ {
foreach (var node in Nodes) foreach (var node in Nodes)
@ -130,5 +187,17 @@ namespace Avalonia.Diagnostics.ViewModels
return null; 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;
} }
} }

45
src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml

@ -2,24 +2,31 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:Avalonia.Diagnostics.Converters" xmlns:conv="clr-namespace:Avalonia.Diagnostics.Converters"
x:Class="Avalonia.Diagnostics.Views.ControlDetailsView"> x:Class="Avalonia.Diagnostics.Views.ControlDetailsView">
<Grid ColumnDefinitions="*"> <Grid ColumnDefinitions="*,Auto" RowDefinitions="Auto,*">
<DockPanel Grid.Column="0">
<TextBox DockPanel.Dock="Top" <TextBox Grid.Row="0" Grid.Column="0"
BorderThickness="0" BorderThickness="0"
Text="{Binding PropertyFilter}" Text="{Binding TreePage.PropertyFilter}"
Watermark="Filter properties"/> Watermark="Filter properties" />
<DataGrid Items="{Binding PropertiesView}"
BorderThickness="0" <CheckBox Grid.Row="0"
RowBackground="Transparent" Grid.Column="1"
SelectedItem="{Binding SelectedProperty, Mode=TwoWay}" Content="Regex"
CanUserResizeColumns="true"> IsChecked="{Binding TreePage.UseRegexFilter}"/>
<DataGrid.Columns>
<DataGridTextColumn Header="Property" Binding="{Binding Name}" IsReadOnly="True"/> <DataGrid Items="{Binding PropertiesView}"
<DataGridTextColumn Header="Value" Binding="{Binding Value}"/> Grid.Row="1" Grid.ColumnSpan="2"
<DataGridTextColumn Header="Type" Binding="{Binding Type}"/> BorderThickness="0"
<DataGridTextColumn Header="Priority" Binding="{Binding Priority}" IsReadOnly="True"/> RowBackground="Transparent"
</DataGrid.Columns> SelectedItem="{Binding SelectedProperty, Mode=TwoWay}"
</DataGrid> CanUserResizeColumns="true">
</DockPanel> <DataGrid.Columns>
<DataGridTextColumn Header="Property" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}" />
<DataGridTextColumn Header="Priority" Binding="{Binding Priority}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</Grid> </Grid>
</UserControl> </UserControl>

Loading…
Cancel
Save