You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1293 lines
40 KiB
1293 lines
40 KiB
/*************************************************************************************
|
|
|
|
Extended WPF Toolkit
|
|
|
|
Copyright (C) 2007-2013 Xceed Software Inc.
|
|
|
|
This program is provided to you under the terms of the Microsoft Public
|
|
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
|
|
|
|
For more features, controls, and fast professional support,
|
|
pick up the Plus Edition at http://xceed.com/wpf_toolkit
|
|
|
|
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|
|
|
***********************************************************************************/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Controls.Primitives;
|
|
using System.Windows.Data;
|
|
using System.Windows.Input;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid.Commands;
|
|
using System.Collections.Specialized;
|
|
using System.Windows.Media;
|
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
|
using System.Collections.ObjectModel;
|
|
using System.Collections;
|
|
using Xceed.Wpf.Toolkit.Core.Utilities;
|
|
using System.Reflection;
|
|
using System.Linq.Expressions;
|
|
using System.Windows.Markup;
|
|
|
|
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
|
{
|
|
[TemplatePart( Name = PART_DragThumb, Type = typeof( Thumb ) )]
|
|
[TemplatePart( Name = PART_PropertyItemsControl, Type = typeof( PropertyItemsControl ) )]
|
|
[StyleTypedProperty( Property = "PropertyContainerStyle", StyleTargetType = typeof( PropertyItemBase ) )]
|
|
public class PropertyGrid : Control, ISupportInitialize, IPropertyContainer, INotifyPropertyChanged
|
|
{
|
|
private const string PART_DragThumb = "PART_DragThumb";
|
|
internal const string PART_PropertyItemsControl = "PART_PropertyItemsControl";
|
|
private static readonly ComponentResourceKey SelectedObjectAdvancedOptionsMenuKey = new ComponentResourceKey( typeof( PropertyGrid ), "SelectedObjectAdvancedOptionsMenu" );
|
|
|
|
#region Members
|
|
|
|
private Thumb _dragThumb;
|
|
private bool _hasPendingSelectedObjectChanged;
|
|
private int _initializationCount;
|
|
private ContainerHelperBase _containerHelper;
|
|
private PropertyDefinitionCollection _propertyDefinitions;
|
|
private EditorDefinitionCollection _editorDefinitions;
|
|
private WeakEventListener<NotifyCollectionChangedEventArgs> _propertyDefinitionsListener;
|
|
private WeakEventListener<NotifyCollectionChangedEventArgs> _editorDefinitionsListener;
|
|
|
|
#endregion //Members
|
|
|
|
#region Properties
|
|
|
|
#region AdvancedOptionsMenu
|
|
|
|
public static readonly DependencyProperty AdvancedOptionsMenuProperty = DependencyProperty.Register( "AdvancedOptionsMenu", typeof( ContextMenu ), typeof( PropertyGrid ), new UIPropertyMetadata( null ) );
|
|
public ContextMenu AdvancedOptionsMenu
|
|
{
|
|
get
|
|
{
|
|
return ( ContextMenu )GetValue( AdvancedOptionsMenuProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( AdvancedOptionsMenuProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //AdvancedOptionsMenu
|
|
|
|
#region AutoGenerateProperties
|
|
|
|
public static readonly DependencyProperty AutoGeneratePropertiesProperty = DependencyProperty.Register( "AutoGenerateProperties", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool AutoGenerateProperties
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( AutoGeneratePropertiesProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( AutoGeneratePropertiesProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //AutoGenerateProperties
|
|
|
|
#region ShowDescriptionByTooltip
|
|
|
|
public static readonly DependencyProperty ShowDescriptionByTooltipProperty = DependencyProperty.Register( "ShowDescriptionByTooltip", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool ShowDescriptionByTooltip
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowDescriptionByTooltipProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowDescriptionByTooltipProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowDescriptionByTooltip
|
|
|
|
#region ShowSummary
|
|
|
|
public static readonly DependencyProperty ShowSummaryProperty = DependencyProperty.Register( "ShowSummary", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool ShowSummary
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowSummaryProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowSummaryProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowSummary
|
|
|
|
#region EditorDefinitions
|
|
|
|
public EditorDefinitionCollection EditorDefinitions
|
|
{
|
|
get
|
|
{
|
|
return _editorDefinitions;
|
|
}
|
|
set
|
|
{
|
|
if( _editorDefinitions != value )
|
|
{
|
|
EditorDefinitionCollection oldValue = _editorDefinitions;
|
|
_editorDefinitions = value;
|
|
this.OnEditorDefinitionsChanged( oldValue, value );
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void OnEditorDefinitionsChanged( EditorDefinitionCollection oldValue, EditorDefinitionCollection newValue )
|
|
{
|
|
if( oldValue != null )
|
|
CollectionChangedEventManager.RemoveListener( oldValue, _editorDefinitionsListener );
|
|
|
|
if( newValue != null )
|
|
CollectionChangedEventManager.AddListener( newValue, _editorDefinitionsListener );
|
|
|
|
this.Notify( this.PropertyChanged, () => this.EditorDefinitions );
|
|
}
|
|
|
|
private void OnEditorDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
|
|
{
|
|
_containerHelper.NotifyEditorDefinitionsCollectionChanged();
|
|
}
|
|
|
|
#endregion //EditorDefinitions
|
|
|
|
#region Filter
|
|
|
|
public static readonly DependencyProperty FilterProperty = DependencyProperty.Register( "Filter", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnFilterChanged ) );
|
|
public string Filter
|
|
{
|
|
get
|
|
{
|
|
return ( string )GetValue( FilterProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( FilterProperty, value );
|
|
}
|
|
}
|
|
|
|
private static void OnFilterChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.OnFilterChanged( ( string )e.OldValue, ( string )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnFilterChanged( string oldValue, string newValue )
|
|
{
|
|
// The Filter property affects the resulting FilterInfo of IPropertyContainer. Raise an event corresponding
|
|
// to this property.
|
|
this.Notify( this.PropertyChanged, () => ( ( IPropertyContainer )this ).FilterInfo );
|
|
}
|
|
|
|
#endregion //Filter
|
|
|
|
#region FilterWatermark
|
|
|
|
public static readonly DependencyProperty FilterWatermarkProperty = DependencyProperty.Register( "FilterWatermark", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( "Search" ) );
|
|
public string FilterWatermark
|
|
{
|
|
get
|
|
{
|
|
return ( string )GetValue( FilterWatermarkProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( FilterWatermarkProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //FilterWatermark
|
|
|
|
#region HideInheritedProperties
|
|
|
|
public static readonly DependencyProperty HideInheritedPropertiesProperty = DependencyProperty.Register( "HideInheritedProperties", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool HideInheritedProperties
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( HideInheritedPropertiesProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( HideInheritedPropertiesProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //HideInheritedProperties
|
|
|
|
#region IsCategorized
|
|
|
|
public static readonly DependencyProperty IsCategorizedProperty = DependencyProperty.Register( "IsCategorized", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true, OnIsCategorizedChanged ) );
|
|
public bool IsCategorized
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( IsCategorizedProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( IsCategorizedProperty, value );
|
|
}
|
|
}
|
|
|
|
private static void OnIsCategorizedChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.OnIsCategorizedChanged( ( bool )e.OldValue, ( bool )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnIsCategorizedChanged( bool oldValue, bool newValue )
|
|
{
|
|
this.UpdateThumb();
|
|
}
|
|
|
|
#endregion //IsCategorized
|
|
|
|
#region IsMiscCategoryLabelHidden
|
|
|
|
public static readonly DependencyProperty IsMiscCategoryLabelHiddenProperty = DependencyProperty.Register( "IsMiscCategoryLabelHidden", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool IsMiscCategoryLabelHidden
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( IsMiscCategoryLabelHiddenProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( IsMiscCategoryLabelHiddenProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //IsMiscCategoryLabelHidden
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region NameColumnWidth
|
|
|
|
public static readonly DependencyProperty NameColumnWidthProperty = DependencyProperty.Register( "NameColumnWidth", typeof( double ), typeof( PropertyGrid ), new UIPropertyMetadata( 150.0, OnNameColumnWidthChanged ) );
|
|
public double NameColumnWidth
|
|
{
|
|
get
|
|
{
|
|
return ( double )GetValue( NameColumnWidthProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( NameColumnWidthProperty, value );
|
|
}
|
|
}
|
|
|
|
private static void OnNameColumnWidthChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.OnNameColumnWidthChanged( ( double )e.OldValue, ( double )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnNameColumnWidthChanged( double oldValue, double newValue )
|
|
{
|
|
if( _dragThumb != null )
|
|
( ( TranslateTransform )_dragThumb.RenderTransform ).X = newValue;
|
|
}
|
|
|
|
#endregion //NameColumnWidth
|
|
|
|
#region Properties
|
|
|
|
public IList Properties
|
|
{
|
|
get
|
|
{
|
|
return _containerHelper.Properties;
|
|
}
|
|
}
|
|
|
|
#endregion //Properties
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region PropertyContainerStyle
|
|
|
|
/// <summary>
|
|
/// Identifies the PropertyContainerStyle dependency property
|
|
/// </summary>
|
|
public static readonly DependencyProperty PropertyContainerStyleProperty =
|
|
DependencyProperty.Register( "PropertyContainerStyle", typeof( Style ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnPropertyContainerStyleChanged ) );
|
|
|
|
/// <summary>
|
|
/// Gets or sets the style that will be applied to all PropertyItemBase instances displayed in the property grid.
|
|
/// </summary>
|
|
public Style PropertyContainerStyle
|
|
{
|
|
get { return ( Style )GetValue( PropertyContainerStyleProperty ); }
|
|
set { SetValue( PropertyContainerStyleProperty, value ); }
|
|
}
|
|
|
|
private static void OnPropertyContainerStyleChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
var owner = o as PropertyGrid;
|
|
if( owner != null )
|
|
owner.OnPropertyContainerStyleChanged( ( Style )e.OldValue, ( Style )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnPropertyContainerStyleChanged( Style oldValue, Style newValue )
|
|
{
|
|
}
|
|
|
|
#endregion //PropertyContainerStyle
|
|
|
|
#region PropertyDefinitions
|
|
|
|
public PropertyDefinitionCollection PropertyDefinitions
|
|
{
|
|
get
|
|
{
|
|
return _propertyDefinitions;
|
|
}
|
|
set
|
|
{
|
|
if( _propertyDefinitions != value )
|
|
{
|
|
PropertyDefinitionCollection oldValue = _propertyDefinitions;
|
|
_propertyDefinitions = value;
|
|
this.OnPropertyDefinitionsChanged( oldValue, value );
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void OnPropertyDefinitionsChanged( PropertyDefinitionCollection oldValue, PropertyDefinitionCollection newValue )
|
|
{
|
|
if( oldValue != null )
|
|
CollectionChangedEventManager.RemoveListener( oldValue, _propertyDefinitionsListener );
|
|
|
|
if( newValue != null )
|
|
CollectionChangedEventManager.AddListener( newValue, _propertyDefinitionsListener );
|
|
|
|
this.Notify( this.PropertyChanged, () => this.PropertyDefinitions );
|
|
}
|
|
|
|
private void OnPropertyDefinitionsCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
|
|
{
|
|
_containerHelper.NotifyPropertyDefinitionsCollectionChanged();
|
|
if( this.IsLoaded )
|
|
{
|
|
this.UpdateContainerHelper();
|
|
}
|
|
}
|
|
|
|
#endregion //PropertyDefinitions
|
|
|
|
#region IsReadOnly
|
|
|
|
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool IsReadOnly
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( IsReadOnlyProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( IsReadOnlyProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ReadOnly
|
|
|
|
#region SelectedObject
|
|
|
|
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register( "SelectedObject", typeof( object ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedObjectChanged ) );
|
|
public object SelectedObject
|
|
{
|
|
get
|
|
{
|
|
return ( object )GetValue( SelectedObjectProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( SelectedObjectProperty, value );
|
|
}
|
|
}
|
|
|
|
private static void OnSelectedObjectChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyInspector = o as PropertyGrid;
|
|
if( propertyInspector != null )
|
|
propertyInspector.OnSelectedObjectChanged( ( object )e.OldValue, ( object )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnSelectedObjectChanged( object oldValue, object newValue )
|
|
{
|
|
// We do not want to process the change now if the grid is initializing (ie. BeginInit/EndInit).
|
|
if( _initializationCount != 0 )
|
|
{
|
|
_hasPendingSelectedObjectChanged = true;
|
|
return;
|
|
}
|
|
|
|
this.UpdateContainerHelper();
|
|
|
|
RaiseEvent( new RoutedPropertyChangedEventArgs<object>( oldValue, newValue, PropertyGrid.SelectedObjectChangedEvent ) );
|
|
}
|
|
|
|
#endregion //SelectedObject
|
|
|
|
#region SelectedObjectType
|
|
|
|
public static readonly DependencyProperty SelectedObjectTypeProperty = DependencyProperty.Register( "SelectedObjectType", typeof( Type ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedObjectTypeChanged ) );
|
|
public Type SelectedObjectType
|
|
{
|
|
get
|
|
{
|
|
return ( Type )GetValue( SelectedObjectTypeProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( SelectedObjectTypeProperty, value );
|
|
}
|
|
}
|
|
|
|
private static void OnSelectedObjectTypeChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.OnSelectedObjectTypeChanged( ( Type )e.OldValue, ( Type )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnSelectedObjectTypeChanged( Type oldValue, Type newValue )
|
|
{
|
|
}
|
|
|
|
#endregion //SelectedObjectType
|
|
|
|
#region SelectedObjectTypeName
|
|
|
|
public static readonly DependencyProperty SelectedObjectTypeNameProperty = DependencyProperty.Register( "SelectedObjectTypeName", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( string.Empty ) );
|
|
public string SelectedObjectTypeName
|
|
{
|
|
get
|
|
{
|
|
return ( string )GetValue( SelectedObjectTypeNameProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( SelectedObjectTypeNameProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //SelectedObjectTypeName
|
|
|
|
#region SelectedObjectName
|
|
|
|
public static readonly DependencyProperty SelectedObjectNameProperty = DependencyProperty.Register( "SelectedObjectName", typeof( string ), typeof( PropertyGrid ), new UIPropertyMetadata( string.Empty, OnSelectedObjectNameChanged, OnCoerceSelectedObjectName ) );
|
|
public string SelectedObjectName
|
|
{
|
|
get
|
|
{
|
|
return ( string )GetValue( SelectedObjectNameProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( SelectedObjectNameProperty, value );
|
|
}
|
|
}
|
|
|
|
private static object OnCoerceSelectedObjectName( DependencyObject o, object baseValue )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
{
|
|
if( (propertyGrid.SelectedObject is FrameworkElement) && ( String.IsNullOrEmpty( ( String )baseValue ) ))
|
|
return "<no name>";
|
|
}
|
|
|
|
return baseValue;
|
|
}
|
|
|
|
private static void OnSelectedObjectNameChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.SelectedObjectNameChanged( ( string )e.OldValue, ( string )e.NewValue );
|
|
}
|
|
|
|
protected virtual void SelectedObjectNameChanged( string oldValue, string newValue )
|
|
{
|
|
}
|
|
|
|
#endregion //SelectedObjectName
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region SelectedPropertyItem
|
|
|
|
private static readonly DependencyPropertyKey SelectedPropertyItemPropertyKey = DependencyProperty.RegisterReadOnly( "SelectedPropertyItem", typeof( PropertyItemBase ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedPropertyItemChanged ) );
|
|
public static readonly DependencyProperty SelectedPropertyItemProperty = SelectedPropertyItemPropertyKey.DependencyProperty;
|
|
public PropertyItemBase SelectedPropertyItem
|
|
{
|
|
get
|
|
{
|
|
return ( PropertyItemBase )GetValue( SelectedPropertyItemProperty );
|
|
}
|
|
internal set
|
|
{
|
|
SetValue( SelectedPropertyItemPropertyKey, value );
|
|
}
|
|
}
|
|
|
|
private static void OnSelectedPropertyItemChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
|
{
|
|
PropertyGrid propertyGrid = o as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
propertyGrid.OnSelectedPropertyItemChanged( ( PropertyItemBase )e.OldValue, ( PropertyItemBase )e.NewValue );
|
|
}
|
|
|
|
protected virtual void OnSelectedPropertyItemChanged( PropertyItemBase oldValue, PropertyItemBase newValue )
|
|
{
|
|
if( oldValue != null )
|
|
oldValue.IsSelected = false;
|
|
|
|
if( newValue != null )
|
|
newValue.IsSelected = true;
|
|
|
|
this.SelectedProperty = ( newValue != null ) ? _containerHelper.ItemFromContainer( newValue ) : null;
|
|
|
|
RaiseEvent( new RoutedPropertyChangedEventArgs<PropertyItemBase>( oldValue, newValue, PropertyGrid.SelectedPropertyItemChangedEvent ) );
|
|
}
|
|
|
|
#endregion //SelectedPropertyItem
|
|
|
|
#region SelectedProperty
|
|
|
|
/// <summary>
|
|
/// Identifies the SelectedProperty dependency property
|
|
/// </summary>
|
|
public static readonly DependencyProperty SelectedPropertyProperty =
|
|
DependencyProperty.Register( "SelectedProperty", typeof( object ), typeof( PropertyGrid ), new UIPropertyMetadata( null, OnSelectedPropertyChanged ) );
|
|
|
|
/// <summary>
|
|
/// Gets or sets the selected property or returns null if the selection is empty.
|
|
/// </summary>
|
|
public object SelectedProperty
|
|
{
|
|
get { return ( object )GetValue( SelectedPropertyProperty ); }
|
|
set { SetValue( SelectedPropertyProperty, value ); }
|
|
}
|
|
|
|
private static void OnSelectedPropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs args )
|
|
{
|
|
PropertyGrid propertyGrid = sender as PropertyGrid;
|
|
if( propertyGrid != null )
|
|
{
|
|
propertyGrid.OnSelectedPropertyChanged( ( object )args.OldValue, ( object )args.NewValue );
|
|
}
|
|
}
|
|
|
|
private void OnSelectedPropertyChanged( object oldValue, object newValue )
|
|
{
|
|
// Do not update the SelectedPropertyItem if the Current SelectedPropertyItem
|
|
// item is the same as the new SelectedProperty. There may be
|
|
// duplicate items and the result could be to change the selection to the wrong item.
|
|
object currentSelectedProperty = _containerHelper.ItemFromContainer( this.SelectedPropertyItem );
|
|
if( !object.Equals( currentSelectedProperty, newValue ) )
|
|
{
|
|
this.SelectedPropertyItem = _containerHelper.ContainerFromItem( newValue );
|
|
}
|
|
}
|
|
|
|
#endregion //SelectedProperty
|
|
|
|
#region ShowAdvancedOptions
|
|
|
|
public static readonly DependencyProperty ShowAdvancedOptionsProperty = DependencyProperty.Register( "ShowAdvancedOptions", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool ShowAdvancedOptions
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowAdvancedOptionsProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowAdvancedOptionsProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowAdvancedOptions
|
|
|
|
#region ShowPreview
|
|
|
|
public static readonly DependencyProperty ShowPreviewProperty = DependencyProperty.Register( "ShowPreview", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( false ) );
|
|
public bool ShowPreview
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowPreviewProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowPreviewProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowPreview
|
|
|
|
#region ShowSearchBox
|
|
|
|
public static readonly DependencyProperty ShowSearchBoxProperty = DependencyProperty.Register( "ShowSearchBox", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool ShowSearchBox
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowSearchBoxProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowSearchBoxProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowSearchBox
|
|
|
|
#region ShowSortOptions
|
|
|
|
public static readonly DependencyProperty ShowSortOptionsProperty = DependencyProperty.Register( "ShowSortOptions", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool ShowSortOptions
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowSortOptionsProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowSortOptionsProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowSortOptions
|
|
|
|
#region ShowTitle
|
|
|
|
public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register( "ShowTitle", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool ShowTitle
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( ShowTitleProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( ShowTitleProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //ShowTitle
|
|
|
|
#region UpdateTextBoxSourceOnEnterKey
|
|
|
|
public static readonly DependencyProperty UpdateTextBoxSourceOnEnterKeyProperty = DependencyProperty.Register( "UpdateTextBoxSourceOnEnterKey", typeof( bool ), typeof( PropertyGrid ), new UIPropertyMetadata( true ) );
|
|
public bool UpdateTextBoxSourceOnEnterKey
|
|
{
|
|
get
|
|
{
|
|
return ( bool )GetValue( UpdateTextBoxSourceOnEnterKeyProperty );
|
|
}
|
|
set
|
|
{
|
|
SetValue( UpdateTextBoxSourceOnEnterKeyProperty, value );
|
|
}
|
|
}
|
|
|
|
#endregion //UpdateTextBoxSourceOnEnterKey
|
|
|
|
#endregion //Properties
|
|
|
|
#region Constructors
|
|
|
|
static PropertyGrid()
|
|
{
|
|
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGrid ), new FrameworkPropertyMetadata( typeof( PropertyGrid ) ) );
|
|
}
|
|
|
|
public PropertyGrid()
|
|
{
|
|
_propertyDefinitionsListener = new WeakEventListener<NotifyCollectionChangedEventArgs>( this.OnPropertyDefinitionsCollectionChanged );
|
|
_editorDefinitionsListener = new WeakEventListener<NotifyCollectionChangedEventArgs>( this.OnEditorDefinitionsCollectionChanged);
|
|
UpdateContainerHelper();
|
|
EditorDefinitions = new EditorDefinitionCollection();
|
|
PropertyDefinitions = new PropertyDefinitionCollection();
|
|
this.PropertyValueChanged += this.PropertyGrid_PropertyValueChanged;
|
|
|
|
AddHandler( PropertyItemBase.ItemSelectionChangedEvent, new RoutedEventHandler( OnItemSelectionChanged ) );
|
|
AddHandler( PropertyItemsControl.PreparePropertyItemEvent, new PropertyItemEventHandler( OnPreparePropertyItemInternal ) );
|
|
AddHandler( PropertyItemsControl.ClearPropertyItemEvent, new PropertyItemEventHandler( OnClearPropertyItemInternal ) );
|
|
CommandBindings.Add( new CommandBinding( PropertyGridCommands.ClearFilter, ClearFilter, CanClearFilter ) );
|
|
}
|
|
|
|
#endregion //Constructors
|
|
|
|
#region Base Class Overrides
|
|
|
|
public override void OnApplyTemplate()
|
|
{
|
|
base.OnApplyTemplate();
|
|
|
|
if( _dragThumb != null )
|
|
_dragThumb.DragDelta -= DragThumb_DragDelta;
|
|
_dragThumb = GetTemplateChild( PART_DragThumb ) as Thumb;
|
|
if( _dragThumb != null )
|
|
_dragThumb.DragDelta += DragThumb_DragDelta;
|
|
|
|
_containerHelper.ChildrenItemsControl = GetTemplateChild( PART_PropertyItemsControl ) as PropertyItemsControl;
|
|
|
|
//Update TranslateTransform in code-behind instead of XAML to remove the
|
|
//output window error.
|
|
//When we use FindAncesstor in custom control template for binding internal elements property
|
|
//into its ancestor element, Visual Studio displays data warning messages in output window when
|
|
//binding engine meets unmatched target type during visual tree traversal though it does the proper
|
|
//binding when it receives expected target type during visual tree traversal
|
|
//ref : http://www.codeproject.com/Tips/124556/How-to-suppress-the-System-Windows-Data-Error-warn
|
|
TranslateTransform _moveTransform = new TranslateTransform();
|
|
_moveTransform.X = NameColumnWidth;
|
|
_dragThumb.RenderTransform = _moveTransform;
|
|
|
|
this.UpdateThumb();
|
|
}
|
|
|
|
protected override void OnPreviewKeyDown( KeyEventArgs e )
|
|
{
|
|
var textBox = e.OriginalSource as TextBox;
|
|
|
|
//hitting enter on textbox will update value of underlying source if UpdateTextBoxSourceOnEnterKey is true
|
|
if( (this.SelectedPropertyItem != null)
|
|
&& (e.Key == Key.Enter)
|
|
&& this.UpdateTextBoxSourceOnEnterKey
|
|
&& (textBox != null)
|
|
&& !textBox.AcceptsReturn )
|
|
{
|
|
BindingExpression be = textBox.GetBindingExpression( TextBox.TextProperty );
|
|
if( be != null )
|
|
be.UpdateSource();
|
|
}
|
|
}
|
|
|
|
protected override void OnPropertyChanged( DependencyPropertyChangedEventArgs e )
|
|
{
|
|
base.OnPropertyChanged( e );
|
|
|
|
// First check that the raised property is actually a real CLR property.
|
|
// This could be something else like a Attached DP.
|
|
if( ReflectionHelper.IsPublicInstanceProperty( GetType(), e.Property.Name ) )
|
|
{
|
|
this.Notify( this.PropertyChanged, e.Property.Name );
|
|
}
|
|
}
|
|
|
|
#endregion //Base Class Overrides
|
|
|
|
#region Event Handlers
|
|
|
|
private void OnItemSelectionChanged( object sender, RoutedEventArgs args )
|
|
{
|
|
PropertyItemBase item = ( PropertyItemBase )args.OriginalSource;
|
|
if( item.IsSelected )
|
|
{
|
|
SelectedPropertyItem = item;
|
|
}
|
|
else
|
|
{
|
|
if( object.ReferenceEquals( item, SelectedPropertyItem ) )
|
|
{
|
|
SelectedPropertyItem = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnPreparePropertyItemInternal( object sender, PropertyItemEventArgs args )
|
|
{
|
|
_containerHelper.PrepareChildrenPropertyItem( args.PropertyItem, args.Item );
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnClearPropertyItemInternal( object sender, PropertyItemEventArgs args )
|
|
{
|
|
_containerHelper.ClearChildrenPropertyItem( args.PropertyItem, args.Item );
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void DragThumb_DragDelta( object sender, DragDeltaEventArgs e )
|
|
{
|
|
NameColumnWidth = Math.Max( 0, NameColumnWidth + e.HorizontalChange );
|
|
}
|
|
|
|
|
|
private void PropertyGrid_PropertyValueChanged( object sender, PropertyValueChangedEventArgs e )
|
|
{
|
|
var modifiedPropertyItem = e.OriginalSource as PropertyItem;
|
|
if( modifiedPropertyItem != null )
|
|
{
|
|
if( modifiedPropertyItem.WillRefreshPropertyGrid )
|
|
this.UpdateContainerHelper();
|
|
|
|
var parentPropertyItem = modifiedPropertyItem.ParentNode as PropertyItem;
|
|
if( ( parentPropertyItem != null ) && parentPropertyItem.IsExpandable )
|
|
{
|
|
//Rebuild Editor for parent propertyItem if one of its sub-propertyItem have changed.
|
|
this.RebuildEditor( parentPropertyItem );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#endregion //Event Handlers
|
|
|
|
#region Commands
|
|
|
|
private void ClearFilter( object sender, ExecutedRoutedEventArgs e )
|
|
{
|
|
Filter = String.Empty;
|
|
}
|
|
|
|
private void CanClearFilter( object sender, CanExecuteRoutedEventArgs e )
|
|
{
|
|
e.CanExecute = !String.IsNullOrEmpty( Filter );
|
|
}
|
|
|
|
#endregion //Commands
|
|
|
|
#region Methods
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void RebuildEditor( PropertyItem propertyItem )
|
|
{
|
|
ObjectContainerHelperBase objectContainerHelperBase = propertyItem.ContainerHelper as ObjectContainerHelperBase;
|
|
//Re-build the editor to update this propertyItem
|
|
FrameworkElement editor = objectContainerHelperBase.GenerateChildrenEditorElement( propertyItem );
|
|
if( editor != null )
|
|
{
|
|
// Tag the editor as generated to know if we should clear it.
|
|
ContainerHelperBase.SetIsGenerated( editor, true );
|
|
propertyItem.Editor = editor;
|
|
}
|
|
}
|
|
|
|
private void UpdateContainerHelper()
|
|
{
|
|
// Keep a backup of the template element and initialize the
|
|
// new helper with it.
|
|
ItemsControl childrenItemsControl = null;
|
|
if( _containerHelper != null )
|
|
{
|
|
childrenItemsControl = _containerHelper.ChildrenItemsControl;
|
|
_containerHelper.ClearHelper();
|
|
if( _containerHelper is ObjectContainerHelperBase )
|
|
{
|
|
// If the actual AdvancedOptionMenu is the default menu for selected object,
|
|
// remove it. Otherwise, it is a custom menu provided by the user.
|
|
// This "default" menu is only valid for the SelectedObject[s] case. Otherwise,
|
|
// it is useless and we must remove it.
|
|
//var defaultAdvancedMenu = ( ContextMenu )this.FindResource( PropertyGrid.SelectedObjectAdvancedOptionsMenuKey );
|
|
//if( this.AdvancedOptionsMenu == defaultAdvancedMenu )
|
|
//{
|
|
this.AdvancedOptionsMenu = null;
|
|
//}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
_containerHelper = new ObjectContainerHelper( this, SelectedObject );
|
|
( ( ObjectContainerHelper )_containerHelper ).GenerateProperties();
|
|
|
|
|
|
_containerHelper.ChildrenItemsControl = childrenItemsControl;
|
|
// Since the template will bind on this property and this property
|
|
// will be different when the property parent is updated.
|
|
this.Notify( this.PropertyChanged, () => this.Properties );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateThumb()
|
|
{
|
|
if( _dragThumb != null )
|
|
{
|
|
if( IsCategorized )
|
|
_dragThumb.Margin = new Thickness( 6, 0, 0, 0 );
|
|
else
|
|
_dragThumb.Margin = new Thickness( -1, 0, 0, 0 );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Override this call to control the filter applied based on the
|
|
/// text input.
|
|
/// </summary>
|
|
/// <param name="filter"></param>
|
|
/// <returns></returns>
|
|
protected virtual Predicate<object> CreateFilter( string filter )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates all property values in the PropertyGrid with the data from the SelectedObject
|
|
/// </summary>
|
|
public void Update()
|
|
{
|
|
_containerHelper.UpdateValuesFromSource();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion //Methods
|
|
|
|
#region Events
|
|
|
|
#region PropertyChanged Event
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
#endregion
|
|
|
|
#region PropertyValueChangedEvent Routed Event
|
|
public static readonly RoutedEvent PropertyValueChangedEvent = EventManager.RegisterRoutedEvent( "PropertyValueChanged", RoutingStrategy.Bubble, typeof( PropertyValueChangedEventHandler ), typeof( PropertyGrid ) );
|
|
public event PropertyValueChangedEventHandler PropertyValueChanged
|
|
{
|
|
add
|
|
{
|
|
AddHandler( PropertyValueChangedEvent, value );
|
|
}
|
|
remove
|
|
{
|
|
RemoveHandler( PropertyValueChangedEvent, value );
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region SelectedPropertyItemChangedEvent Routed Event
|
|
|
|
public static readonly RoutedEvent SelectedPropertyItemChangedEvent = EventManager.RegisterRoutedEvent( "SelectedPropertyItemChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler<PropertyItemBase> ), typeof( PropertyGrid ) );
|
|
public event RoutedPropertyChangedEventHandler<PropertyItemBase> SelectedPropertyItemChanged
|
|
{
|
|
add
|
|
{
|
|
AddHandler( SelectedPropertyItemChangedEvent, value );
|
|
}
|
|
remove
|
|
{
|
|
RemoveHandler( SelectedPropertyItemChangedEvent, value );
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region SelectedObjectChangedEventRouted Routed Event
|
|
|
|
public static readonly RoutedEvent SelectedObjectChangedEvent = EventManager.RegisterRoutedEvent( "SelectedObjectChanged", RoutingStrategy.Bubble, typeof( RoutedPropertyChangedEventHandler<object> ), typeof( PropertyGrid ) );
|
|
public event RoutedPropertyChangedEventHandler<object> SelectedObjectChanged
|
|
{
|
|
add
|
|
{
|
|
AddHandler( SelectedObjectChangedEvent, value );
|
|
}
|
|
remove
|
|
{
|
|
RemoveHandler( SelectedObjectChangedEvent, value );
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PreparePropertyItemEvent Attached Routed Event
|
|
|
|
/// <summary>
|
|
/// Identifies the PreparePropertyItem event.
|
|
/// This attached routed event may be raised by the PropertyGrid itself or by a
|
|
/// PropertyItemBase containing sub-items.
|
|
/// </summary>
|
|
public static readonly RoutedEvent PreparePropertyItemEvent = EventManager.RegisterRoutedEvent( "PreparePropertyItem", RoutingStrategy.Bubble, typeof( PropertyItemEventHandler ), typeof( PropertyGrid ) );
|
|
|
|
/// <summary>
|
|
/// This event is raised when a property item is about to be displayed in the PropertyGrid.
|
|
/// This allow the user to customize the property item just before it is displayed.
|
|
/// </summary>
|
|
public event PropertyItemEventHandler PreparePropertyItem
|
|
{
|
|
add
|
|
{
|
|
AddHandler( PropertyGrid.PreparePropertyItemEvent, value );
|
|
}
|
|
remove
|
|
{
|
|
RemoveHandler( PropertyGrid.PreparePropertyItemEvent, value );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a handler for the PreparePropertyItem attached event
|
|
/// </summary>
|
|
/// <param name="element">the element to attach the handler</param>
|
|
/// <param name="handler">the handler for the event</param>
|
|
public static void AddPreparePropertyItemHandler( UIElement element, PropertyItemEventHandler handler )
|
|
{
|
|
element.AddHandler( PropertyGrid.PreparePropertyItemEvent, handler );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a handler for the PreparePropertyItem attached event
|
|
/// </summary>
|
|
/// <param name="element">the element to attach the handler</param>
|
|
/// <param name="handler">the handler for the event</param>
|
|
public static void RemovePreparePropertyItemHandler( UIElement element, PropertyItemEventHandler handler )
|
|
{
|
|
element.RemoveHandler( PropertyGrid.PreparePropertyItemEvent, handler );
|
|
}
|
|
|
|
internal static void RaisePreparePropertyItemEvent( UIElement source, PropertyItemBase propertyItem, object item )
|
|
{
|
|
source.RaiseEvent( new PropertyItemEventArgs( PropertyGrid.PreparePropertyItemEvent, source, propertyItem, item ) );
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ClearPropertyItemEvent Attached Routed Event
|
|
|
|
/// <summary>
|
|
/// Identifies the ClearPropertyItem event.
|
|
/// This attached routed event may be raised by the PropertyGrid itself or by a
|
|
/// PropertyItemBase containing sub items.
|
|
/// </summary>
|
|
public static readonly RoutedEvent ClearPropertyItemEvent = EventManager.RegisterRoutedEvent( "ClearPropertyItem", RoutingStrategy.Bubble, typeof( PropertyItemEventHandler ), typeof( PropertyGrid ) );
|
|
/// <summary>
|
|
/// This event is raised when an property item is about to be remove from the display in the PropertyGrid
|
|
/// This allow the user to remove any attached handler in the PreparePropertyItem event.
|
|
/// </summary>
|
|
public event PropertyItemEventHandler ClearPropertyItem
|
|
{
|
|
add
|
|
{
|
|
AddHandler( PropertyGrid.ClearPropertyItemEvent, value );
|
|
}
|
|
remove
|
|
{
|
|
RemoveHandler( PropertyGrid.ClearPropertyItemEvent, value );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a handler for the ClearPropertyItem attached event
|
|
/// </summary>
|
|
/// <param name="element">the element to attach the handler</param>
|
|
/// <param name="handler">the handler for the event</param>
|
|
public static void AddClearPropertyItemHandler( UIElement element, PropertyItemEventHandler handler )
|
|
{
|
|
element.AddHandler( PropertyGrid.ClearPropertyItemEvent, handler );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a handler for the ClearPropertyItem attached event
|
|
/// </summary>
|
|
/// <param name="element">the element to attach the handler</param>
|
|
/// <param name="handler">the handler for the event</param>
|
|
public static void RemoveClearPropertyItemHandler( UIElement element, PropertyItemEventHandler handler )
|
|
{
|
|
element.RemoveHandler( PropertyGrid.ClearPropertyItemEvent, handler );
|
|
}
|
|
|
|
internal static void RaiseClearPropertyItemEvent( UIElement source, PropertyItemBase propertyItem, object item )
|
|
{
|
|
source.RaiseEvent( new PropertyItemEventArgs( PropertyGrid.ClearPropertyItemEvent, source, propertyItem, item ) );
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion //Events
|
|
|
|
#region Interfaces
|
|
|
|
#region ISupportInitialize Members
|
|
|
|
public override void BeginInit()
|
|
{
|
|
base.BeginInit();
|
|
_initializationCount++;
|
|
}
|
|
|
|
public override void EndInit()
|
|
{
|
|
base.EndInit();
|
|
if( --_initializationCount == 0 )
|
|
{
|
|
if( _hasPendingSelectedObjectChanged )
|
|
{
|
|
//This will update SelectedObject, Type, Name based on the actual config.
|
|
this.UpdateContainerHelper();
|
|
_hasPendingSelectedObjectChanged = false;
|
|
}
|
|
_containerHelper.OnEndInit();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IPropertyContainer Members
|
|
|
|
FilterInfo IPropertyContainer.FilterInfo
|
|
{
|
|
get
|
|
{
|
|
return new FilterInfo()
|
|
{
|
|
Predicate = this.CreateFilter(this.Filter),
|
|
InputString = this.Filter
|
|
};
|
|
}
|
|
}
|
|
|
|
ContainerHelperBase IPropertyContainer.ContainerHelper
|
|
{
|
|
get
|
|
{
|
|
return _containerHelper;
|
|
}
|
|
}
|
|
|
|
bool IPropertyContainer.IsSortedAlphabetically
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
#region PropertyValueChangedEvent Handler/Args
|
|
public delegate void PropertyValueChangedEventHandler( object sender, PropertyValueChangedEventArgs e );
|
|
public class PropertyValueChangedEventArgs : RoutedEventArgs
|
|
{
|
|
public object NewValue
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
public object OldValue
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public PropertyValueChangedEventArgs( RoutedEvent routedEvent, object source, object oldValue, object newValue )
|
|
: base( routedEvent, source )
|
|
{
|
|
NewValue = newValue;
|
|
OldValue = oldValue;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region PropertyItemCreatedEvent Handler/Args
|
|
public delegate void PropertyItemEventHandler( object sender, PropertyItemEventArgs e );
|
|
public class PropertyItemEventArgs : RoutedEventArgs
|
|
{
|
|
public PropertyItemBase PropertyItem
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public object Item
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public PropertyItemEventArgs( RoutedEvent routedEvent, object source, PropertyItemBase propertyItem, object item )
|
|
: base( routedEvent, source )
|
|
{
|
|
this.PropertyItem = propertyItem;
|
|
this.Item = item;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
|