port from perforce
This commit is contained in:
56
hgplus/bliss/Tweaky/PropertyGrid/EditorTemplateSelector.cs
Normal file
56
hgplus/bliss/Tweaky/PropertyGrid/EditorTemplateSelector.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Tweaky.PropertyGrid
|
||||
{
|
||||
public class EditorTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public EditorTemplateSelector()
|
||||
{
|
||||
defaultDataTemplate = new DataTemplate() { VisualTree = new FrameworkElementFactory(typeof(DefaultEditor)) };
|
||||
}
|
||||
|
||||
private DataTemplate defaultDataTemplate;
|
||||
public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
|
||||
{
|
||||
if (item == null)
|
||||
return defaultDataTemplate;
|
||||
|
||||
if (!(item is PropertyItem))
|
||||
return defaultDataTemplate;
|
||||
|
||||
var pd = (item as PropertyItem).PropertyDescriptor;
|
||||
var editorAttribute = pd.Attributes.OfType<EditorAttribute>().LastOrDefault();
|
||||
|
||||
if (editorAttribute != null)
|
||||
{
|
||||
var editorType = Type.GetType(editorAttribute.EditorTypeName);
|
||||
if (typeof(FrameworkElement).IsAssignableFrom(editorType))
|
||||
return new DataTemplate() { VisualTree = new FrameworkElementFactory(editorType) };
|
||||
}
|
||||
|
||||
if (pd.PropertyType.IsEnum)
|
||||
{
|
||||
return new DataTemplate() { VisualTree = new FrameworkElementFactory(typeof(EnumEditor)) };
|
||||
}
|
||||
else if (pd.PropertyType == typeof(System.Drawing.Color))
|
||||
{
|
||||
return new DataTemplate() { VisualTree = new FrameworkElementFactory(typeof(FloatArrayColorEditor)) };
|
||||
}
|
||||
else if (pd.PropertyType == typeof(float4))
|
||||
{
|
||||
return new DataTemplate() { VisualTree = new FrameworkElementFactory(typeof(Float4Editor)) };
|
||||
}
|
||||
|
||||
return defaultDataTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
158
hgplus/bliss/Tweaky/PropertyGrid/PropertyGrid.xaml
Normal file
158
hgplus/bliss/Tweaky/PropertyGrid/PropertyGrid.xaml
Normal file
@@ -0,0 +1,158 @@
|
||||
<UserControl x:Class="Tweaky.PropertyGrid.PropertyGrid"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:pg="clr-namespace:Tweaky.PropertyGrid"
|
||||
xmlns:t="clr-namespace:Tweaky"
|
||||
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
|
||||
mc:Ignorable="d"
|
||||
x:Name="Me"
|
||||
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance Type={x:Type t:DataViewModel}}" >
|
||||
|
||||
<UserControl.Resources>
|
||||
<pg:EditorTemplateSelector x:Key="EditorTemplateSelector" />
|
||||
<Style x:Key="ClearFilterButtonStyle" TargetType="{x:Type Button}">
|
||||
<Setter Property="Foreground" Value="{DynamicResource ForegroundGradient}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Grid Background="{DynamicResource PseudoTransparent}">
|
||||
<Border x:Name="hoverBorder" CornerRadius="2" BorderBrush="{DynamicResource SeparatingBorder}" BorderThickness="1" Background="{DynamicResource ForegroundGradient}" Visibility="Collapsed" />
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="hoverBorder" Property="Visibility" Value="Visible" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter TargetName="hoverBorder" Property="Background" Value="{DynamicResource BrightGradient}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<CollectionViewSource Source="{Binding PropertyItems, ElementName=Me}" x:Key="collectionView" Filter="CollectionViewSource_Filter" CollectionViewType="ListCollectionView">
|
||||
<CollectionViewSource.SortDescriptions>
|
||||
<scm:SortDescription PropertyName="Category" Direction="Ascending" />
|
||||
<scm:SortDescription PropertyName="Index" Direction="Ascending" />
|
||||
</CollectionViewSource.SortDescriptions>
|
||||
<CollectionViewSource.GroupDescriptions>
|
||||
<PropertyGroupDescription PropertyName="Category" />
|
||||
</CollectionViewSource.GroupDescriptions>
|
||||
</CollectionViewSource>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.RowSpan="2" Background="{DynamicResource BarGradient}" />
|
||||
<StackPanel Orientation="Horizontal" Margin="13,0,0,2">
|
||||
<TextBlock Foreground="{DynamicResource Foreground}" Text="{Binding ItemsSourceName, ElementName=Me}" MinWidth="50" Margin="0,1,0,0" TextBlock.FontWeight="Bold" VerticalAlignment="Center" />
|
||||
<TextBlock Foreground="{DynamicResource Foreground}" Text="{Binding ItemsSourceType, ElementName=Me}" Margin="5,1,0,0" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Name="searchBoxContainer" Grid.Row="1" Margin="4" BorderThickness="1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="Search:" VerticalAlignment="Center" Margin="3,0" Foreground="{DynamicResource Foreground}" />
|
||||
<TextBox Grid.Column="1" Text="{Binding Filter, ElementName=Me, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="2" CanContentScroll="False">
|
||||
<ItemsControl x:Name="PART_PropertyItemsControl" IsTabStop="False" Focusable="False" VerticalAlignment="Top" ItemsSource="{Binding Source={StaticResource collectionView}}">
|
||||
<ItemsControl.Resources>
|
||||
<Style TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource {x:Type ScrollViewer}}">
|
||||
<Setter Property="HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="VerticalScrollBarVisibility" Value="Hidden" />
|
||||
<Setter Property="CanContentScroll" Value="False" />
|
||||
</Style>
|
||||
</ItemsControl.Resources>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<VirtualizingStackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.ContainerStyle>
|
||||
<Style TargetType="{x:Type GroupItem}">
|
||||
<Setter Property="Control.Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Border>
|
||||
<Expander IsExpanded="True">
|
||||
<Expander.Header>
|
||||
<TextBlock Foreground="{DynamicResource Foreground}" Text="{Binding Name}" />
|
||||
</Expander.Header>
|
||||
<ItemsPresenter Margin="10,0,0,0" />
|
||||
</Expander>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</GroupStyle.ContainerStyle>
|
||||
</GroupStyle>
|
||||
</ItemsControl.GroupStyle>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type pg:PropertyItem}">
|
||||
<Border x:Name="MainBorder" ContextMenuService.Placement="Bottom" SnapsToDevicePixels="True" UseLayoutRounding="False" Background="{DynamicResource PseudoTransparent}" PreviewMouseDown="PropertyItem_PreviewMouseDown">
|
||||
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border Name="PART_Name" VerticalAlignment="Stretch" Margin="0,0,0,1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="10" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" Foreground="{DynamicResource Foreground}" />
|
||||
<TextBlock VerticalAlignment="Center" Text=":" Foreground="{DynamicResource Foreground}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Name="PART_Editor" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10,0,1,0">
|
||||
<ContentPresenter ContentTemplateSelector="{StaticResource EditorTemplateSelector}" Content="{Binding}" SnapsToDevicePixels="True" UseLayoutRounding="False" />
|
||||
<!--<TextBox Name="PART_ValueContainer" MaxLines="1" PreviewMouseWheel="PART_ValueContainer_PreviewMouseWheel" Text="{Binding Value, Mode=TwoWay}" Focusable="False" IsTabStop="False" IsEnabled="{Binding IsReadOnly, Converter={StaticResource InvBooleanToVisibilityConverter}}" TextOptions.TextFormattingMode="Display" />-->
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<DataTemplate.Triggers>
|
||||
<Trigger Property="UIElement.IsMouseOver" Value="True">
|
||||
<Setter TargetName="MainBorder" Property="Border.Background" Value="{DynamicResource LightGradient}" />
|
||||
</Trigger>
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="True">
|
||||
<Setter TargetName="MainBorder" Property="Border.Background" Value="{DynamicResource BrightGradient}" />
|
||||
</DataTrigger>
|
||||
<!--<Trigger Property="UIElement.IsEnabled" Value="False">
|
||||
<Setter TargetName="PART_ValueContainer" Value="{DynamicResource DisabledForegroundBrush}" Property="Control.Foreground" />
|
||||
</Trigger>-->
|
||||
<Trigger Property="Validation.HasError" Value="True">
|
||||
<Setter Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" Property="FrameworkElement.ToolTip" />
|
||||
</Trigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<GridSplitter Grid.Row="3" Height="5" ResizeBehavior="PreviousAndNext" HorizontalAlignment="Stretch" Background="{DynamicResource PseudoTransparent}" ResizeDirection="Rows" />
|
||||
<StackPanel Grid.Row="4" Margin="0,0,0,5">
|
||||
<TextBlock Foreground="{DynamicResource Foreground}" Padding="2 2 2 0" TextBlock.FontWeight="Bold" Text="{Binding SelectedPropertyItem.Name, ElementName=Me}" />
|
||||
<TextBlock Foreground="{DynamicResource Foreground}" Padding="5 2 2 0" TextWrapping="WrapWithOverflow" Text="{Binding SelectedPropertyItem.Description, ElementName=Me}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
172
hgplus/bliss/Tweaky/PropertyGrid/PropertyGrid.xaml.cs
Normal file
172
hgplus/bliss/Tweaky/PropertyGrid/PropertyGrid.xaml.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Tweaky.PropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PropertyGrid.xaml
|
||||
/// </summary>
|
||||
public partial class PropertyGrid : UserControl, INotifyPropertyChanged
|
||||
{
|
||||
public PropertyGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
PropertyItems = new ObservableCollection<PropertyItem>();
|
||||
LeftColumn = new GridLength(150, GridUnitType.Pixel);
|
||||
RightColumn = new GridLength(1, GridUnitType.Star);
|
||||
}
|
||||
|
||||
public ObservableCollection<PropertyItem> PropertyItems
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public GridLength LeftColumn
|
||||
{
|
||||
get;
|
||||
[Notify]
|
||||
set;
|
||||
}
|
||||
|
||||
public GridLength RightColumn
|
||||
{
|
||||
get;
|
||||
[Notify]
|
||||
set;
|
||||
}
|
||||
|
||||
private string filter;
|
||||
public string Filter
|
||||
{
|
||||
get
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
[Notify]
|
||||
set
|
||||
{
|
||||
filter = value;
|
||||
(this.Resources["collectionView"] as CollectionViewSource).View.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyItem SelectedPropertyItem
|
||||
{
|
||||
get { return (PropertyItem)this.GetValue(SelectedPropertyItemProperty); }
|
||||
[Notify]
|
||||
set { this.SetValue(SelectedPropertyItemProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty SelectedPropertyItemProperty = DependencyProperty.Register("SelectedPropertyItem", typeof(PropertyItem), typeof(PropertyGrid), new FrameworkPropertyMetadata(null));
|
||||
|
||||
public string ItemsSourceType
|
||||
{
|
||||
get { return (string)this.GetValue(ItemsSourceTypeProperty); }
|
||||
[Notify]
|
||||
set { this.SetValue(ItemsSourceTypeProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register("ItemsSourceType", typeof(string), typeof(PropertyGrid), new FrameworkPropertyMetadata(null));
|
||||
|
||||
public string ItemsSourceName
|
||||
{
|
||||
get { return (string)this.GetValue(ItemsSourceNameProperty); }
|
||||
[Notify]
|
||||
set { this.SetValue(ItemsSourceNameProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty ItemsSourceNameProperty = DependencyProperty.Register("ItemsSourceName", typeof(string), typeof(PropertyGrid), new FrameworkPropertyMetadata(null));
|
||||
|
||||
public object ItemsSource
|
||||
{
|
||||
get { return this.GetValue(ItemsSourceProperty); }
|
||||
[Notify]
|
||||
set { this.SetValue(ItemsSourceProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(object), typeof(PropertyGrid), new FrameworkPropertyMetadata(null, OnItemsSourceChanged));
|
||||
|
||||
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var me = d as PropertyGrid;
|
||||
if (me != null)
|
||||
{
|
||||
if (e.OldValue != null && e.OldValue is INotifyPropertyChanged)
|
||||
(e.OldValue as INotifyPropertyChanged).PropertyChanged -= me.PropertyGrid_PropertyChanged;
|
||||
|
||||
UpdatePropertyItems(me.ItemsSource, me.PropertyItems);
|
||||
me.RaisePropertyChanged(null);
|
||||
|
||||
if (e.NewValue != null && e.NewValue is INotifyPropertyChanged)
|
||||
(e.NewValue as INotifyPropertyChanged).PropertyChanged += me.PropertyGrid_PropertyChanged;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyGrid_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "Properties")
|
||||
{
|
||||
UpdatePropertyItems(ItemsSource, PropertyItems);
|
||||
RaisePropertyChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdatePropertyItems(object itemsSource, IList<PropertyItem> propertyItems)
|
||||
{
|
||||
propertyItems.Clear();
|
||||
int index = 0;
|
||||
if (itemsSource != null)
|
||||
{
|
||||
var properties = (itemsSource is ICustomTypeDescriptor) ? (itemsSource as ICustomTypeDescriptor).GetProperties() : TypeDescriptor.GetProperties(itemsSource);
|
||||
foreach (PropertyDescriptor pd in properties.Cast<PropertyDescriptor>())
|
||||
{
|
||||
var browsableAttribute = pd.Attributes.OfType<BrowsableAttribute>().FirstOrDefault();
|
||||
if (browsableAttribute != null && !browsableAttribute.Browsable)
|
||||
continue;
|
||||
|
||||
propertyItems.Add(new PropertyItem(itemsSource, index++, pd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public void RaisePropertyChanged(string propertyName)
|
||||
{
|
||||
if (PropertyChanged != null)
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
|
||||
{
|
||||
e.Accepted = string.IsNullOrEmpty(this.Filter) || (e.Item as PropertyItem).Name.ToLower().Contains(this.Filter.ToLower());
|
||||
}
|
||||
|
||||
public void PropertyItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var pi = (sender as FrameworkElement).DataContext as PropertyItem;
|
||||
if (this.SelectedPropertyItem == pi)
|
||||
return;
|
||||
|
||||
if (pi != null)
|
||||
{
|
||||
if (this.SelectedPropertyItem != null)
|
||||
this.SelectedPropertyItem.IsSelected = false;
|
||||
|
||||
pi.IsSelected = true;
|
||||
this.SelectedPropertyItem = pi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
148
hgplus/bliss/Tweaky/PropertyGrid/PropertyItem.cs
Normal file
148
hgplus/bliss/Tweaky/PropertyGrid/PropertyItem.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Tweaky.PropertyGrid
|
||||
{
|
||||
public class PropertyItem : DependencyObject, INotifyPropertyChanged
|
||||
{
|
||||
public PropertyItem(object source, int index, PropertyDescriptor pd)
|
||||
{
|
||||
this.PropertyDescriptor = pd;
|
||||
this.Instance = source;
|
||||
this.Index = index;
|
||||
this.PropertyItems = new ObservableCollectionEx<PropertyItem>();
|
||||
if (source is INotifyPropertyChanged)
|
||||
(source as INotifyPropertyChanged).PropertyChanged += Source_PropertyChanged;
|
||||
|
||||
var categoryAttribute = pd.Attributes.OfType<CategoryAttribute>().FirstOrDefault();
|
||||
var descriptionAttribute = pd.Attributes.OfType<DescriptionAttribute>().FirstOrDefault();
|
||||
var displayNameAttribute = pd.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault();
|
||||
var readOnlyAttribute = pd.Attributes.OfType<ReadOnlyAttribute>().FirstOrDefault();
|
||||
Category = categoryAttribute == null ? "Misc" : categoryAttribute.Category;
|
||||
Description = descriptionAttribute == null ? "" : descriptionAttribute.Description;
|
||||
Name = displayNameAttribute == null ? pd.Name : displayNameAttribute.DisplayName;
|
||||
if (!pd.IsReadOnly && (readOnlyAttribute == null || !readOnlyAttribute.IsReadOnly))
|
||||
{
|
||||
IsReadOnly = false;
|
||||
BindingOperations.SetBinding(this, ValueProperty, new Binding() { Source = source, Path = new PropertyPath(pd.Name) });
|
||||
}
|
||||
else
|
||||
{
|
||||
IsReadOnly = true;
|
||||
BindingOperations.SetBinding(this, ValueProperty, new Binding() { Source = source, Path = new PropertyPath(pd.Name), Mode = BindingMode.OneWay });
|
||||
}
|
||||
}
|
||||
|
||||
void Source_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == this.PropertyDescriptor.Name || string.IsNullOrEmpty(e.PropertyName))
|
||||
RaisePropertyChanged("Value");
|
||||
}
|
||||
|
||||
public int Index
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public PropertyItem Parent
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public object Instance
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public PropertyDescriptor PropertyDescriptor
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Category
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool IsEditable
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsExpanded
|
||||
{
|
||||
get;
|
||||
[Notify]
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get;
|
||||
[Notify]
|
||||
set;
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get { return this.GetValue(ValueProperty); }
|
||||
[Notify]
|
||||
set { this.SetValue(ValueProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(PropertyItem), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged));
|
||||
|
||||
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var pi = (d as PropertyItem);
|
||||
pi.RaisePropertyChanged("Value");
|
||||
(pi.Instance as ViewModelBase).RaisePropertyChanged("Name");
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
public void RaisePropertyChanged(string propertyName)
|
||||
{
|
||||
if (PropertyChanged != null)
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public ObservableCollectionEx<PropertyItem> PropertyItems
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user