Add support for Category, Name, and Description to PropertyGrid using DisplayAttribute

This commit is contained in:
Brant Martin
2018-02-11 22:43:22 -05:00
parent 04e949ed0c
commit c32badb750
3 changed files with 136 additions and 78 deletions

View File

@@ -118,7 +118,7 @@
</StackPanel>
<Button Grid.Row="1" Content="Save Config" Margin="3" Click="Save_OnClick" />
</Grid>
<views:PropertyGrid Grid.Column="1" Margin="3" DataContext="{Binding SessionSettings}" />
<views:PropertyGrid Grid.Column="1" Margin="3" DataContext="{Binding SessionSettings}" IgnoreDisplay ="True" />
<GridSplitter Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Stretch" ShowsPreview="True"
Width="2" Background="Gray" />
</Grid>

View File

@@ -9,6 +9,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
@@ -19,5 +20,6 @@
<TextBox Grid.Column="1" Margin="3" TextChanged="UpdateFilter"/>
</Grid>
<ScrollViewer Grid.Row="1" x:Name="ScrollViewer"/>
<TextBlock x:Name="TbDescription" Grid.Row="2" MinHeight="18" Background="#FFBBB9B9"/>
</Grid>
</UserControl>

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
@@ -29,6 +30,14 @@ namespace Torch.Views
{
private Dictionary<Type, Grid> _viewCache = new Dictionary<Type, Grid>();
public static readonly DependencyProperty IgnoreDisplayProperty = DependencyProperty.Register("IgnoreDisplay", typeof(bool), typeof(PropertyGrid));
public bool IgnoreDisplay
{
get => (bool)base.GetValue(IgnoreDisplayProperty);
set => base.SetValue(IgnoreDisplayProperty, value);
}
public PropertyGrid()
{
InitializeComponent();
@@ -59,26 +68,66 @@ namespace Torch.Views
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var categories = new Dictionary<string, List<PropertyInfo>>();
var descriptors = new Dictionary<PropertyInfo, DisplayAttribute>(properties.Length);
foreach (var property in properties)
{
var a = property.GetCustomAttribute<DisplayAttribute>();
if (IgnoreDisplay)
a = null;
descriptors[property] = a;
string category = a?.GroupName ?? "Misc";
if (!categories.TryGetValue(category, out List<PropertyInfo> l))
{
l = new List<PropertyInfo>();
categories[category] = l;
}
l.Add(property);
}
var curRow = 0;
foreach (var property in properties.OrderBy(x => x.Name))
foreach (var c in categories.OrderBy(x => x.Key))
{
grid.RowDefinitions.Add(new RowDefinition());
var cl = new TextBlock
{
Text = c.Key,
VerticalAlignment = VerticalAlignment.Center
};
cl.SetValue(Grid.ColumnProperty, 0);
cl.SetValue(Grid.ColumnSpanProperty, 2);
cl.SetValue(Grid.RowProperty, curRow);
cl.Margin = new Thickness(3);
cl.FontWeight = FontWeights.Bold;
grid.Children.Add(cl);
curRow++;
c.Value.Sort((a,b)=> string.Compare((descriptors[a]?.Name ?? a.Name), descriptors[b]?.Name ?? b.Name, StringComparison.Ordinal));
foreach (var property in c.Value)
{
if (property.GetGetMethod() == null)
continue;
grid.RowDefinitions.Add(new RowDefinition());
var displayName = property.GetCustomAttribute<DisplayAttribute>()?.Name;
var descriptor = descriptors[property];
var displayName = descriptor?.Name;
var propertyType = property.PropertyType;
var text = new TextBlock
{
Text = property.Name,
Text = displayName ?? property.Name,
ToolTip = displayName,
VerticalAlignment = VerticalAlignment.Center
};
text.SetValue(Grid.ColumnProperty, 0);
text.SetValue(Grid.RowProperty, curRow);
text.Margin = new Thickness(3);
text.Tag = $"{text.Text}: {descriptor?.Description}";
text.IsMouseDirectlyOverChanged += Text_IsMouseDirectlyOverChanged;
grid.Children.Add(text);
FrameworkElement valueControl;
@@ -158,15 +207,22 @@ namespace Torch.Views
valueControl.VerticalAlignment = VerticalAlignment.Center;
valueControl.SetValue(Grid.ColumnProperty, 1);
valueControl.SetValue(Grid.RowProperty, curRow);
valueControl.IsMouseDirectlyOverChanged += Text_IsMouseDirectlyOverChanged;
grid.Children.Add(valueControl);
curRow++;
}
}
_viewCache.Add(t, grid);
return grid;
}
private void Text_IsMouseDirectlyOverChanged(object sender, DependencyPropertyChangedEventArgs e)
{
TbDescription.Text = (sender as FrameworkElement)?.Tag?.ToString() ?? string.Empty;
}
private void EditDictionary(object dict)
{
var dic = (IDictionary)dict;