Init
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
[AttributeUsage( AttributeTargets.Class, AllowMultiple = true )]
|
||||
public class CategoryOrderAttribute : Attribute
|
||||
{
|
||||
#region Properties
|
||||
|
||||
#region Order
|
||||
|
||||
public int Order
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Category
|
||||
|
||||
public virtual string Category
|
||||
{
|
||||
get
|
||||
{
|
||||
return CategoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CategoryValue
|
||||
|
||||
public string CategoryValue
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region constructor
|
||||
|
||||
public CategoryOrderAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
public CategoryOrderAttribute( string categoryName, int order )
|
||||
:this()
|
||||
{
|
||||
CategoryValue = categoryName;
|
||||
Order = order;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
public class ExpandableObjectAttribute : Attribute
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public ExpandableObjectAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
public interface IItemsSource
|
||||
{
|
||||
ItemCollection GetValues();
|
||||
}
|
||||
|
||||
public class Item
|
||||
{
|
||||
public string DisplayName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public object Value
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemCollection : List<Item>
|
||||
{
|
||||
public void Add( object value )
|
||||
{
|
||||
Item item = new Item();
|
||||
item.DisplayName = value.ToString();
|
||||
item.Value = value;
|
||||
base.Add( item );
|
||||
}
|
||||
|
||||
public void Add( object value, string displayName )
|
||||
{
|
||||
Item newItem = new Item();
|
||||
newItem.DisplayName = displayName;
|
||||
newItem.Value = value;
|
||||
base.Add( newItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
public class ItemsSourceAttribute : Attribute
|
||||
{
|
||||
public Type Type
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public ItemsSourceAttribute( Type type )
|
||||
{
|
||||
var valueSourceInterface = type.GetInterface( typeof( IItemsSource ).FullName );
|
||||
if( valueSourceInterface == null )
|
||||
throw new ArgumentException( "Type must implement the IItemsSource interface.", "type" );
|
||||
|
||||
Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// This attribute can decorate the collection properties (i.e., IList)
|
||||
/// of your selected object in order to control the types that will be allowed
|
||||
/// to be instantiated in the CollectionControl.
|
||||
/// </summary>
|
||||
[AttributeUsage( AttributeTargets.Property, AllowMultiple = false, Inherited = true )]
|
||||
public class NewItemTypesAttribute : Attribute
|
||||
{
|
||||
public IList<Type> Types
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public NewItemTypesAttribute( params Type[] types )
|
||||
{
|
||||
this.Types = new List<Type>( types );
|
||||
}
|
||||
|
||||
public NewItemTypesAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Attributes
|
||||
{
|
||||
public enum UsageContextEnum
|
||||
{
|
||||
Alphabetical,
|
||||
Categorized,
|
||||
Both
|
||||
}
|
||||
|
||||
[AttributeUsage( AttributeTargets.Property, AllowMultiple = true, Inherited = true )]
|
||||
public class PropertyOrderAttribute : Attribute
|
||||
{
|
||||
#region Properties
|
||||
|
||||
public int Order
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public UsageContextEnum UsageContext
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override object TypeId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Initialization
|
||||
|
||||
public PropertyOrderAttribute( int order )
|
||||
: this( order, UsageContextEnum.Both )
|
||||
{
|
||||
}
|
||||
|
||||
public PropertyOrderAttribute( int order, UsageContextEnum usageContext )
|
||||
{
|
||||
Order = order;
|
||||
UsageContext = usageContext;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class CategoryGroupStyleSelector : StyleSelector
|
||||
{
|
||||
public Style SingleDefaultCategoryItemGroupStyle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public Style ItemGroupStyle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override Style SelectStyle( object item, DependencyObject container )
|
||||
{
|
||||
var group = item as CollectionViewGroup;
|
||||
// Category is not "Misc" => use regular ItemGroupStyle
|
||||
if( !group.Name.Equals( CategoryAttribute.Default.Category ) )
|
||||
return this.ItemGroupStyle;
|
||||
|
||||
// Category is "Misc"
|
||||
while( container != null )
|
||||
{
|
||||
container = VisualTreeHelper.GetParent( container );
|
||||
if( container is ItemsControl )
|
||||
break;
|
||||
}
|
||||
|
||||
var itemsControl = container as ItemsControl;
|
||||
if( itemsControl != null )
|
||||
{
|
||||
// Category is "Misc" and this is the only category => use SingleDefaultCategoryItemGroupContainerStyle
|
||||
if( (itemsControl.Items.Count > 0) && (itemsControl.Items.Groups.Count == 1) )
|
||||
return this.SingleDefaultCategoryItemGroupStyle;
|
||||
}
|
||||
|
||||
// Category is "Misc" and this is NOT the only category => use regular ItemGroupStyle
|
||||
return this.ItemGroupStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows.Input;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Commands
|
||||
{
|
||||
public class PropertyGridCommands
|
||||
{
|
||||
private static RoutedCommand _clearFilterCommand = new RoutedCommand();
|
||||
public static RoutedCommand ClearFilter
|
||||
{
|
||||
get
|
||||
{
|
||||
return _clearFilterCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows.Input;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Commands
|
||||
{
|
||||
public static class PropertyItemCommands
|
||||
{
|
||||
private static RoutedCommand _resetValueCommand = new RoutedCommand();
|
||||
public static RoutedCommand ResetValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _resetValueCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.ComponentModel;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal class CommonPropertyExceptionValidationRule : ValidationRule
|
||||
{
|
||||
private TypeConverter _propertyTypeConverter;
|
||||
private Type _type;
|
||||
|
||||
internal CommonPropertyExceptionValidationRule( Type type )
|
||||
{
|
||||
_propertyTypeConverter = TypeDescriptor.GetConverter( type );
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public override ValidationResult Validate( object value, CultureInfo cultureInfo )
|
||||
{
|
||||
ValidationResult result = new ValidationResult( true, null );
|
||||
|
||||
if( GeneralUtilities.CanConvertValue( value, _type ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
_propertyTypeConverter.ConvertFrom( value );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
// Will display a red border in propertyGrid
|
||||
result = new ValidationResult( false, e.Message );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.ComponentModel;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Windows.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal abstract class ContainerHelperBase
|
||||
{
|
||||
protected readonly IPropertyContainer PropertyContainer;
|
||||
|
||||
public ContainerHelperBase(IPropertyContainer propertyContainer)
|
||||
{
|
||||
if( propertyContainer == null )
|
||||
throw new ArgumentNullException( "propertyContainer" );
|
||||
|
||||
PropertyContainer = propertyContainer;
|
||||
|
||||
var propChange = propertyContainer as INotifyPropertyChanged;
|
||||
if( propChange != null )
|
||||
{
|
||||
propChange.PropertyChanged += new PropertyChangedEventHandler( OnPropertyContainerPropertyChanged );
|
||||
}
|
||||
}
|
||||
|
||||
#region IsGenerated attached property
|
||||
|
||||
internal static readonly DependencyProperty IsGeneratedProperty = DependencyProperty.RegisterAttached(
|
||||
"IsGenerated",
|
||||
typeof( bool ),
|
||||
typeof( ContainerHelperBase ),
|
||||
new PropertyMetadata( false ) );
|
||||
|
||||
internal static bool GetIsGenerated( DependencyObject obj )
|
||||
{
|
||||
return ( bool )obj.GetValue( ContainerHelperBase.IsGeneratedProperty );
|
||||
}
|
||||
|
||||
internal static void SetIsGenerated( DependencyObject obj, bool value )
|
||||
{
|
||||
obj.SetValue( ContainerHelperBase.IsGeneratedProperty, value );
|
||||
}
|
||||
|
||||
#endregion IsGenerated attached property
|
||||
|
||||
public abstract IList Properties
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
internal ItemsControl ChildrenItemsControl
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public virtual void ClearHelper()
|
||||
{
|
||||
var propChange = PropertyContainer as INotifyPropertyChanged;
|
||||
if( propChange != null )
|
||||
{
|
||||
propChange.PropertyChanged -= new PropertyChangedEventHandler( OnPropertyContainerPropertyChanged );
|
||||
}
|
||||
|
||||
// Calling RemoveAll() will force the ItemsContol displaying the
|
||||
// properties to clear all the current container (i.e., ClearContainerForItem).
|
||||
// This will make the call at "ClearChildrenPropertyItem" for every prepared
|
||||
// container. Fortunately, the ItemsContainer will not re-prepare the items yet
|
||||
// (i.e., probably made on next measure pass), allowing us to set up the new
|
||||
// parent helper.
|
||||
if( ChildrenItemsControl != null )
|
||||
{
|
||||
( ( IItemContainerGenerator )ChildrenItemsControl.ItemContainerGenerator ).RemoveAll();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PrepareChildrenPropertyItem( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
// Initialize the parent node
|
||||
propertyItem.ParentNode = PropertyContainer;
|
||||
|
||||
PropertyGrid.RaisePreparePropertyItemEvent( ( UIElement )PropertyContainer, propertyItem, item );
|
||||
}
|
||||
|
||||
public virtual void ClearChildrenPropertyItem( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
|
||||
propertyItem.ParentNode = null;
|
||||
|
||||
PropertyGrid.RaiseClearPropertyItemEvent( ( UIElement )PropertyContainer, propertyItem, item );
|
||||
}
|
||||
|
||||
protected FrameworkElement GenerateCustomEditingElement( Type definitionKey, PropertyItemBase propertyItem )
|
||||
{
|
||||
return ( PropertyContainer.EditorDefinitions != null )
|
||||
? this.CreateCustomEditor( PropertyContainer.EditorDefinitions.GetRecursiveBaseTypes( definitionKey ), propertyItem )
|
||||
: null;
|
||||
}
|
||||
|
||||
protected FrameworkElement GenerateCustomEditingElement( object definitionKey, PropertyItemBase propertyItem )
|
||||
{
|
||||
return ( PropertyContainer.EditorDefinitions != null )
|
||||
? this.CreateCustomEditor( PropertyContainer.EditorDefinitions[ definitionKey ], propertyItem )
|
||||
: null;
|
||||
}
|
||||
|
||||
protected FrameworkElement CreateCustomEditor( EditorDefinitionBase customEditor, PropertyItemBase propertyItem )
|
||||
{
|
||||
return ( customEditor != null )
|
||||
? customEditor.GenerateEditingElementInternal( propertyItem )
|
||||
: null;
|
||||
}
|
||||
|
||||
protected virtual void OnPropertyContainerPropertyChanged( object sender, PropertyChangedEventArgs e )
|
||||
{
|
||||
var propertyName = e.PropertyName;
|
||||
IPropertyContainer ps = null;
|
||||
if( propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.FilterInfo ) )
|
||||
{
|
||||
this.OnFilterChanged();
|
||||
}
|
||||
else if( propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.IsCategorized ) )
|
||||
{
|
||||
this.OnCategorizationChanged();
|
||||
}
|
||||
else if( propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.AutoGenerateProperties ) )
|
||||
{
|
||||
this.OnAutoGeneratePropertiesChanged();
|
||||
}
|
||||
else if( propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.HideInheritedProperties ) )
|
||||
{
|
||||
this.OnHideInheritedPropertiesChanged();
|
||||
}
|
||||
else if(propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.EditorDefinitions ))
|
||||
{
|
||||
this.OnEditorDefinitionsChanged();
|
||||
}
|
||||
else if(propertyName == ReflectionHelper.GetPropertyOrFieldName( () => ps.PropertyDefinitions ))
|
||||
{
|
||||
this.OnPropertyDefinitionsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnCategorizationChanged() { }
|
||||
|
||||
protected virtual void OnFilterChanged() { }
|
||||
|
||||
protected virtual void OnAutoGeneratePropertiesChanged() { }
|
||||
|
||||
protected virtual void OnHideInheritedPropertiesChanged() { }
|
||||
|
||||
protected virtual void OnEditorDefinitionsChanged() { }
|
||||
|
||||
protected virtual void OnPropertyDefinitionsChanged() { }
|
||||
|
||||
|
||||
public virtual void OnEndInit() { }
|
||||
|
||||
public abstract PropertyItemBase ContainerFromItem( object item );
|
||||
|
||||
public abstract object ItemFromContainer( PropertyItemBase container );
|
||||
|
||||
public abstract Binding CreateChildrenDefaultBinding( PropertyItemBase propertyItem );
|
||||
|
||||
public virtual void NotifyEditorDefinitionsCollectionChanged() { }
|
||||
public virtual void NotifyPropertyDefinitionsCollectionChanged() { }
|
||||
|
||||
public abstract void UpdateValuesFromSource();
|
||||
|
||||
protected internal virtual void SetPropertiesExpansion( bool isExpanded )
|
||||
{
|
||||
foreach( var item in this.Properties )
|
||||
{
|
||||
var propertyItem = item as PropertyItemBase;
|
||||
if( (propertyItem != null) && propertyItem.IsExpandable )
|
||||
{
|
||||
if( propertyItem.ContainerHelper != null )
|
||||
{
|
||||
propertyItem.ContainerHelper.SetPropertiesExpansion( isExpanded );
|
||||
}
|
||||
propertyItem.IsExpanded = isExpanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected internal virtual void SetPropertiesExpansion( string propertyName, bool isExpanded )
|
||||
{
|
||||
foreach( var item in this.Properties )
|
||||
{
|
||||
var propertyItem = item as PropertyItemBase;
|
||||
if( (propertyItem != null) && propertyItem.IsExpandable )
|
||||
{
|
||||
if( propertyItem.DisplayName == propertyName )
|
||||
{
|
||||
propertyItem.IsExpanded = isExpanded;
|
||||
break;
|
||||
}
|
||||
|
||||
if( propertyItem.ContainerHelper != null )
|
||||
{
|
||||
propertyItem.ContainerHelper.SetPropertiesExpansion( propertyName, isExpanded );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a TimeSpan value to a DateTime value.
|
||||
///
|
||||
/// This converter can be used in conjunction with a TimePicker in order
|
||||
/// to create a TimeSpan edit control.
|
||||
/// </summary>
|
||||
public sealed class EditorTimeSpanConverter : IValueConverter
|
||||
{
|
||||
public bool AllowNulls { get; set; }
|
||||
|
||||
object IValueConverter.Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( this.AllowNulls && value == null )
|
||||
return null;
|
||||
|
||||
TimeSpan timeSpan = ( value != null ) ? ( TimeSpan )value : TimeSpan.Zero;
|
||||
return DateTime.Today + timeSpan;
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( this.AllowNulls && value == null )
|
||||
return null;
|
||||
|
||||
return ( value != null )
|
||||
? ( ( DateTime )value ).TimeOfDay
|
||||
: TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
public class ExpandableObjectMarginConverter : IValueConverter
|
||||
{
|
||||
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
|
||||
{
|
||||
int childLevel = ( int )value;
|
||||
return new Thickness( childLevel * 15, 0, 0, 0 );
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
public class IsDefaultCategoryConverter : IValueConverter
|
||||
{
|
||||
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
string categoryName = value as string;
|
||||
if( categoryName != null )
|
||||
{
|
||||
return ( categoryName == CategoryAttribute.Default.Category );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
public class IsStringEmptyConverter : IValueConverter
|
||||
{
|
||||
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( value is string )
|
||||
{
|
||||
return string.IsNullOrEmpty( ( string )value );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
internal class ListConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType )
|
||||
{
|
||||
return ( destinationType == typeof( string ) );
|
||||
}
|
||||
|
||||
public override object ConvertFrom( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value )
|
||||
{
|
||||
if( value == null )
|
||||
return null;
|
||||
|
||||
string names = value as string;
|
||||
|
||||
var list = new List<object>();
|
||||
if( names == null && value != null )
|
||||
{
|
||||
list.Add( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( names == null )
|
||||
return null;
|
||||
|
||||
foreach( var name in names.Split( ',' ) )
|
||||
{
|
||||
list.Add( name.Trim() );
|
||||
}
|
||||
}
|
||||
|
||||
return new ReadOnlyCollection<object>( list );
|
||||
}
|
||||
|
||||
public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType )
|
||||
{
|
||||
if( destinationType != typeof( string ) )
|
||||
throw new InvalidOperationException( "Can only convert to string." );
|
||||
|
||||
|
||||
IList strs = ( IList )value;
|
||||
|
||||
if( strs == null )
|
||||
return null;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
bool first = true;
|
||||
foreach( object o in strs )
|
||||
{
|
||||
if( o == null )
|
||||
throw new InvalidOperationException( "Property names cannot be null." );
|
||||
|
||||
string s = o as string;
|
||||
if( s == null )
|
||||
throw new InvalidOperationException( "Does not support serialization of non-string property names." );
|
||||
|
||||
if( s.Contains( ',' ) )
|
||||
throw new InvalidOperationException( "Property names cannot contain commas." );
|
||||
|
||||
if( s.Trim().Length != s.Length )
|
||||
throw new InvalidOperationException( "Property names cannot start or end with whitespace characters." );
|
||||
|
||||
if( !first )
|
||||
{
|
||||
sb.Append( ", " );
|
||||
}
|
||||
first = false;
|
||||
|
||||
sb.Append( s );
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
public class ObjectToUIElementConverter : IValueConverter
|
||||
{
|
||||
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( value is UIElement )
|
||||
return value;
|
||||
|
||||
return new Control();
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Data;
|
||||
using System.Globalization;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters
|
||||
{
|
||||
public class SelectedObjectConverter : IValueConverter
|
||||
{
|
||||
private const string ValidParameterMessage = @"parameter must be one of the following strings: 'Type', 'TypeName', 'SelectedObjectName'";
|
||||
#region IValueConverter Members
|
||||
|
||||
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( parameter == null )
|
||||
throw new ArgumentNullException( "parameter" );
|
||||
|
||||
if( !( parameter is string ) )
|
||||
throw new ArgumentException( SelectedObjectConverter.ValidParameterMessage );
|
||||
|
||||
if( this.CompareParam(parameter, "Type") )
|
||||
{
|
||||
return this.ConvertToType( value, culture );
|
||||
}
|
||||
else if( this.CompareParam( parameter, "TypeName" ) )
|
||||
{
|
||||
return this.ConvertToTypeName( value, culture );
|
||||
}
|
||||
else if( this.CompareParam( parameter, "SelectedObjectName" ) )
|
||||
{
|
||||
return this.ConvertToSelectedObjectName( value, culture );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException( SelectedObjectConverter.ValidParameterMessage );
|
||||
}
|
||||
}
|
||||
|
||||
private bool CompareParam(object parameter, string parameterValue )
|
||||
{
|
||||
return string.Compare( ( string )parameter, parameterValue, true ) == 0;
|
||||
}
|
||||
|
||||
private object ConvertToType( object value, CultureInfo culture )
|
||||
{
|
||||
return ( value != null )
|
||||
? value.GetType()
|
||||
: null;
|
||||
}
|
||||
|
||||
private object ConvertToTypeName( object value, CultureInfo culture )
|
||||
{
|
||||
if( value == null )
|
||||
return string.Empty;
|
||||
|
||||
Type newType = value.GetType();
|
||||
|
||||
DisplayNameAttribute displayNameAttribute = newType.GetCustomAttributes( false ).OfType<DisplayNameAttribute>().FirstOrDefault();
|
||||
|
||||
return (displayNameAttribute == null)
|
||||
? newType.Name
|
||||
: displayNameAttribute.DisplayName;
|
||||
}
|
||||
|
||||
private object ConvertToSelectedObjectName( object value, CultureInfo culture )
|
||||
{
|
||||
if( value == null )
|
||||
return String.Empty;
|
||||
|
||||
Type newType = value.GetType();
|
||||
PropertyInfo[] properties = newType.GetProperties();
|
||||
foreach( PropertyInfo property in properties )
|
||||
{
|
||||
if( property.Name == "Name" )
|
||||
return property.GetValue( value, null );
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// Used when properties are provided using a list source of items (eg. Properties or PropertiesSource).
|
||||
///
|
||||
/// An instance of this class can be used as an item to easily customize the
|
||||
/// display of the property directly by modifying the values of this class
|
||||
/// (e.g., DisplayName, value, Category, etc.).
|
||||
/// </summary>
|
||||
public class CustomPropertyItem : PropertyItemBase
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
internal CustomPropertyItem() { }
|
||||
|
||||
internal CustomPropertyItem( bool isPropertyGridCategorized, bool isSortedAlphabetically )
|
||||
{
|
||||
this.Init( isPropertyGridCategorized, isSortedAlphabetically );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Category
|
||||
|
||||
public static readonly DependencyProperty CategoryProperty =
|
||||
DependencyProperty.Register( "Category", typeof( string ), typeof( CustomPropertyItem ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public string Category
|
||||
{
|
||||
get { return ( string )GetValue( CategoryProperty ); }
|
||||
set { SetValue( CategoryProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //Category
|
||||
|
||||
#region CategoryOrder
|
||||
|
||||
public int CategoryOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return _categoryOrder;
|
||||
}
|
||||
set
|
||||
{
|
||||
if( _categoryOrder != value )
|
||||
{
|
||||
_categoryOrder = value;
|
||||
// Notify the parent helper since this property may affect ordering.
|
||||
this.RaisePropertyChanged( () => this.CategoryOrder );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _categoryOrder;
|
||||
|
||||
#endregion //CategoryOrder
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region PropertyOrder
|
||||
|
||||
public static readonly DependencyProperty PropertyOrderProperty =
|
||||
DependencyProperty.Register( "PropertyOrder", typeof( int ), typeof( CustomPropertyItem ), new UIPropertyMetadata( 0 ) );
|
||||
|
||||
public int PropertyOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( int )GetValue( PropertyOrderProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( PropertyOrderProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //PropertyOrder
|
||||
|
||||
#region Value
|
||||
|
||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( object ), typeof( CustomPropertyItem ), new UIPropertyMetadata( null, OnValueChanged, OnCoerceValueChanged ) );
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( object )GetValue( ValueProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( ValueProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static object OnCoerceValueChanged( DependencyObject o, object baseValue )
|
||||
{
|
||||
CustomPropertyItem prop = o as CustomPropertyItem;
|
||||
if( prop != null )
|
||||
return prop.OnCoerceValueChanged( baseValue );
|
||||
|
||||
return baseValue;
|
||||
}
|
||||
|
||||
protected virtual object OnCoerceValueChanged( object baseValue )
|
||||
{
|
||||
return baseValue;
|
||||
}
|
||||
|
||||
private static void OnValueChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
CustomPropertyItem propertyItem = o as CustomPropertyItem;
|
||||
if( propertyItem != null )
|
||||
{
|
||||
propertyItem.OnValueChanged( ( object )e.OldValue, ( object )e.NewValue );
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnValueChanged( object oldValue, object newValue )
|
||||
{
|
||||
if( IsInitialized )
|
||||
{
|
||||
RaiseEvent( new PropertyValueChangedEventArgs( PropertyGrid.PropertyValueChangedEvent, this, oldValue, newValue ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Value
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
protected override Type GetPropertyItemType()
|
||||
{
|
||||
return this.Value.GetType();
|
||||
}
|
||||
|
||||
protected override void OnEditorChanged( FrameworkElement oldValue, FrameworkElement newValue )
|
||||
{
|
||||
if( oldValue != null )
|
||||
oldValue.DataContext = null;
|
||||
|
||||
if( newValue != null )
|
||||
newValue.DataContext = this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void Init( bool isPropertyGridCategorized, bool isSortedAlphabetically )
|
||||
{
|
||||
_isPropertyGridCategorized = isPropertyGridCategorized;
|
||||
_isSortedAlphabetically = isSortedAlphabetically;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
|
||||
using System.Windows;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public abstract class DefinitionBase : DependencyObject
|
||||
{
|
||||
private bool _isLocked;
|
||||
|
||||
internal bool IsLocked
|
||||
{
|
||||
get { return _isLocked; }
|
||||
}
|
||||
|
||||
internal void ThrowIfLocked<TMember>( Expression<Func<TMember>> propertyExpression )
|
||||
{
|
||||
//In XAML, when using any properties of PropertyDefinition, the error of ThrowIfLocked is always thrown => prevent it !
|
||||
if( DesignerProperties.GetIsInDesignMode( this ) )
|
||||
return;
|
||||
|
||||
if( this.IsLocked )
|
||||
{
|
||||
string propertyName = ReflectionHelper.GetPropertyOrFieldName( propertyExpression );
|
||||
string message = string.Format(
|
||||
@"Cannot modify {0} once the definition has beed added to a collection.",
|
||||
propertyName );
|
||||
throw new InvalidOperationException( message );
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void Lock()
|
||||
{
|
||||
if( !_isLocked )
|
||||
{
|
||||
_isLocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public abstract class EditorDefinitionBase : PropertyDefinitionBase
|
||||
{
|
||||
|
||||
internal EditorDefinitionBase() { }
|
||||
|
||||
internal FrameworkElement GenerateEditingElementInternal( PropertyItemBase propertyItem )
|
||||
{
|
||||
return this.GenerateEditingElement( propertyItem );
|
||||
}
|
||||
|
||||
protected virtual FrameworkElement GenerateEditingElement( PropertyItemBase propertyItem ) { return null; }
|
||||
|
||||
internal void UpdateProperty( FrameworkElement element, DependencyProperty elementProp, DependencyProperty definitionProperty )
|
||||
{
|
||||
object currentValue = this.GetValue( definitionProperty );
|
||||
object localValue = this.ReadLocalValue( definitionProperty );
|
||||
object elementValue = element.GetValue( elementProp );
|
||||
bool areEquals = false;
|
||||
|
||||
// Avoid setting values if it does not affect anything
|
||||
// because setting a local value may prevent a style setter from being active.
|
||||
if( localValue != DependencyProperty.UnsetValue )
|
||||
{
|
||||
if( ( elementValue != null ) && ( currentValue != null ) )
|
||||
{
|
||||
areEquals = ( elementValue.GetType().IsValueType && currentValue.GetType().IsValueType )
|
||||
? elementValue.Equals( currentValue ) // Value Types
|
||||
: currentValue == element.GetValue( elementProp ); // Reference Types
|
||||
}
|
||||
|
||||
if( !areEquals )
|
||||
{
|
||||
element.SetValue( elementProp, currentValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
element.ClearValue( elementProp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class EditorTemplateDefinition : EditorDefinitionBase
|
||||
{
|
||||
|
||||
|
||||
#region EditingTemplate
|
||||
public static readonly DependencyProperty EditingTemplateProperty =
|
||||
DependencyProperty.Register( "EditingTemplate", typeof( DataTemplate ), typeof( EditorTemplateDefinition ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public DataTemplate EditingTemplate
|
||||
{
|
||||
get { return ( DataTemplate )GetValue( EditingTemplateProperty ); }
|
||||
set { SetValue( EditingTemplateProperty, value ); }
|
||||
}
|
||||
#endregion //EditingTemplate
|
||||
|
||||
protected override sealed FrameworkElement GenerateEditingElement( PropertyItemBase propertyItem )
|
||||
{
|
||||
return ( this.EditingTemplate != null )
|
||||
? this.EditingTemplate.LoadContent() as FrameworkElement
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public abstract class PropertyDefinitionBase : DefinitionBase
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
internal PropertyDefinitionBase()
|
||||
{
|
||||
_targetProperties = new List<object>();
|
||||
this.PropertyDefinitions = new PropertyDefinitionCollection();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region TargetProperties
|
||||
|
||||
[TypeConverter(typeof(ListConverter))]
|
||||
public IList TargetProperties
|
||||
{
|
||||
get { return _targetProperties; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.TargetProperties );
|
||||
_targetProperties = value;
|
||||
}
|
||||
}
|
||||
|
||||
private IList _targetProperties;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PropertyDefinitions
|
||||
|
||||
public PropertyDefinitionCollection PropertyDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyDefinitions;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.PropertyDefinitions );
|
||||
_propertyDefinitions = value;
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyDefinitionCollection _propertyDefinitions;
|
||||
|
||||
#endregion //PropertyDefinitions
|
||||
|
||||
#endregion
|
||||
|
||||
#region Overrides
|
||||
|
||||
internal override void Lock()
|
||||
{
|
||||
if( this.IsLocked )
|
||||
return;
|
||||
|
||||
base.Lock();
|
||||
|
||||
// Just create a new copy of the properties target to ensure
|
||||
// that the list doesn't ever get modified.
|
||||
|
||||
List<object> newList = new List<object>();
|
||||
if( _targetProperties != null )
|
||||
{
|
||||
foreach( object p in _targetProperties )
|
||||
{
|
||||
object prop = p;
|
||||
// Convert all TargetPropertyType to Types
|
||||
var targetType = prop as TargetPropertyType;
|
||||
if( targetType != null )
|
||||
{
|
||||
prop = targetType.Type;
|
||||
}
|
||||
newList.Add( prop );
|
||||
}
|
||||
}
|
||||
|
||||
//In Designer Mode, the Designer is broken if using a ReadOnlyCollection
|
||||
_targetProperties = DesignerProperties.GetIsInDesignMode( this )
|
||||
? new Collection<object>( newList )
|
||||
: new ReadOnlyCollection<object>( newList ) as IList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup.Primitives;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Commands;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal class DescriptorPropertyDefinition : DescriptorPropertyDefinitionBase
|
||||
{
|
||||
#region Members
|
||||
|
||||
private object _selectedObject;
|
||||
private PropertyDescriptor _propertyDescriptor;
|
||||
private DependencyPropertyDescriptor _dpDescriptor;
|
||||
private MarkupObject _markupObject;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
|
||||
internal DescriptorPropertyDefinition( PropertyDescriptor propertyDescriptor, object selectedObject, bool isPropertyGridCategorized )
|
||||
: base( isPropertyGridCategorized )
|
||||
{
|
||||
this.Init( propertyDescriptor, selectedObject );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Custom Properties
|
||||
|
||||
internal override PropertyDescriptor PropertyDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
private object SelectedObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selectedObject;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Override Methods
|
||||
|
||||
internal override ObjectContainerHelperBase CreateContainerHelper( IPropertyContainer parent )
|
||||
{
|
||||
return new ObjectContainerHelper( parent, this.Value );
|
||||
}
|
||||
|
||||
internal override void OnValueChanged( object oldValue, object newValue )
|
||||
{
|
||||
base.OnValueChanged( oldValue, newValue );
|
||||
this.RaiseContainerHelperInvalidated();
|
||||
}
|
||||
|
||||
protected override BindingBase CreateValueBinding()
|
||||
{
|
||||
var selectedObject = this.SelectedObject;
|
||||
var propertyName = this.PropertyDescriptor.Name;
|
||||
|
||||
//Bind the value property with the source object.
|
||||
var binding = new Binding( propertyName )
|
||||
{
|
||||
Source = this.GetValueInstance( selectedObject ),
|
||||
Mode = PropertyDescriptor.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay,
|
||||
ValidatesOnDataErrors = true,
|
||||
ValidatesOnExceptions = true,
|
||||
ConverterCulture = CultureInfo.CurrentCulture
|
||||
};
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
||||
protected override bool ComputeIsReadOnly()
|
||||
{
|
||||
return PropertyDescriptor.IsReadOnly;
|
||||
}
|
||||
|
||||
internal override ITypeEditor CreateDefaultEditor( PropertyItem propertyItem )
|
||||
{
|
||||
return PropertyGridUtilities.CreateDefaultEditor( PropertyDescriptor.PropertyType, PropertyDescriptor.Converter, propertyItem );
|
||||
}
|
||||
|
||||
protected override bool ComputeCanResetValue()
|
||||
{
|
||||
return PropertyDescriptor.CanResetValue( SelectedObject )
|
||||
&& !PropertyDescriptor.IsReadOnly;
|
||||
}
|
||||
|
||||
protected override object ComputeAdvancedOptionsTooltip()
|
||||
{
|
||||
object tooltip;
|
||||
UpdateAdvanceOptionsForItem( _markupObject, SelectedObject as DependencyObject, _dpDescriptor, out tooltip );
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
protected override string ComputeCategory()
|
||||
{
|
||||
#if VS2008
|
||||
return PropertyDescriptor.Category;
|
||||
#else
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( PropertyDescriptor );
|
||||
return ( (displayAttribute != null) && (displayAttribute.GetGroupName() != null) ) ? displayAttribute.GetGroupName() : PropertyDescriptor.Category;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override string ComputeCategoryValue()
|
||||
{
|
||||
return PropertyDescriptor.Category;
|
||||
}
|
||||
|
||||
protected override bool ComputeExpandableAttribute()
|
||||
{
|
||||
return ( bool )this.ComputeExpandableAttributeForItem( PropertyDescriptor );
|
||||
}
|
||||
|
||||
protected override bool ComputeIsExpandable()
|
||||
{
|
||||
return ( this.Value != null )
|
||||
;
|
||||
}
|
||||
|
||||
protected override IList<Type> ComputeNewItemTypes()
|
||||
{
|
||||
return ( IList<Type> )ComputeNewItemTypesForItem( PropertyDescriptor );
|
||||
}
|
||||
protected override string ComputeDescription()
|
||||
{
|
||||
return ( string )ComputeDescriptionForItem( PropertyDescriptor );
|
||||
}
|
||||
|
||||
protected override int ComputeDisplayOrder( bool isPropertyGridCategorized )
|
||||
{
|
||||
this.IsPropertyGridCategorized = isPropertyGridCategorized;
|
||||
return ( int )ComputeDisplayOrderForItem( PropertyDescriptor );
|
||||
}
|
||||
|
||||
protected override void ResetValue()
|
||||
{
|
||||
PropertyDescriptor.ResetValue( SelectedObject );
|
||||
}
|
||||
|
||||
internal override ITypeEditor CreateAttributeEditor()
|
||||
{
|
||||
var editorAttribute = GetAttribute<EditorAttribute>();
|
||||
if( editorAttribute != null )
|
||||
{
|
||||
Type type = Type.GetType( editorAttribute.EditorTypeName );
|
||||
|
||||
// If the editor does not have any public parameterless constructor, forget it.
|
||||
if( typeof( ITypeEditor ).IsAssignableFrom( type )
|
||||
&& ( type.GetConstructor( new Type[ 0 ] ) != null ) )
|
||||
{
|
||||
var instance = Activator.CreateInstance( type ) as ITypeEditor;
|
||||
Debug.Assert( instance != null, "Type was expected to be ITypeEditor with public constructor." );
|
||||
if( instance != null )
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
var itemsSourceAttribute = GetAttribute<ItemsSourceAttribute>();
|
||||
if( itemsSourceAttribute != null )
|
||||
return new ItemsSourceAttributeEditor( itemsSourceAttribute );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private T GetAttribute<T>() where T : Attribute
|
||||
{
|
||||
return PropertyGridUtilities.GetAttribute<T>( PropertyDescriptor );
|
||||
}
|
||||
|
||||
private void Init( PropertyDescriptor propertyDescriptor, object selectedObject )
|
||||
{
|
||||
if( propertyDescriptor == null )
|
||||
throw new ArgumentNullException( "propertyDescriptor" );
|
||||
|
||||
if( selectedObject == null )
|
||||
throw new ArgumentNullException( "selectedObject" );
|
||||
|
||||
_propertyDescriptor = propertyDescriptor;
|
||||
_selectedObject = selectedObject;
|
||||
_dpDescriptor = DependencyPropertyDescriptor.FromProperty( propertyDescriptor );
|
||||
_markupObject = MarkupWriter.GetMarkupObjectFor( SelectedObject );
|
||||
}
|
||||
|
||||
#endregion //Private Methods
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,614 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Commands;
|
||||
using System.Windows.Media;
|
||||
using System.Collections;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using System.Diagnostics;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Markup.Primitives;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media.Imaging;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal abstract class DescriptorPropertyDefinitionBase : DependencyObject
|
||||
{
|
||||
#region Members
|
||||
|
||||
private string _category;
|
||||
private string _categoryValue;
|
||||
private string _description;
|
||||
private string _displayName;
|
||||
private int _displayOrder;
|
||||
private bool _expandableAttribute;
|
||||
private bool _isReadOnly;
|
||||
private IList<Type> _newItemTypes;
|
||||
private IEnumerable<CommandBinding> _commandBindings;
|
||||
|
||||
#endregion
|
||||
|
||||
internal abstract PropertyDescriptor PropertyDescriptor
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
#region Initialization
|
||||
|
||||
internal DescriptorPropertyDefinitionBase( bool isPropertyGridCategorized )
|
||||
{
|
||||
this.IsPropertyGridCategorized = isPropertyGridCategorized;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Virtual Methods
|
||||
|
||||
protected virtual string ComputeCategory()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual string ComputeCategoryValue()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual string ComputeDescription()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual int ComputeDisplayOrder( bool isPropertyGridCategorized )
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
protected virtual bool ComputeExpandableAttribute()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract bool ComputeIsExpandable();
|
||||
|
||||
protected virtual IList<Type> ComputeNewItemTypes()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual bool ComputeIsReadOnly()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool ComputeCanResetValue()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual object ComputeAdvancedOptionsTooltip()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual void ResetValue()
|
||||
{
|
||||
}
|
||||
|
||||
protected abstract BindingBase CreateValueBinding();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal abstract ObjectContainerHelperBase CreateContainerHelper( IPropertyContainer parent );
|
||||
|
||||
internal void RaiseContainerHelperInvalidated()
|
||||
{
|
||||
if( this.ContainerHelperInvalidated != null )
|
||||
{
|
||||
this.ContainerHelperInvalidated( this, EventArgs.Empty );
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual ITypeEditor CreateDefaultEditor( PropertyItem propertyItem )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal virtual ITypeEditor CreateAttributeEditor()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal void UpdateAdvanceOptionsForItem( MarkupObject markupObject, DependencyObject dependencyObject, DependencyPropertyDescriptor dpDescriptor,
|
||||
out object tooltip )
|
||||
{
|
||||
tooltip = StringConstants.AdvancedProperties;
|
||||
|
||||
bool isResource = false;
|
||||
bool isDynamicResource = false;
|
||||
|
||||
var markupProperty = markupObject.Properties.FirstOrDefault( p => p.Name == PropertyName );
|
||||
if( markupProperty != null )
|
||||
{
|
||||
//TODO: need to find a better way to determine if a StaticResource has been applied to any property not just a style(maybe with StaticResourceExtension)
|
||||
isResource = typeof( Style ).IsAssignableFrom( markupProperty.PropertyType );
|
||||
isDynamicResource = typeof( DynamicResourceExtension ).IsAssignableFrom( markupProperty.PropertyType );
|
||||
}
|
||||
|
||||
if( isResource || isDynamicResource )
|
||||
{
|
||||
tooltip = StringConstants.Resource;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (dependencyObject != null) && (dpDescriptor != null) )
|
||||
{
|
||||
if( BindingOperations.GetBindingExpressionBase( dependencyObject, dpDescriptor.DependencyProperty ) != null )
|
||||
{
|
||||
tooltip = StringConstants.Databinding;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseValueSource bvs =
|
||||
DependencyPropertyHelper
|
||||
.GetValueSource( dependencyObject, dpDescriptor.DependencyProperty )
|
||||
.BaseValueSource;
|
||||
|
||||
switch( bvs )
|
||||
{
|
||||
case BaseValueSource.Inherited:
|
||||
case BaseValueSource.DefaultStyle:
|
||||
case BaseValueSource.ImplicitStyleReference:
|
||||
tooltip = StringConstants.Inheritance;
|
||||
break;
|
||||
case BaseValueSource.DefaultStyleTrigger:
|
||||
break;
|
||||
case BaseValueSource.Style:
|
||||
tooltip = StringConstants.StyleSetter;
|
||||
break;
|
||||
|
||||
case BaseValueSource.Local:
|
||||
tooltip = StringConstants.Local;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAdvanceOptions()
|
||||
{
|
||||
// Only set the Tooltip. the Icon will be added in XAML based on the Tooltip.
|
||||
this.AdvancedOptionsTooltip = this.ComputeAdvancedOptionsTooltip();
|
||||
}
|
||||
|
||||
internal void UpdateIsExpandable()
|
||||
{
|
||||
this.IsExpandable =
|
||||
this.ExpandableAttribute
|
||||
&& this.ComputeIsExpandable();
|
||||
}
|
||||
|
||||
internal void UpdateValueFromSource()
|
||||
{
|
||||
BindingOperations.GetBindingExpressionBase( this, DescriptorPropertyDefinitionBase.ValueProperty ).UpdateTarget();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
internal object ComputeDescriptionForItem( object item )
|
||||
{
|
||||
PropertyDescriptor pd = item as PropertyDescriptor;
|
||||
|
||||
//We do not simply rely on the "Description" property of PropertyDescriptor
|
||||
//since this value is cached by PropertyDescriptor and the localized version
|
||||
//(e.g., LocalizedDescriptionAttribute) value can dynamicaly change.
|
||||
#if !VS2008
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( pd );
|
||||
if( displayAttribute != null )
|
||||
{
|
||||
return displayAttribute.GetDescription();
|
||||
}
|
||||
#endif
|
||||
|
||||
var descriptionAtt = PropertyGridUtilities.GetAttribute<DescriptionAttribute>( pd );
|
||||
return (descriptionAtt != null)
|
||||
? descriptionAtt.Description
|
||||
: pd.Description;
|
||||
}
|
||||
|
||||
internal object ComputeNewItemTypesForItem( object item )
|
||||
{
|
||||
PropertyDescriptor pd = item as PropertyDescriptor;
|
||||
var attribute = PropertyGridUtilities.GetAttribute<NewItemTypesAttribute>( pd );
|
||||
|
||||
return (attribute != null)
|
||||
? attribute.Types
|
||||
: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
internal object ComputeDisplayOrderForItem( object item )
|
||||
{
|
||||
PropertyDescriptor pd = item as PropertyDescriptor;
|
||||
#if !VS2008
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( PropertyDescriptor );
|
||||
if( displayAttribute != null )
|
||||
{
|
||||
var order = displayAttribute.GetOrder();
|
||||
if( order.HasValue )
|
||||
return displayAttribute.GetOrder();
|
||||
}
|
||||
#endif
|
||||
|
||||
List<PropertyOrderAttribute> list = pd.Attributes.OfType<PropertyOrderAttribute>().ToList();
|
||||
|
||||
if( list.Count > 0 )
|
||||
{
|
||||
this.ValidatePropertyOrderAttributes( list );
|
||||
|
||||
if( this.IsPropertyGridCategorized )
|
||||
{
|
||||
var attribute = list.FirstOrDefault( x => ((x.UsageContext == UsageContextEnum.Categorized)
|
||||
|| (x.UsageContext == UsageContextEnum.Both)) );
|
||||
if( attribute != null )
|
||||
return attribute.Order;
|
||||
}
|
||||
else
|
||||
{
|
||||
var attribute = list.FirstOrDefault( x => ((x.UsageContext == UsageContextEnum.Alphabetical)
|
||||
|| (x.UsageContext == UsageContextEnum.Both)) );
|
||||
if( attribute != null )
|
||||
return attribute.Order;
|
||||
}
|
||||
}
|
||||
|
||||
// Max Value. Properties with no order will be displayed last.
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
internal object ComputeExpandableAttributeForItem( object item )
|
||||
{
|
||||
var pd = (PropertyDescriptor)item;
|
||||
|
||||
var attribute = PropertyGridUtilities.GetAttribute<ExpandableObjectAttribute>( pd );
|
||||
return (attribute != null);
|
||||
}
|
||||
|
||||
internal int ComputeDisplayOrderInternal( bool isPropertyGridCategorized )
|
||||
{
|
||||
return this.ComputeDisplayOrder( isPropertyGridCategorized );
|
||||
}
|
||||
|
||||
internal object GetValueInstance( object sourceObject )
|
||||
{
|
||||
ICustomTypeDescriptor customTypeDescriptor = sourceObject as ICustomTypeDescriptor;
|
||||
if( customTypeDescriptor != null )
|
||||
sourceObject = customTypeDescriptor.GetPropertyOwner( PropertyDescriptor );
|
||||
|
||||
return sourceObject;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ExecuteResetValueCommand( object sender, ExecutedRoutedEventArgs e )
|
||||
{
|
||||
if( ComputeCanResetValue() )
|
||||
ResetValue();
|
||||
}
|
||||
|
||||
private void CanExecuteResetValueCommand( object sender, CanExecuteRoutedEventArgs e )
|
||||
{
|
||||
e.CanExecute = ComputeCanResetValue();
|
||||
}
|
||||
|
||||
private string ComputeDisplayName()
|
||||
{
|
||||
#if VS2008
|
||||
var displayName = PropertyDescriptor.DisplayName;
|
||||
#else
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( PropertyDescriptor );
|
||||
var displayName = (displayAttribute != null) ? displayAttribute.GetName() : PropertyDescriptor.DisplayName;
|
||||
#endif
|
||||
|
||||
var attribute = PropertyGridUtilities.GetAttribute<ParenthesizePropertyNameAttribute>( PropertyDescriptor );
|
||||
if( (attribute != null) && attribute.NeedParenthesis )
|
||||
{
|
||||
displayName = "(" + displayName + ")";
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
private void ValidatePropertyOrderAttributes( List<PropertyOrderAttribute> list )
|
||||
{
|
||||
if( list.Count > 0 )
|
||||
{
|
||||
PropertyOrderAttribute both = list.FirstOrDefault( x => x.UsageContext == UsageContextEnum.Both );
|
||||
if( (both != null) && (list.Count > 1) )
|
||||
Debug.Assert( false, "A PropertyItem can't have more than 1 PropertyOrderAttribute when it has UsageContext : Both" );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler ContainerHelperInvalidated;
|
||||
|
||||
#endregion
|
||||
|
||||
#region AdvancedOptionsIcon (DP)
|
||||
|
||||
public static readonly DependencyProperty AdvancedOptionsIconProperty =
|
||||
DependencyProperty.Register( "AdvancedOptionsIcon", typeof( ImageSource ), typeof( DescriptorPropertyDefinitionBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public ImageSource AdvancedOptionsIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ImageSource)GetValue( AdvancedOptionsIconProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( AdvancedOptionsIconProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AdvancedOptionsTooltip (DP)
|
||||
|
||||
public static readonly DependencyProperty AdvancedOptionsTooltipProperty =
|
||||
DependencyProperty.Register( "AdvancedOptionsTooltip", typeof( object ), typeof( DescriptorPropertyDefinitionBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public object AdvancedOptionsTooltip
|
||||
{
|
||||
get
|
||||
{
|
||||
return (object)GetValue( AdvancedOptionsTooltipProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( AdvancedOptionsTooltipProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //AdvancedOptionsTooltip
|
||||
|
||||
#region IsExpandable (DP)
|
||||
|
||||
public static readonly DependencyProperty IsExpandableProperty =
|
||||
DependencyProperty.Register( "IsExpandable", typeof( bool ), typeof( DescriptorPropertyDefinitionBase ), new UIPropertyMetadata( false ) );
|
||||
|
||||
public bool IsExpandable
|
||||
{
|
||||
get
|
||||
{
|
||||
return (bool)GetValue( IsExpandableProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( IsExpandableProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //IsExpandable
|
||||
|
||||
public string Category
|
||||
{
|
||||
get
|
||||
{
|
||||
return _category;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_category = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string CategoryValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _categoryValue;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_categoryValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<CommandBinding> CommandBindings
|
||||
{
|
||||
get
|
||||
{
|
||||
return _commandBindings;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _displayName;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_displayName = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_description = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int DisplayOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return _displayOrder;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_displayOrder = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Type> NewItemTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _newItemTypes;
|
||||
}
|
||||
}
|
||||
|
||||
public string PropertyName
|
||||
{
|
||||
get
|
||||
{
|
||||
// A common property which is present in all selectedObjects will always have the same name.
|
||||
return PropertyDescriptor.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public Type PropertyType
|
||||
{
|
||||
get
|
||||
{
|
||||
return PropertyDescriptor.PropertyType;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ExpandableAttribute
|
||||
{
|
||||
get
|
||||
{
|
||||
return _expandableAttribute;
|
||||
}
|
||||
set
|
||||
{
|
||||
_expandableAttribute = value;
|
||||
this.UpdateIsExpandable();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsPropertyGridCategorized
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
#region Value Property (DP)
|
||||
|
||||
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( object ), typeof( DescriptorPropertyDefinitionBase ), new UIPropertyMetadata( null, OnValueChanged ) );
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetValue( ValueProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( ValueProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnValueChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
((DescriptorPropertyDefinitionBase)o).OnValueChanged( e.OldValue, e.NewValue );
|
||||
}
|
||||
|
||||
internal virtual void OnValueChanged( object oldValue, object newValue )
|
||||
{
|
||||
UpdateIsExpandable();
|
||||
UpdateAdvanceOptions();
|
||||
|
||||
// Reset command also affected.
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
#endregion //Value Property
|
||||
|
||||
public virtual void InitProperties()
|
||||
{
|
||||
// Do "IsReadOnly" and PropertyName first since the others may need that value.
|
||||
_isReadOnly = ComputeIsReadOnly();
|
||||
_category = ComputeCategory();
|
||||
_categoryValue = ComputeCategoryValue();
|
||||
_description = ComputeDescription();
|
||||
_displayName = ComputeDisplayName();
|
||||
_displayOrder = ComputeDisplayOrder( this.IsPropertyGridCategorized );
|
||||
|
||||
_expandableAttribute = ComputeExpandableAttribute();
|
||||
|
||||
|
||||
_newItemTypes = ComputeNewItemTypes();
|
||||
_commandBindings = new CommandBinding[] { new CommandBinding( PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand ) };
|
||||
|
||||
UpdateIsExpandable();
|
||||
UpdateAdvanceOptions();
|
||||
|
||||
BindingBase valueBinding = this.CreateValueBinding();
|
||||
BindingOperations.SetBinding( this, DescriptorPropertyDefinitionBase.ValueProperty, valueBinding );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
[Obsolete(@"Use EditorTemplateDefinition instead of EditorDefinition. " + EditorDefinition.UsageEx)]
|
||||
public class EditorDefinition : EditorTemplateDefinition
|
||||
{
|
||||
private const string UsageEx = " (XAML Ex: <t:EditorTemplateDefinition TargetProperties=\"FirstName,LastName\" .../> OR <t:EditorTemplateDefinition TargetProperties=\"{x:Type l:MyType}\" .../> )";
|
||||
|
||||
public EditorDefinition()
|
||||
{
|
||||
const string usageErr = "{0} is obsolete. Instead use {1}.";
|
||||
System.Diagnostics.Trace.TraceWarning( string.Format( usageErr, typeof( EditorDefinition ), typeof( EditorTemplateDefinition ) ) + UsageEx );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the template of the editor.
|
||||
/// This Property is part of the obsolete EditorDefinition class.
|
||||
/// Use EditorTemplateDefinition class and the Edit<b>ing</b>Template property.
|
||||
/// </summary>
|
||||
public DataTemplate EditorTemplate
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
private PropertyDefinitionCollection _properties = new PropertyDefinitionCollection();
|
||||
/// <summary>
|
||||
/// List the PropertyDefinitions that identify the properties targeted by the EditorTemplate.
|
||||
/// This Property is part of the obsolete EditorDefinition class.
|
||||
/// Use "EditorTemplateDefinition" class and the "TargetProperties" property<br/>
|
||||
/// XAML Ex.: <t:EditorTemplateDefinition TargetProperties="FirstName,LastName" .../>
|
||||
/// </summary>
|
||||
public PropertyDefinitionCollection PropertiesDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
set
|
||||
{
|
||||
_properties = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
internal override void Lock()
|
||||
{
|
||||
const string usageError = @"Use a EditorTemplateDefinition instead of EditorDefinition in order to use the '{0}' property.";
|
||||
if( this.EditingTemplate != null )
|
||||
throw new InvalidOperationException( string.Format( usageError, "EditingTemplate" ) );
|
||||
|
||||
if( this.TargetProperties != null && this.TargetProperties.Count > 0)
|
||||
throw new InvalidOperationException( string.Format( usageError, "TargetProperties" ) );
|
||||
|
||||
List<object> properties = new List<object>();
|
||||
if( this.PropertiesDefinitions != null )
|
||||
{
|
||||
foreach( PropertyDefinition def in this.PropertiesDefinitions )
|
||||
{
|
||||
if( def.TargetProperties != null )
|
||||
{
|
||||
properties.AddRange( def.TargetProperties.Cast<object>() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.TargetProperties = properties;
|
||||
this.EditingTemplate = this.EditorTemplate;
|
||||
|
||||
base.Lock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class CheckBoxEditor : TypeEditor<CheckBox>
|
||||
{
|
||||
protected override CheckBox CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorCheckBox();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.Margin = new Thickness( 5, 0, 0, 0 );
|
||||
}
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = CheckBox.IsCheckedProperty;
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorCheckBox : CheckBox
|
||||
{
|
||||
static PropertyGridEditorCheckBox()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorCheckBox ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorCheckBox ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class CollectionEditor : TypeEditor<CollectionControlButton>
|
||||
{
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = CollectionControlButton.ItemsSourceProperty;
|
||||
}
|
||||
|
||||
|
||||
protected override void ResolveValueBinding( PropertyItem propertyItem )
|
||||
{
|
||||
var type = propertyItem.PropertyType;
|
||||
|
||||
Editor.ItemsSourceType = type;
|
||||
|
||||
if( type.BaseType == typeof( System.Array ) )
|
||||
{
|
||||
Editor.NewItemTypes = new List<Type>() { type.GetElementType() };
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (propertyItem.DescriptorDefinition != null)
|
||||
&& (propertyItem.DescriptorDefinition.NewItemTypes != null)
|
||||
&& (propertyItem.DescriptorDefinition.NewItemTypes.Count > 0) )
|
||||
{
|
||||
Editor.NewItemTypes = propertyItem.DescriptorDefinition.NewItemTypes;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check if we have a Dictionary
|
||||
var dictionaryTypes = ListUtilities.GetDictionaryItemsType( type );
|
||||
if( (dictionaryTypes != null) && (dictionaryTypes.Length == 2) )
|
||||
{
|
||||
// A Dictionary contains KeyValuePair that can't be edited.
|
||||
// We need to create EditableKeyValuePairs.
|
||||
// Create a EditableKeyValuePair< TKey, TValue> type from dictionary generic arguments type
|
||||
var editableKeyValuePairType = ListUtilities.CreateEditableKeyValuePairType( dictionaryTypes[ 0 ], dictionaryTypes[ 1 ] );
|
||||
Editor.NewItemTypes = new List<Type>() { editableKeyValuePairType };
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check if we have a list
|
||||
var listType = ListUtilities.GetListItemType( type );
|
||||
if( listType != null )
|
||||
{
|
||||
Editor.NewItemTypes = new List<Type>() { listType };
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check if we have a Collection of T
|
||||
var colType = ListUtilities.GetCollectionItemType( type );
|
||||
if( colType != null )
|
||||
{
|
||||
Editor.NewItemTypes = new List<Type>() { colType };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.ResolveValueBinding( propertyItem );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PropertyGridEditorCollectionControl : CollectionControlButton
|
||||
{
|
||||
static PropertyGridEditorCollectionControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorCollectionControl ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorCollectionControl ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class ColorEditor : TypeEditor<ColorPicker>
|
||||
{
|
||||
protected override ColorPicker CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorColorPicker();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.BorderThickness = new System.Windows.Thickness( 0 );
|
||||
Editor.DisplayColorAndName = true;
|
||||
}
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = ColorPicker.SelectedColorProperty;
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorColorPicker : ColorPicker
|
||||
{
|
||||
static PropertyGridEditorColorPicker()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorColorPicker ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorColorPicker ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public abstract class ComboBoxEditor : TypeEditor<System.Windows.Controls.ComboBox>
|
||||
{
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = System.Windows.Controls.ComboBox.SelectedItemProperty;
|
||||
}
|
||||
|
||||
protected override System.Windows.Controls.ComboBox CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorComboBox();
|
||||
}
|
||||
|
||||
protected override void ResolveValueBinding( PropertyItem propertyItem )
|
||||
{
|
||||
SetItemsSource( propertyItem );
|
||||
base.ResolveValueBinding( propertyItem );
|
||||
}
|
||||
|
||||
protected abstract IEnumerable CreateItemsSource( PropertyItem propertyItem );
|
||||
|
||||
private void SetItemsSource( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.ItemsSource = CreateItemsSource( propertyItem );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorComboBox : System.Windows.Controls.ComboBox
|
||||
{
|
||||
static PropertyGridEditorComboBox()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorComboBox ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorComboBox ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Reflection;
|
||||
using System.Collections;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class EnumComboBoxEditor : ComboBoxEditor
|
||||
{
|
||||
protected override IEnumerable CreateItemsSource( PropertyItem propertyItem )
|
||||
{
|
||||
return GetValues( propertyItem.PropertyType );
|
||||
}
|
||||
|
||||
private static object[] GetValues( Type enumType )
|
||||
{
|
||||
List<object> values = new List<object>();
|
||||
|
||||
if( enumType != null )
|
||||
{
|
||||
var fields = enumType.GetFields().Where( x => x.IsLiteral );
|
||||
foreach( FieldInfo field in fields )
|
||||
{
|
||||
// Get array of BrowsableAttribute attributes
|
||||
object[] attrs = field.GetCustomAttributes( typeof( BrowsableAttribute ), false );
|
||||
if( attrs.Length == 1 )
|
||||
{
|
||||
// If attribute exists and its value is false continue to the next field...
|
||||
BrowsableAttribute brAttr = ( BrowsableAttribute )attrs[ 0 ];
|
||||
if( brAttr.Browsable == false )
|
||||
continue;
|
||||
}
|
||||
|
||||
values.Add( field.GetValue( enumType ) );
|
||||
}
|
||||
}
|
||||
|
||||
return values.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Collections;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class FontComboBoxEditor : ComboBoxEditor
|
||||
{
|
||||
protected override IEnumerable CreateItemsSource( PropertyItem propertyItem )
|
||||
{
|
||||
if( propertyItem.PropertyType == typeof( FontFamily ) )
|
||||
return FontUtilities.Families.OrderBy( x => x.Source);
|
||||
else if( propertyItem.PropertyType == typeof( FontWeight ) )
|
||||
return FontUtilities.Weights;
|
||||
else if( propertyItem.PropertyType == typeof( FontStyle ) )
|
||||
return FontUtilities.Styles;
|
||||
else if( propertyItem.PropertyType == typeof( FontStretch ) )
|
||||
return FontUtilities.Stretches;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public interface ITypeEditor
|
||||
{
|
||||
FrameworkElement ResolveEditor( PropertyItem propertyItem );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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 Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class ItemsSourceAttributeEditor : TypeEditor<System.Windows.Controls.ComboBox>
|
||||
{
|
||||
private readonly ItemsSourceAttribute _attribute;
|
||||
|
||||
public ItemsSourceAttributeEditor( ItemsSourceAttribute attribute )
|
||||
{
|
||||
_attribute = attribute;
|
||||
}
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = System.Windows.Controls.ComboBox.SelectedValueProperty;
|
||||
}
|
||||
|
||||
protected override System.Windows.Controls.ComboBox CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorComboBox();
|
||||
}
|
||||
|
||||
protected override void ResolveValueBinding( PropertyItem propertyItem )
|
||||
{
|
||||
SetItemsSource();
|
||||
base.ResolveValueBinding( propertyItem );
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.DisplayMemberPath = "DisplayName";
|
||||
Editor.SelectedValuePath = "Value";
|
||||
}
|
||||
|
||||
private void SetItemsSource()
|
||||
{
|
||||
Editor.ItemsSource = CreateItemsSource();
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerable CreateItemsSource()
|
||||
{
|
||||
var instance = Activator.CreateInstance( _attribute.Type );
|
||||
return ( instance as IItemsSource ).GetValues();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class MaskedTextBoxEditor : TypeEditor<MaskedTextBox>
|
||||
{
|
||||
public string Mask
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Type ValueDataType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.BorderThickness = new System.Windows.Thickness( 0 );
|
||||
this.Editor.ValueDataType = this.ValueDataType;
|
||||
this.Editor.Mask = this.Mask;
|
||||
}
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
this.ValueProperty = MaskedTextBox.ValueProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class PrimitiveTypeCollectionEditor : TypeEditor<PrimitiveTypeCollectionControl>
|
||||
{
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.BorderThickness = new System.Windows.Thickness( 0 );
|
||||
Editor.Content = "(Collection)";
|
||||
}
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = PrimitiveTypeCollectionControl.ItemsSourceProperty;
|
||||
}
|
||||
|
||||
protected override void ResolveValueBinding( PropertyItem propertyItem )
|
||||
{
|
||||
var type = propertyItem.PropertyType;
|
||||
Editor.ItemsSourceType = type;
|
||||
|
||||
if( type.BaseType == typeof( System.Array ) )
|
||||
{
|
||||
Editor.ItemType = type.GetElementType();
|
||||
}
|
||||
else
|
||||
{
|
||||
var typeArguments = type.GetGenericArguments();
|
||||
if( typeArguments.Length > 0 )
|
||||
{
|
||||
Editor.ItemType = typeArguments[ 0 ];
|
||||
}
|
||||
}
|
||||
|
||||
base.ResolveValueBinding( propertyItem );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorPrimitiveTypeCollectionControl : PrimitiveTypeCollectionControl
|
||||
{
|
||||
static PropertyGridEditorPrimitiveTypeCollectionControl()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorPrimitiveTypeCollectionControl ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorPrimitiveTypeCollectionControl ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class SourceComboBoxEditor : ComboBoxEditor
|
||||
{
|
||||
ICollection _collection;
|
||||
TypeConverter _typeConverter;
|
||||
|
||||
public SourceComboBoxEditor( ICollection collection, TypeConverter typeConverter )
|
||||
{
|
||||
_collection = collection;
|
||||
_typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
protected override IEnumerable CreateItemsSource( PropertyItem propertyItem )
|
||||
{
|
||||
return _collection;
|
||||
}
|
||||
|
||||
protected override IValueConverter CreateValueConverter()
|
||||
{
|
||||
//When using a stringConverter, we need to convert the value
|
||||
if( (_typeConverter != null) && (_typeConverter is StringConverter) )
|
||||
return new SourceComboBoxEditorConverter( _typeConverter );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SourceComboBoxEditorConverter : IValueConverter
|
||||
{
|
||||
private TypeConverter _typeConverter;
|
||||
|
||||
internal SourceComboBoxEditorConverter( TypeConverter typeConverter )
|
||||
{
|
||||
_typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( _typeConverter != null )
|
||||
{
|
||||
if( _typeConverter.CanConvertTo( typeof(string) ) )
|
||||
return _typeConverter.ConvertTo( value, typeof(string) );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
|
||||
{
|
||||
if( _typeConverter != null )
|
||||
{
|
||||
if( _typeConverter.CanConvertFrom( value.GetType() ) )
|
||||
return _typeConverter.ConvertFrom( value );
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows.Controls;
|
||||
using System.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class TextBlockEditor : TypeEditor<TextBlock>
|
||||
{
|
||||
protected override TextBlock CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorTextBlock();
|
||||
}
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = TextBlock.TextProperty;
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.Margin = new System.Windows.Thickness( 5, 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorTextBlock : TextBlock
|
||||
{
|
||||
static PropertyGridEditorTextBlock()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorTextBlock ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorTextBlock ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows.Controls;
|
||||
using System.Windows;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class TextBoxEditor : TypeEditor<WatermarkTextBox>
|
||||
{
|
||||
protected override WatermarkTextBox CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorTextBox();
|
||||
}
|
||||
|
||||
#if !VS2008
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( propertyItem.PropertyDescriptor );
|
||||
if( displayAttribute != null )
|
||||
{
|
||||
this.Editor.Watermark = displayAttribute.GetPrompt();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = TextBox.TextProperty;
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorTextBox : WatermarkTextBox
|
||||
{
|
||||
static PropertyGridEditorTextBox()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorTextBox ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorTextBox ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Windows;
|
||||
using System.Windows.Data;
|
||||
using Xceed.Wpf.Toolkit.Primitives;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public abstract class TypeEditor<T> : ITypeEditor where T : FrameworkElement, new()
|
||||
{
|
||||
#region Properties
|
||||
|
||||
protected T Editor
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
protected DependencyProperty ValueProperty
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region ITypeEditor Members
|
||||
|
||||
public virtual FrameworkElement ResolveEditor( PropertyItem propertyItem )
|
||||
{
|
||||
Editor = this.CreateEditor();
|
||||
SetValueDependencyProperty();
|
||||
SetControlProperties( propertyItem );
|
||||
ResolveValueBinding( propertyItem );
|
||||
return Editor;
|
||||
}
|
||||
|
||||
#endregion //ITypeEditor Members
|
||||
|
||||
#region Methods
|
||||
|
||||
protected virtual T CreateEditor()
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
|
||||
protected virtual IValueConverter CreateValueConverter()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual void ResolveValueBinding( PropertyItem propertyItem )
|
||||
{
|
||||
var _binding = new Binding( "Value" );
|
||||
_binding.Source = propertyItem;
|
||||
_binding.UpdateSourceTrigger = (Editor is InputBase) ? UpdateSourceTrigger.PropertyChanged : UpdateSourceTrigger.Default;
|
||||
_binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
|
||||
_binding.Converter = CreateValueConverter();
|
||||
BindingOperations.SetBinding( Editor, ValueProperty, _binding );
|
||||
}
|
||||
|
||||
protected virtual void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
//TODO: implement in derived class
|
||||
}
|
||||
|
||||
protected abstract void SetValueDependencyProperty();
|
||||
|
||||
#endregion //Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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 Xceed.Wpf.Toolkit.Primitives;
|
||||
using System;
|
||||
using System.Windows;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Editors
|
||||
{
|
||||
public class UpDownEditor<TEditor, TType> : TypeEditor<TEditor> where TEditor : UpDownBase<TType>, new()
|
||||
{
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
Editor.TextAlignment = System.Windows.TextAlignment.Left;
|
||||
}
|
||||
protected override void SetValueDependencyProperty()
|
||||
{
|
||||
ValueProperty = UpDownBase<TType>.ValueProperty;
|
||||
}
|
||||
|
||||
#if !VS2008
|
||||
internal void SetMinMaxFromRangeAttribute( PropertyDescriptor propertyDescriptor, TypeConverter converter )
|
||||
{
|
||||
if( propertyDescriptor == null )
|
||||
return;
|
||||
|
||||
var rangeAttribute = PropertyGridUtilities.GetAttribute<RangeAttribute>( propertyDescriptor );
|
||||
if( rangeAttribute != null )
|
||||
{
|
||||
Editor.Maximum = ((TType)converter.ConvertFrom( rangeAttribute.Maximum.ToString() ));
|
||||
Editor.Minimum = ((TType)converter.ConvertFrom( rangeAttribute.Minimum.ToString() ));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public class ByteUpDownEditor : UpDownEditor<ByteUpDown, byte?>
|
||||
{
|
||||
protected override ByteUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorByteUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( byte ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class DecimalUpDownEditor : UpDownEditor<DecimalUpDown, decimal?>
|
||||
{
|
||||
protected override DecimalUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorDecimalUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( decimal ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class DoubleUpDownEditor : UpDownEditor<DoubleUpDown, double?>
|
||||
{
|
||||
protected override DoubleUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorDoubleUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
Editor.AllowInputSpecialValues = AllowedSpecialValues.Any;
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( double ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class IntegerUpDownEditor : UpDownEditor<IntegerUpDown, int?>
|
||||
{
|
||||
protected override IntegerUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorIntegerUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( int ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class LongUpDownEditor : UpDownEditor<LongUpDown, long?>
|
||||
{
|
||||
protected override LongUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorLongUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( long ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class ShortUpDownEditor : UpDownEditor<ShortUpDown, short?>
|
||||
{
|
||||
protected override ShortUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorShortUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( short ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class SingleUpDownEditor : UpDownEditor<SingleUpDown, float?>
|
||||
{
|
||||
protected override SingleUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorSingleUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
Editor.AllowInputSpecialValues = AllowedSpecialValues.Any;
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( float ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class DateTimeUpDownEditor : UpDownEditor<DateTimeUpDown, DateTime?>
|
||||
{
|
||||
protected override DateTimeUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorDateTimeUpDown();
|
||||
}
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( DateTime ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public class TimeSpanUpDownEditor : UpDownEditor<TimeSpanUpDown, TimeSpan?>
|
||||
{
|
||||
protected override TimeSpanUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorTimeSpanUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( TimeSpan ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class SByteUpDownEditor : UpDownEditor<SByteUpDown, sbyte?>
|
||||
{
|
||||
protected override SByteUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorSByteUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( sbyte ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class UIntegerUpDownEditor : UpDownEditor<UIntegerUpDown, uint?>
|
||||
{
|
||||
protected override UIntegerUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorUIntegerUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( uint ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class ULongUpDownEditor : UpDownEditor<ULongUpDown, ulong?>
|
||||
{
|
||||
protected override ULongUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorULongUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( ulong ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal class UShortUpDownEditor : UpDownEditor<UShortUpDown, ushort?>
|
||||
{
|
||||
protected override UShortUpDown CreateEditor()
|
||||
{
|
||||
return new PropertyGridEditorUShortUpDown();
|
||||
}
|
||||
|
||||
protected override void SetControlProperties( PropertyItem propertyItem )
|
||||
{
|
||||
base.SetControlProperties( propertyItem );
|
||||
#if !VS2008
|
||||
this.SetMinMaxFromRangeAttribute( propertyItem.PropertyDescriptor, TypeDescriptor.GetConverter( typeof( ushort ) ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class PropertyGridEditorByteUpDown : ByteUpDown
|
||||
{
|
||||
static PropertyGridEditorByteUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorByteUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorByteUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorDecimalUpDown : DecimalUpDown
|
||||
{
|
||||
static PropertyGridEditorDecimalUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorDecimalUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorDecimalUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorDoubleUpDown : DoubleUpDown
|
||||
{
|
||||
static PropertyGridEditorDoubleUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorDoubleUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorDoubleUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorIntegerUpDown : IntegerUpDown
|
||||
{
|
||||
static PropertyGridEditorIntegerUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorIntegerUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorIntegerUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorLongUpDown : LongUpDown
|
||||
{
|
||||
static PropertyGridEditorLongUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorLongUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorLongUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorShortUpDown : ShortUpDown
|
||||
{
|
||||
static PropertyGridEditorShortUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorShortUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorShortUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorSingleUpDown : SingleUpDown
|
||||
{
|
||||
static PropertyGridEditorSingleUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorSingleUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorSingleUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorDateTimeUpDown : DateTimeUpDown
|
||||
{
|
||||
static PropertyGridEditorDateTimeUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorDateTimeUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorDateTimeUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class PropertyGridEditorTimeSpanUpDown : TimeSpanUpDown
|
||||
{
|
||||
static PropertyGridEditorTimeSpanUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorTimeSpanUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorTimeSpanUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
internal class PropertyGridEditorSByteUpDown : SByteUpDown
|
||||
{
|
||||
static PropertyGridEditorSByteUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorSByteUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorSByteUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
internal class PropertyGridEditorUIntegerUpDown : UIntegerUpDown
|
||||
{
|
||||
static PropertyGridEditorUIntegerUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorUIntegerUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorUIntegerUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
internal class PropertyGridEditorULongUpDown : ULongUpDown
|
||||
{
|
||||
static PropertyGridEditorULongUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorULongUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorULongUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
internal class PropertyGridEditorUShortUpDown : UShortUpDown
|
||||
{
|
||||
static PropertyGridEditorUShortUpDown()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorUShortUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorUShortUpDown ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal struct FilterInfo
|
||||
{
|
||||
public string InputString;
|
||||
public Predicate<object> Predicate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Data;
|
||||
using System;
|
||||
using System.Windows;
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal interface IPropertyContainer
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ContainerHelperBase ContainerHelper { get; }
|
||||
|
||||
Style PropertyContainerStyle { get; }
|
||||
|
||||
EditorDefinitionCollection EditorDefinitions { get; }
|
||||
|
||||
PropertyDefinitionCollection PropertyDefinitions { get; }
|
||||
|
||||
bool IsCategorized { get; }
|
||||
|
||||
bool IsSortedAlphabetically { get; }
|
||||
|
||||
bool AutoGenerateProperties { get; }
|
||||
|
||||
bool HideInheritedProperties { get; }
|
||||
|
||||
FilterInfo FilterInfo { get; }
|
||||
|
||||
bool? IsPropertyVisible( PropertyDescriptor pd );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal class ObjectContainerHelper : ObjectContainerHelperBase
|
||||
{
|
||||
private object _selectedObject;
|
||||
|
||||
public ObjectContainerHelper( IPropertyContainer propertyContainer, object selectedObject )
|
||||
: base( propertyContainer )
|
||||
{
|
||||
_selectedObject = selectedObject;
|
||||
}
|
||||
|
||||
private object SelectedObject
|
||||
{
|
||||
get
|
||||
{
|
||||
return _selectedObject;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string GetDefaultPropertyName()
|
||||
{
|
||||
object selectedObject = SelectedObject;
|
||||
return ( selectedObject != null ) ? ObjectContainerHelperBase.GetDefaultPropertyName( SelectedObject ) : ( string )null;
|
||||
}
|
||||
|
||||
protected override IEnumerable<PropertyItem> GenerateSubPropertiesCore()
|
||||
{
|
||||
var propertyItems = new List<PropertyItem>();
|
||||
|
||||
if( SelectedObject != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
List<PropertyDescriptor> descriptors = new List<PropertyDescriptor>();
|
||||
{
|
||||
descriptors = ObjectContainerHelperBase.GetPropertyDescriptors( SelectedObject, this.PropertyContainer.HideInheritedProperties );
|
||||
}
|
||||
|
||||
foreach( var descriptor in descriptors )
|
||||
{
|
||||
var propertyDef = this.GetPropertyDefinition( descriptor );
|
||||
bool isBrowsable = false;
|
||||
|
||||
var isPropertyBrowsable = this.PropertyContainer.IsPropertyVisible( descriptor );
|
||||
if( isPropertyBrowsable.HasValue )
|
||||
{
|
||||
isBrowsable = isPropertyBrowsable.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !VS2008
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( descriptor );
|
||||
if( displayAttribute != null )
|
||||
{
|
||||
var autoGenerateField = displayAttribute.GetAutoGenerateField();
|
||||
isBrowsable = this.PropertyContainer.AutoGenerateProperties
|
||||
&& ((autoGenerateField.HasValue && autoGenerateField.Value) || !autoGenerateField.HasValue);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
isBrowsable = descriptor.IsBrowsable && this.PropertyContainer.AutoGenerateProperties;
|
||||
}
|
||||
|
||||
if( propertyDef != null )
|
||||
{
|
||||
isBrowsable = propertyDef.IsBrowsable.GetValueOrDefault( isBrowsable );
|
||||
}
|
||||
}
|
||||
|
||||
if( isBrowsable )
|
||||
{
|
||||
var prop = this.CreatePropertyItem( descriptor, propertyDef );
|
||||
if( prop != null )
|
||||
{
|
||||
propertyItems.Add( prop );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
//TODO: handle this some how
|
||||
Debug.WriteLine( "Property creation failed." );
|
||||
Debug.WriteLine( e.StackTrace );
|
||||
}
|
||||
}
|
||||
|
||||
return propertyItems;
|
||||
}
|
||||
|
||||
|
||||
private PropertyItem CreatePropertyItem( PropertyDescriptor property, PropertyDefinition propertyDef )
|
||||
{
|
||||
DescriptorPropertyDefinition definition = new DescriptorPropertyDefinition( property,
|
||||
SelectedObject,
|
||||
this.PropertyContainer.IsCategorized
|
||||
);
|
||||
definition.InitProperties();
|
||||
|
||||
this.InitializeDescriptorDefinition( definition, propertyDef );
|
||||
PropertyItem propertyItem = new PropertyItem( definition );
|
||||
Debug.Assert( SelectedObject != null );
|
||||
propertyItem.Instance = SelectedObject;
|
||||
propertyItem.CategoryOrder = this.GetCategoryOrder( definition.CategoryValue );
|
||||
propertyItem.WillRefreshPropertyGrid = this.GetWillRefreshPropertyGrid( property );
|
||||
return propertyItem;
|
||||
}
|
||||
|
||||
private int GetCategoryOrder( object categoryValue )
|
||||
{
|
||||
Debug.Assert( SelectedObject != null );
|
||||
|
||||
if( categoryValue == null )
|
||||
return int.MaxValue;
|
||||
|
||||
int order = int.MaxValue;
|
||||
object selectedObject = SelectedObject;
|
||||
CategoryOrderAttribute[] orderAttributes = ( selectedObject != null )
|
||||
? ( CategoryOrderAttribute[] )selectedObject.GetType().GetCustomAttributes( typeof( CategoryOrderAttribute ), true )
|
||||
: new CategoryOrderAttribute[ 0 ];
|
||||
|
||||
var orderAttribute = orderAttributes
|
||||
.FirstOrDefault( ( a ) => object.Equals( a.CategoryValue, categoryValue ) );
|
||||
|
||||
if( orderAttribute != null )
|
||||
{
|
||||
order = orderAttribute.Order;
|
||||
}
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,540 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal abstract class ObjectContainerHelperBase : ContainerHelperBase
|
||||
{
|
||||
// This is needed to work around the ItemsControl behavior.
|
||||
// When ItemsControl is preparing its containers, it appears
|
||||
// that calling Refresh() on the CollectionView bound to
|
||||
// the ItemsSource prevents the items from being displayed.
|
||||
// This patch is to avoid such a behavior.
|
||||
private bool _isPreparingItemFlag = false;
|
||||
private PropertyItemCollection _propertyItemCollection;
|
||||
|
||||
public ObjectContainerHelperBase( IPropertyContainer propertyContainer)
|
||||
: base( propertyContainer )
|
||||
{
|
||||
_propertyItemCollection = new PropertyItemCollection( new ObservableCollection<PropertyItem>() );
|
||||
UpdateFilter();
|
||||
UpdateCategorization( false );
|
||||
|
||||
}
|
||||
|
||||
public override IList Properties
|
||||
{
|
||||
get { return _propertyItemCollection; }
|
||||
}
|
||||
|
||||
private PropertyItem DefaultProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
PropertyItem defaultProperty = null;
|
||||
var defaultName = this.GetDefaultPropertyName();
|
||||
if( defaultName != null )
|
||||
{
|
||||
defaultProperty = _propertyItemCollection
|
||||
.FirstOrDefault( ( prop ) => object.Equals( defaultName, prop.PropertyDescriptor.Name ) );
|
||||
}
|
||||
|
||||
return defaultProperty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected PropertyItemCollection PropertyItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyItemCollection;
|
||||
}
|
||||
}
|
||||
|
||||
public override PropertyItemBase ContainerFromItem( object item )
|
||||
{
|
||||
if( item == null )
|
||||
return null;
|
||||
// Exception case for ObjectContainerHelperBase. The "Item" may sometimes
|
||||
// be identified as a string representing the property name or
|
||||
// the PropertyItem itself.
|
||||
Debug.Assert( item is PropertyItem || item is string );
|
||||
|
||||
var propertyItem = item as PropertyItem;
|
||||
if( propertyItem != null )
|
||||
return propertyItem;
|
||||
|
||||
|
||||
var propertyStr = item as string;
|
||||
if( propertyStr != null )
|
||||
return PropertyItems.FirstOrDefault( ( prop ) => propertyStr == prop.PropertyDescriptor.Name );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object ItemFromContainer( PropertyItemBase container )
|
||||
{
|
||||
// Since this call is only used to update the PropertyGrid.SelectedProperty property,
|
||||
// return the PropertyName.
|
||||
var propertyItem = container as PropertyItem;
|
||||
if( propertyItem == null )
|
||||
return null;
|
||||
|
||||
return propertyItem.PropertyDescriptor.Name;
|
||||
}
|
||||
|
||||
public override void UpdateValuesFromSource()
|
||||
{
|
||||
foreach( PropertyItem item in PropertyItems )
|
||||
{
|
||||
item.DescriptorDefinition.UpdateValueFromSource();
|
||||
item.ContainerHelper.UpdateValuesFromSource();
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateProperties()
|
||||
{
|
||||
if( (PropertyItems.Count == 0)
|
||||
)
|
||||
{
|
||||
this.RegenerateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnFilterChanged()
|
||||
{
|
||||
this.UpdateFilter();
|
||||
}
|
||||
|
||||
protected override void OnCategorizationChanged()
|
||||
{
|
||||
UpdateCategorization( true );
|
||||
}
|
||||
|
||||
protected override void OnAutoGeneratePropertiesChanged()
|
||||
{
|
||||
this.RegenerateProperties();
|
||||
}
|
||||
|
||||
protected override void OnHideInheritedPropertiesChanged()
|
||||
{
|
||||
this.RegenerateProperties();
|
||||
}
|
||||
|
||||
protected override void OnEditorDefinitionsChanged()
|
||||
{
|
||||
this.RegenerateProperties();
|
||||
}
|
||||
|
||||
protected override void OnPropertyDefinitionsChanged()
|
||||
{
|
||||
this.RegenerateProperties();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected internal override void SetPropertiesExpansion( bool isExpanded )
|
||||
{
|
||||
if( this.Properties.Count == 0 )
|
||||
{
|
||||
this.GenerateProperties();
|
||||
}
|
||||
|
||||
base.SetPropertiesExpansion( isExpanded );
|
||||
}
|
||||
|
||||
protected internal override void SetPropertiesExpansion( string propertyName, bool isExpanded )
|
||||
{
|
||||
if( this.Properties.Count == 0 )
|
||||
{
|
||||
this.GenerateProperties();
|
||||
}
|
||||
|
||||
base.SetPropertiesExpansion( propertyName, isExpanded );
|
||||
}
|
||||
|
||||
private void UpdateFilter()
|
||||
{
|
||||
FilterInfo filterInfo = PropertyContainer.FilterInfo;
|
||||
|
||||
PropertyItems.FilterPredicate = filterInfo.Predicate
|
||||
?? PropertyItemCollection.CreateFilter( filterInfo.InputString );
|
||||
}
|
||||
|
||||
private void UpdateCategorization( bool updateSubPropertiesCategorization )
|
||||
{
|
||||
_propertyItemCollection.UpdateCategorization( this.ComputeCategoryGroupDescription(), this.PropertyContainer.IsCategorized, this.PropertyContainer.IsSortedAlphabetically );
|
||||
if( updateSubPropertiesCategorization && (_propertyItemCollection.Count > 0) )
|
||||
{
|
||||
foreach( PropertyItem propertyItem in _propertyItemCollection )
|
||||
{
|
||||
PropertyItemCollection subPropertyItemsCollection = propertyItem.Properties as PropertyItemCollection;
|
||||
if( subPropertyItemsCollection != null )
|
||||
{
|
||||
subPropertyItemsCollection.UpdateCategorization( this.ComputeCategoryGroupDescription(), this.PropertyContainer.IsCategorized, this.PropertyContainer.IsSortedAlphabetically );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GroupDescription ComputeCategoryGroupDescription()
|
||||
{
|
||||
if( !PropertyContainer.IsCategorized )
|
||||
return null;
|
||||
return new PropertyGroupDescription( PropertyItemCollection.CategoryPropertyName );
|
||||
}
|
||||
|
||||
private string GetCategoryGroupingPropertyName()
|
||||
{
|
||||
var propGroup = this.ComputeCategoryGroupDescription() as PropertyGroupDescription;
|
||||
return ( propGroup != null ) ? propGroup.PropertyName : null;
|
||||
}
|
||||
|
||||
private void OnChildrenPropertyChanged( object sender, PropertyChangedEventArgs e )
|
||||
{
|
||||
if( ObjectContainerHelperBase.IsItemOrderingProperty( e.PropertyName )
|
||||
|| this.GetCategoryGroupingPropertyName() == e.PropertyName )
|
||||
{
|
||||
// Refreshing the view while Containers are generated will throw an exception
|
||||
if( this.ChildrenItemsControl.ItemContainerGenerator.Status != GeneratorStatus.GeneratingContainers
|
||||
&& !_isPreparingItemFlag )
|
||||
{
|
||||
PropertyItems.RefreshView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract string GetDefaultPropertyName();
|
||||
|
||||
protected abstract IEnumerable<PropertyItem> GenerateSubPropertiesCore();
|
||||
|
||||
private void RegenerateProperties()
|
||||
{
|
||||
IEnumerable<PropertyItem> subProperties = this.GenerateSubPropertiesCore();
|
||||
|
||||
foreach( var propertyItem in subProperties )
|
||||
{
|
||||
this.InitializePropertyItem( propertyItem );
|
||||
}
|
||||
|
||||
//Remove the event callback from the previous children (if any)
|
||||
foreach( var propertyItem in PropertyItems )
|
||||
{
|
||||
propertyItem.PropertyChanged -= OnChildrenPropertyChanged;
|
||||
}
|
||||
|
||||
PropertyItems.UpdateItems( subProperties );
|
||||
|
||||
//Add the event callback to the new childrens
|
||||
foreach( var propertyItem in PropertyItems )
|
||||
{
|
||||
propertyItem.PropertyChanged += OnChildrenPropertyChanged;
|
||||
}
|
||||
|
||||
// Update the selected property on the property grid only.
|
||||
PropertyGrid propertyGrid = PropertyContainer as PropertyGrid;
|
||||
if( propertyGrid != null )
|
||||
{
|
||||
propertyGrid.SelectedPropertyItem = this.DefaultProperty;
|
||||
}
|
||||
}
|
||||
|
||||
protected static List<PropertyDescriptor> GetPropertyDescriptors( object instance, bool hideInheritedProperties )
|
||||
{
|
||||
PropertyDescriptorCollection descriptors;
|
||||
|
||||
TypeConverter tc = TypeDescriptor.GetConverter( instance );
|
||||
if( tc == null || !tc.GetPropertiesSupported() )
|
||||
{
|
||||
if( instance is ICustomTypeDescriptor )
|
||||
{
|
||||
descriptors = ((ICustomTypeDescriptor)instance).GetProperties();
|
||||
}
|
||||
//ICustomTypeProvider is only available in .net 4.5 and over. Use reflection so the .net 4.0 and .net 3.5 still works.
|
||||
else if( instance.GetType().GetInterface( "ICustomTypeProvider", true ) != null )
|
||||
{
|
||||
var methodInfo = instance.GetType().GetMethod( "GetCustomType" );
|
||||
var result = methodInfo.Invoke( instance, null ) as Type;
|
||||
descriptors = TypeDescriptor.GetProperties( result );
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptors = TypeDescriptor.GetProperties( instance.GetType() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptors = tc.GetProperties( instance );
|
||||
}
|
||||
|
||||
if( ( descriptors != null ) )
|
||||
{
|
||||
var descriptorsProperties = descriptors.Cast<PropertyDescriptor>();
|
||||
if( hideInheritedProperties )
|
||||
{
|
||||
var properties = from p in descriptorsProperties
|
||||
where p.ComponentType == instance.GetType()
|
||||
select p;
|
||||
return properties.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return descriptorsProperties.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected bool GetWillRefreshPropertyGrid( PropertyDescriptor propertyDescriptor )
|
||||
{
|
||||
if( propertyDescriptor == null )
|
||||
return false;
|
||||
|
||||
var attribute = PropertyGridUtilities.GetAttribute<RefreshPropertiesAttribute>( propertyDescriptor );
|
||||
if( attribute != null )
|
||||
return attribute.RefreshProperties != RefreshProperties.None;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal void InitializeDescriptorDefinition(
|
||||
DescriptorPropertyDefinitionBase descriptorDef,
|
||||
PropertyDefinition propertyDefinition )
|
||||
{
|
||||
if( descriptorDef == null )
|
||||
throw new ArgumentNullException( "descriptorDef" );
|
||||
|
||||
if( propertyDefinition == null )
|
||||
return;
|
||||
|
||||
// Values defined on PropertyDefinition have priority on the attributes
|
||||
if( propertyDefinition != null )
|
||||
{
|
||||
if( propertyDefinition.Category != null )
|
||||
{
|
||||
descriptorDef.Category = propertyDefinition.Category;
|
||||
descriptorDef.CategoryValue = propertyDefinition.Category;
|
||||
}
|
||||
|
||||
if( propertyDefinition.Description != null )
|
||||
{
|
||||
descriptorDef.Description = propertyDefinition.Description;
|
||||
}
|
||||
|
||||
if( propertyDefinition.DisplayName != null )
|
||||
{
|
||||
descriptorDef.DisplayName = propertyDefinition.DisplayName;
|
||||
}
|
||||
|
||||
if( propertyDefinition.DisplayOrder != null )
|
||||
{
|
||||
descriptorDef.DisplayOrder = propertyDefinition.DisplayOrder.Value;
|
||||
}
|
||||
|
||||
if( propertyDefinition.IsExpandable != null )
|
||||
{
|
||||
descriptorDef.ExpandableAttribute = propertyDefinition.IsExpandable.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializePropertyItem( PropertyItem propertyItem )
|
||||
{
|
||||
DescriptorPropertyDefinitionBase pd = propertyItem.DescriptorDefinition;
|
||||
propertyItem.PropertyDescriptor = pd.PropertyDescriptor;
|
||||
|
||||
propertyItem.IsReadOnly = pd.IsReadOnly;
|
||||
propertyItem.DisplayName = pd.DisplayName;
|
||||
propertyItem.Description = pd.Description;
|
||||
|
||||
propertyItem.Category = pd.Category;
|
||||
propertyItem.PropertyOrder = pd.DisplayOrder;
|
||||
|
||||
//These properties can vary with the value. They need to be bound.
|
||||
if( pd.PropertyDescriptor.Converter is ExpandableObjectConverter )
|
||||
{
|
||||
propertyItem.IsExpandable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupDefinitionBinding( propertyItem, PropertyItemBase.IsExpandableProperty, pd, () => pd.IsExpandable, BindingMode.OneWay );
|
||||
}
|
||||
SetupDefinitionBinding( propertyItem, PropertyItemBase.AdvancedOptionsIconProperty, pd, () => pd.AdvancedOptionsIcon, BindingMode.OneWay );
|
||||
SetupDefinitionBinding( propertyItem, PropertyItemBase.AdvancedOptionsTooltipProperty, pd, () => pd.AdvancedOptionsTooltip, BindingMode.OneWay );
|
||||
SetupDefinitionBinding( propertyItem, PropertyItem.ValueProperty, pd, () => pd.Value, BindingMode.TwoWay );
|
||||
|
||||
if( pd.CommandBindings != null )
|
||||
{
|
||||
foreach( CommandBinding commandBinding in pd.CommandBindings )
|
||||
{
|
||||
propertyItem.CommandBindings.Add( commandBinding );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupDefinitionBinding<T>(
|
||||
PropertyItem propertyItem,
|
||||
DependencyProperty itemProperty,
|
||||
DescriptorPropertyDefinitionBase pd,
|
||||
Expression<Func<T>> definitionProperty,
|
||||
BindingMode bindingMode )
|
||||
{
|
||||
string sourceProperty = ReflectionHelper.GetPropertyOrFieldName( definitionProperty );
|
||||
Binding binding = new Binding( sourceProperty )
|
||||
{
|
||||
Source = pd,
|
||||
Mode = bindingMode
|
||||
};
|
||||
|
||||
propertyItem.SetBinding( itemProperty, binding );
|
||||
}
|
||||
|
||||
internal FrameworkElement GenerateChildrenEditorElement( PropertyItem propertyItem )
|
||||
{
|
||||
FrameworkElement editorElement = null;
|
||||
DescriptorPropertyDefinitionBase pd = propertyItem.DescriptorDefinition;
|
||||
object definitionKey = null;
|
||||
Type definitionKeyAsType = definitionKey as Type;
|
||||
ITypeEditor editor = null;
|
||||
|
||||
if( editor == null )
|
||||
editor = pd.CreateAttributeEditor();
|
||||
|
||||
if( editor != null )
|
||||
editorElement = editor.ResolveEditor( propertyItem );
|
||||
|
||||
|
||||
if( editorElement == null && definitionKey == null )
|
||||
editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyDescriptor.Name, propertyItem );
|
||||
|
||||
if( editorElement == null && definitionKeyAsType == null )
|
||||
editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyType, propertyItem );
|
||||
|
||||
if( editorElement == null )
|
||||
{
|
||||
if( pd.IsReadOnly )
|
||||
editor = new TextBlockEditor();
|
||||
|
||||
// Fallback: Use a default type editor.
|
||||
if( editor == null )
|
||||
{
|
||||
editor = ( definitionKeyAsType != null )
|
||||
? PropertyGridUtilities.CreateDefaultEditor( definitionKeyAsType, null, propertyItem )
|
||||
: pd.CreateDefaultEditor( propertyItem );
|
||||
}
|
||||
|
||||
Debug.Assert( editor != null );
|
||||
|
||||
editorElement = editor.ResolveEditor( propertyItem );
|
||||
}
|
||||
|
||||
return editorElement;
|
||||
}
|
||||
|
||||
internal PropertyDefinition GetPropertyDefinition( PropertyDescriptor descriptor )
|
||||
{
|
||||
PropertyDefinition def = null;
|
||||
|
||||
var propertyDefs = this.PropertyContainer.PropertyDefinitions;
|
||||
if( propertyDefs != null )
|
||||
{
|
||||
def = propertyDefs[ descriptor.Name ];
|
||||
if( def == null )
|
||||
{
|
||||
def = propertyDefs.GetRecursiveBaseTypes( descriptor.PropertyType );
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
public override void PrepareChildrenPropertyItem( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
_isPreparingItemFlag = true;
|
||||
base.PrepareChildrenPropertyItem( propertyItem, item );
|
||||
|
||||
if( propertyItem.Editor == null )
|
||||
{
|
||||
FrameworkElement editor = this.GenerateChildrenEditorElement( ( PropertyItem )propertyItem );
|
||||
if( editor != null )
|
||||
{
|
||||
// Tag the editor as generated to know if we should clear it.
|
||||
ContainerHelperBase.SetIsGenerated( editor, true );
|
||||
propertyItem.Editor = editor;
|
||||
}
|
||||
}
|
||||
_isPreparingItemFlag = false;
|
||||
}
|
||||
|
||||
public override void ClearChildrenPropertyItem( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
if( propertyItem.Editor != null
|
||||
&& ContainerHelperBase.GetIsGenerated( propertyItem.Editor ) )
|
||||
{
|
||||
propertyItem.Editor = null;
|
||||
}
|
||||
|
||||
base.ClearChildrenPropertyItem( propertyItem, item );
|
||||
}
|
||||
|
||||
public override Binding CreateChildrenDefaultBinding( PropertyItemBase propertyItem )
|
||||
{
|
||||
Binding binding = new Binding( "Value" );
|
||||
binding.Mode = ( ( ( PropertyItem )propertyItem ).IsReadOnly ) ? BindingMode.OneWay : BindingMode.TwoWay;
|
||||
return binding;
|
||||
}
|
||||
|
||||
protected static string GetDefaultPropertyName( object instance )
|
||||
{
|
||||
AttributeCollection attributes = TypeDescriptor.GetAttributes( instance );
|
||||
DefaultPropertyAttribute defaultPropertyAttribute = ( DefaultPropertyAttribute )attributes[ typeof( DefaultPropertyAttribute ) ];
|
||||
return defaultPropertyAttribute != null ? defaultPropertyAttribute.Name : null;
|
||||
}
|
||||
|
||||
private static bool IsItemOrderingProperty( string propertyName )
|
||||
{
|
||||
return string.Equals( propertyName, PropertyItemCollection.DisplayNamePropertyName )
|
||||
|| string.Equals( propertyName, PropertyItemCollection.CategoryOrderPropertyName )
|
||||
|| string.Equals( propertyName, PropertyItemCollection.PropertyOrderPropertyName );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class PropertyDefinition : PropertyDefinitionBase
|
||||
{
|
||||
private string _name;
|
||||
private bool? _isBrowsable = true;
|
||||
private bool? _isExpandable = null;
|
||||
private string _displayName = null;
|
||||
private string _description = null;
|
||||
private string _category = null;
|
||||
private int? _displayOrder = null;
|
||||
|
||||
[Obsolete(@"Use 'TargetProperties' instead of 'Name'")]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
const string usageError = "{0}: \'Name\' property is obsolete. Instead use \'TargetProperties\'. (XAML example: <t:PropertyDefinition TargetProperties=\"FirstName,LastName\" />)";
|
||||
System.Diagnostics.Trace.TraceWarning( usageError, typeof( PropertyDefinition ) );
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Category
|
||||
{
|
||||
get { return _category; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.Category );
|
||||
_category = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get { return _displayName; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.DisplayName );
|
||||
_displayName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return _description; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.Description );
|
||||
_description = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int? DisplayOrder
|
||||
{
|
||||
get { return _displayOrder; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.DisplayOrder );
|
||||
_displayOrder = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool? IsBrowsable
|
||||
{
|
||||
get { return _isBrowsable; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.IsBrowsable );
|
||||
_isBrowsable = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool? IsExpandable
|
||||
{
|
||||
get { return _isExpandable; }
|
||||
set
|
||||
{
|
||||
this.ThrowIfLocked( () => this.IsExpandable );
|
||||
_isExpandable = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void Lock()
|
||||
{
|
||||
if( _name != null
|
||||
&& this.TargetProperties != null
|
||||
&& this.TargetProperties.Count > 0 )
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format(
|
||||
@"{0}: When using 'TargetProperties' property, do not use 'Name' property.",
|
||||
typeof( PropertyDefinition ) ) );
|
||||
}
|
||||
|
||||
if( _name != null )
|
||||
{
|
||||
this.TargetProperties = new List<object>() { _name };
|
||||
}
|
||||
base.Lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Documents;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class PropertyDefinitionCollection : PropertyDefinitionBaseCollection<PropertyDefinition>
|
||||
{
|
||||
}
|
||||
public class EditorDefinitionCollection : PropertyDefinitionBaseCollection<EditorDefinitionBase>
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public abstract class PropertyDefinitionBaseCollection<T> : DefinitionCollectionBase<T> where T : PropertyDefinitionBase
|
||||
{
|
||||
protected PropertyDefinitionBaseCollection()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual T this[ object propertyId ]
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach( var item in Items )
|
||||
{
|
||||
if( item.TargetProperties.Contains( propertyId ) )
|
||||
return item;
|
||||
|
||||
// Using the special character "*" in a string of TargetProperties will
|
||||
// return all the items containing the string (before or after) the "*".
|
||||
// ex : Prop* will return properties named Prop1, Prop2, Prop3...
|
||||
List<string> stringTargetProperties = item.TargetProperties.OfType<string>().ToList();
|
||||
if( ( stringTargetProperties != null ) && ( stringTargetProperties.Count > 0 ) )
|
||||
{
|
||||
if( propertyId is string )
|
||||
{
|
||||
string stringPropertyID = ( string )propertyId;
|
||||
foreach( var targetPropertyString in stringTargetProperties )
|
||||
{
|
||||
if( targetPropertyString.Contains( "*" ) )
|
||||
{
|
||||
string searchString = targetPropertyString.Replace( "*", "" );
|
||||
if( stringPropertyID.StartsWith( searchString ) || stringPropertyID.EndsWith( searchString ) )
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Manage Interfaces
|
||||
var type = propertyId as Type;
|
||||
if( type != null )
|
||||
{
|
||||
foreach( Type targetProperty in item.TargetProperties )
|
||||
{
|
||||
if( targetProperty.IsAssignableFrom( type ) )
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetRecursiveBaseTypes( Type type )
|
||||
{
|
||||
// If no definition for the current type, fall back on base type editor recursively.
|
||||
T ret = null;
|
||||
while( ret == null && type != null )
|
||||
{
|
||||
ret = this[ type ];
|
||||
type = type.BaseType;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DefinitionCollectionBase<T> : ObservableCollection<T> where T : DefinitionBase
|
||||
{
|
||||
internal DefinitionCollectionBase()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InsertItem( int index, T item )
|
||||
{
|
||||
if( item == null )
|
||||
throw new InvalidOperationException( @"Cannot insert null items in the collection." );
|
||||
|
||||
item.Lock();
|
||||
base.InsertItem( index, item );
|
||||
}
|
||||
|
||||
protected override void SetItem( int index, T item )
|
||||
{
|
||||
if( item == null )
|
||||
throw new InvalidOperationException( @"Cannot insert null items in the collection." );
|
||||
|
||||
item.Lock();
|
||||
base.SetItem( index, item );
|
||||
}
|
||||
}
|
||||
}
|
||||
1473
Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs
Normal file
1473
Src/Xceed.Wpf.Toolkit/PropertyGrid/Implementation/PropertyGrid.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,210 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors;
|
||||
using System.Linq.Expressions;
|
||||
using System.Windows.Input;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Windows.Controls;
|
||||
using System.Reflection;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Converters;
|
||||
using Xceed.Wpf.Toolkit.Primitives;
|
||||
using System.IO;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
internal class PropertyGridUtilities
|
||||
{
|
||||
internal static T GetAttribute<T>( PropertyDescriptor property ) where T : Attribute
|
||||
{
|
||||
return property.Attributes.OfType<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
internal static ITypeEditor CreateDefaultEditor( Type propertyType, TypeConverter typeConverter, PropertyItem propertyItem )
|
||||
{
|
||||
ITypeEditor editor = null;
|
||||
|
||||
var context = new EditorTypeDescriptorContext( null, propertyItem.Instance, propertyItem.PropertyDescriptor );
|
||||
if( (typeConverter != null)
|
||||
&& typeConverter.GetStandardValuesSupported( context )
|
||||
&& typeConverter.GetStandardValuesExclusive( context )
|
||||
&& (propertyType != typeof( bool )) && (propertyType != typeof( bool? )) ) //Bool type always have a BooleanConverter with standardValues : True/False.
|
||||
{
|
||||
var items = typeConverter.GetStandardValues( context );
|
||||
editor = new SourceComboBoxEditor( items, typeConverter );
|
||||
}
|
||||
else if( propertyType == typeof( string ) )
|
||||
editor = new TextBoxEditor();
|
||||
else if( propertyType == typeof( bool ) || propertyType == typeof( bool? ) )
|
||||
editor = new CheckBoxEditor();
|
||||
else if( propertyType == typeof( decimal ) || propertyType == typeof( decimal? ) )
|
||||
editor = new DecimalUpDownEditor();
|
||||
else if( propertyType == typeof( double ) || propertyType == typeof( double? ) )
|
||||
editor = new DoubleUpDownEditor();
|
||||
else if( propertyType == typeof( int ) || propertyType == typeof( int? ) )
|
||||
editor = new IntegerUpDownEditor();
|
||||
else if( propertyType == typeof( short ) || propertyType == typeof( short? ) )
|
||||
editor = new ShortUpDownEditor();
|
||||
else if( propertyType == typeof( long ) || propertyType == typeof( long? ) )
|
||||
editor = new LongUpDownEditor();
|
||||
else if( propertyType == typeof( float ) || propertyType == typeof( float? ) )
|
||||
editor = new SingleUpDownEditor();
|
||||
else if( propertyType == typeof( byte ) || propertyType == typeof( byte? ) )
|
||||
editor = new ByteUpDownEditor();
|
||||
else if( propertyType == typeof( sbyte ) || propertyType == typeof( sbyte? ) )
|
||||
editor = new SByteUpDownEditor();
|
||||
else if( propertyType == typeof( uint ) || propertyType == typeof( uint? ) )
|
||||
editor = new UIntegerUpDownEditor();
|
||||
else if( propertyType == typeof( ulong ) || propertyType == typeof( ulong? ) )
|
||||
editor = new ULongUpDownEditor();
|
||||
else if( propertyType == typeof( ushort ) || propertyType == typeof( ushort? ) )
|
||||
editor = new UShortUpDownEditor();
|
||||
else if( propertyType == typeof( DateTime ) || propertyType == typeof( DateTime? ) )
|
||||
editor = new DateTimeUpDownEditor();
|
||||
else if( ( propertyType == typeof( Color ) ) || ( propertyType == typeof( Color? ) ) )
|
||||
editor = new ColorEditor();
|
||||
else if( propertyType.IsEnum )
|
||||
editor = new EnumComboBoxEditor();
|
||||
else if( propertyType == typeof( TimeSpan ) || propertyType == typeof( TimeSpan? ) )
|
||||
editor = new TimeSpanUpDownEditor();
|
||||
else if( propertyType == typeof( FontFamily ) || propertyType == typeof( FontWeight ) || propertyType == typeof( FontStyle ) || propertyType == typeof( FontStretch ) )
|
||||
editor = new FontComboBoxEditor();
|
||||
else if (propertyType == typeof(Guid) || propertyType == typeof(Guid?))
|
||||
editor = new MaskedTextBoxEditor() { ValueDataType = propertyType, Mask = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" };
|
||||
else if (propertyType == typeof(char) || propertyType == typeof(char?))
|
||||
editor = new MaskedTextBoxEditor() { ValueDataType = propertyType, Mask = "&" };
|
||||
else if( propertyType == typeof( object ) )
|
||||
// If any type of object is possible in the property, default to the TextBoxEditor.
|
||||
// Useful in some case (e.g., Button.Content).
|
||||
// Can be reconsidered but was the legacy behavior on the PropertyGrid.
|
||||
editor = new TextBoxEditor();
|
||||
else
|
||||
{
|
||||
var listType = ListUtilities.GetListItemType( propertyType );
|
||||
|
||||
// A List of T
|
||||
if( listType != null )
|
||||
{
|
||||
if( !listType.IsPrimitive && !listType.Equals( typeof( String ) ) && !listType.IsEnum )
|
||||
editor = new Xceed.Wpf.Toolkit.PropertyGrid.Editors.CollectionEditor();
|
||||
else
|
||||
editor = new Xceed.Wpf.Toolkit.PropertyGrid.Editors.PrimitiveTypeCollectionEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
var dictionaryType = ListUtilities.GetDictionaryItemsType( propertyType );
|
||||
var collectionType = ListUtilities.GetCollectionItemType( propertyType );
|
||||
// A dictionary of T or a Collection of T or an ICollection
|
||||
if( (dictionaryType != null) || (collectionType != null) || typeof( ICollection ).IsAssignableFrom( propertyType ) )
|
||||
{
|
||||
editor = new Xceed.Wpf.Toolkit.PropertyGrid.Editors.CollectionEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the type is not supported, check if there is a converter that supports
|
||||
// string conversion to the object type. Use TextBox in theses cases.
|
||||
// Otherwise, return a TextBlock editor since no valid editor exists.
|
||||
editor = (typeConverter != null && typeConverter.CanConvertFrom( typeof( string ) ))
|
||||
? (ITypeEditor)new TextBoxEditor()
|
||||
: (ITypeEditor)new TextBlockEditor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region Private class
|
||||
|
||||
private class EditorTypeDescriptorContext : ITypeDescriptorContext
|
||||
{
|
||||
IContainer _container;
|
||||
object _instance;
|
||||
PropertyDescriptor _propertyDescriptor;
|
||||
|
||||
internal EditorTypeDescriptorContext( IContainer container, object instance, PropertyDescriptor pd )
|
||||
{
|
||||
_container = container;
|
||||
_instance = instance;
|
||||
_propertyDescriptor = pd;
|
||||
}
|
||||
|
||||
IContainer ITypeDescriptorContext.Container
|
||||
{
|
||||
get
|
||||
{
|
||||
return _container;
|
||||
}
|
||||
}
|
||||
object ITypeDescriptorContext.Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
PropertyDescriptor ITypeDescriptorContext.PropertyDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return _propertyDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
void ITypeDescriptorContext.OnComponentChanged()
|
||||
{
|
||||
}
|
||||
|
||||
bool ITypeDescriptorContext.OnComponentChanging()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
object IServiceProvider.GetService( Type serviceType )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Data;
|
||||
using System.Collections;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Linq.Expressions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
[TemplatePart( Name = "content", Type = typeof( ContentControl ) )]
|
||||
public class PropertyItem : CustomPropertyItem
|
||||
{
|
||||
#region Properties
|
||||
|
||||
#region IsReadOnly
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the IsReadOnly dependency property
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsReadOnlyProperty =
|
||||
DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PropertyItem ), new UIPropertyMetadata( false ) );
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return ( bool )GetValue( IsReadOnlyProperty ); }
|
||||
set { SetValue( IsReadOnlyProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //IsReadOnly
|
||||
|
||||
#region PropertyDescriptor
|
||||
|
||||
public PropertyDescriptor PropertyDescriptor
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
#endregion //PropertyDescriptor
|
||||
|
||||
#region PropertyName
|
||||
|
||||
public string PropertyName
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.DescriptorDefinition != null) ? this.DescriptorDefinition.PropertyName : null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PropertyType
|
||||
|
||||
public Type PropertyType
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( PropertyDescriptor != null )
|
||||
? PropertyDescriptor.PropertyType
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //PropertyType
|
||||
|
||||
#region DescriptorDefinition
|
||||
|
||||
internal DescriptorPropertyDefinitionBase DescriptorDefinition
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#endregion DescriptorDefinition
|
||||
|
||||
#region Instance
|
||||
|
||||
public object Instance
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
#endregion //Instance
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region Overrides
|
||||
|
||||
protected override string GetPropertyItemName()
|
||||
{
|
||||
return this.PropertyName;
|
||||
}
|
||||
|
||||
protected override Type GetPropertyItemType()
|
||||
{
|
||||
return this.PropertyType;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void OnIsExpandedChanged( bool oldValue, bool newValue )
|
||||
{
|
||||
if( newValue )
|
||||
{
|
||||
// This withholds the generation of all PropertyItem instances (recursively)
|
||||
// until the PropertyItem is expanded.
|
||||
var objectContainerHelper = ContainerHelper as ObjectContainerHelperBase;
|
||||
if( objectContainerHelper != null )
|
||||
{
|
||||
objectContainerHelper.GenerateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override object OnCoerceValueChanged( object baseValue )
|
||||
{
|
||||
// Propagate error from DescriptorPropertyDefinitionBase to PropertyItem.Value
|
||||
// to see the red error rectangle in the propertyGrid.
|
||||
BindingExpression be = this.GetBindingExpression( PropertyItem.ValueProperty );
|
||||
this.SetRedInvalidBorder( be );
|
||||
return baseValue;
|
||||
}
|
||||
|
||||
protected override void OnValueChanged( object oldValue, object newValue )
|
||||
{
|
||||
base.OnValueChanged( oldValue, newValue );
|
||||
}
|
||||
|
||||
internal void SetRedInvalidBorder( BindingExpression be )
|
||||
{
|
||||
if( (be != null) && be.DataItem is DescriptorPropertyDefinitionBase )
|
||||
{
|
||||
DescriptorPropertyDefinitionBase descriptor = be.DataItem as DescriptorPropertyDefinitionBase;
|
||||
if( Validation.GetHasError( descriptor ) )
|
||||
{
|
||||
ReadOnlyObservableCollection<ValidationError> errors = Validation.GetErrors( descriptor );
|
||||
Validation.MarkInvalid( be, errors[ 0 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDefinitionContainerHelperInvalidated( object sender, EventArgs e )
|
||||
{
|
||||
if( this.ContainerHelper != null )
|
||||
{
|
||||
this.ContainerHelper.ClearHelper();
|
||||
}
|
||||
var helper = this.DescriptorDefinition.CreateContainerHelper( this );
|
||||
this.ContainerHelper = helper;
|
||||
if( this.IsExpanded )
|
||||
{
|
||||
helper.GenerateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void Init( DescriptorPropertyDefinitionBase definition )
|
||||
{
|
||||
if( definition == null )
|
||||
throw new ArgumentNullException( "definition" );
|
||||
|
||||
if( this.ContainerHelper != null )
|
||||
{
|
||||
this.ContainerHelper.ClearHelper();
|
||||
}
|
||||
this.DescriptorDefinition = definition;
|
||||
this.ContainerHelper = definition.CreateContainerHelper( this );
|
||||
definition.ContainerHelperInvalidated += new EventHandler( OnDefinitionContainerHelperInvalidated );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal PropertyItem( DescriptorPropertyDefinitionBase definition )
|
||||
: base( definition.IsPropertyGridCategorized, !definition.PropertyType.IsArray )
|
||||
{
|
||||
this.Init( definition );
|
||||
}
|
||||
|
||||
#endregion //Constructors
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,572 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Data;
|
||||
using System.Collections;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
using System.Reflection;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
[TemplatePart( Name = PropertyGrid.PART_PropertyItemsControl, Type = typeof( PropertyItemsControl ) )]
|
||||
[TemplatePart( Name = PropertyItemBase.PART_ValueContainer, Type = typeof( ContentControl ) )]
|
||||
public abstract class PropertyItemBase : Control, IPropertyContainer, INotifyPropertyChanged
|
||||
{
|
||||
internal const string PART_ValueContainer = "PART_ValueContainer";
|
||||
|
||||
private ContentControl _valueContainer;
|
||||
private ContainerHelperBase _containerHelper;
|
||||
private IPropertyContainer _parentNode;
|
||||
internal bool _isPropertyGridCategorized;
|
||||
internal bool _isSortedAlphabetically = true;
|
||||
|
||||
#region Properties
|
||||
|
||||
#region AdvancedOptionsIcon
|
||||
|
||||
public static readonly DependencyProperty AdvancedOptionsIconProperty =
|
||||
DependencyProperty.Register( "AdvancedOptionsIcon", typeof( ImageSource ), typeof( PropertyItemBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public ImageSource AdvancedOptionsIcon
|
||||
{
|
||||
get { return ( ImageSource )GetValue( AdvancedOptionsIconProperty ); }
|
||||
set { SetValue( AdvancedOptionsIconProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //AdvancedOptionsIcon
|
||||
|
||||
#region AdvancedOptionsTooltip
|
||||
|
||||
public static readonly DependencyProperty AdvancedOptionsTooltipProperty =
|
||||
DependencyProperty.Register( "AdvancedOptionsTooltip", typeof( object ), typeof( PropertyItemBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public object AdvancedOptionsTooltip
|
||||
{
|
||||
get { return ( object )GetValue( AdvancedOptionsTooltipProperty ); }
|
||||
set { SetValue( AdvancedOptionsTooltipProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //AdvancedOptionsTooltip
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region Description
|
||||
|
||||
public static readonly DependencyProperty DescriptionProperty =
|
||||
DependencyProperty.Register( "Description", typeof( string ), typeof( PropertyItemBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return ( string )GetValue( DescriptionProperty ); }
|
||||
set { SetValue( DescriptionProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //Description
|
||||
|
||||
#region DisplayName
|
||||
|
||||
public static readonly DependencyProperty DisplayNameProperty =
|
||||
DependencyProperty.Register( "DisplayName", typeof( string ), typeof( PropertyItemBase ), new UIPropertyMetadata( null ) );
|
||||
|
||||
public string DisplayName
|
||||
{
|
||||
get { return ( string )GetValue( DisplayNameProperty ); }
|
||||
set { SetValue( DisplayNameProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //DisplayName
|
||||
|
||||
#region Editor
|
||||
|
||||
public static readonly DependencyProperty EditorProperty = DependencyProperty.Register( "Editor", typeof( FrameworkElement ), typeof( PropertyItemBase ), new UIPropertyMetadata( null, OnEditorChanged ) );
|
||||
public FrameworkElement Editor
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( FrameworkElement )GetValue( EditorProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( EditorProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnEditorChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
PropertyItemBase propertyItem = o as PropertyItemBase;
|
||||
if( propertyItem != null )
|
||||
propertyItem.OnEditorChanged( ( FrameworkElement )e.OldValue, ( FrameworkElement )e.NewValue );
|
||||
}
|
||||
|
||||
protected virtual void OnEditorChanged( FrameworkElement oldValue, FrameworkElement newValue )
|
||||
{
|
||||
}
|
||||
|
||||
#endregion //Editor
|
||||
|
||||
#region IsExpanded
|
||||
|
||||
public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register( "IsExpanded", typeof( bool ), typeof( PropertyItemBase ), new UIPropertyMetadata( false, OnIsExpandedChanged ) );
|
||||
public bool IsExpanded
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( bool )GetValue( IsExpandedProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( IsExpandedProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIsExpandedChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
PropertyItemBase propertyItem = o as PropertyItemBase;
|
||||
if( propertyItem != null )
|
||||
propertyItem.OnIsExpandedChanged( ( bool )e.OldValue, ( bool )e.NewValue );
|
||||
}
|
||||
|
||||
protected virtual void OnIsExpandedChanged( bool oldValue, bool newValue )
|
||||
{
|
||||
}
|
||||
|
||||
#endregion IsExpanded
|
||||
|
||||
#region IsExpandable
|
||||
|
||||
public static readonly DependencyProperty IsExpandableProperty =
|
||||
DependencyProperty.Register( "IsExpandable", typeof( bool ), typeof( PropertyItemBase ), new UIPropertyMetadata( false ) );
|
||||
|
||||
public bool IsExpandable
|
||||
{
|
||||
get { return ( bool )GetValue( IsExpandableProperty ); }
|
||||
set { SetValue( IsExpandableProperty, value ); }
|
||||
}
|
||||
|
||||
#endregion //IsExpandable
|
||||
|
||||
#region IsSelected
|
||||
|
||||
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register( "IsSelected", typeof( bool ), typeof( PropertyItemBase ), new UIPropertyMetadata( false, OnIsSelectedChanged ) );
|
||||
public bool IsSelected
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( bool )GetValue( IsSelectedProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( IsSelectedProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIsSelectedChanged( DependencyObject o, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
PropertyItemBase propertyItem = o as PropertyItemBase;
|
||||
if( propertyItem != null )
|
||||
propertyItem.OnIsSelectedChanged( ( bool )e.OldValue, ( bool )e.NewValue );
|
||||
}
|
||||
|
||||
protected virtual void OnIsSelectedChanged( bool oldValue, bool newValue )
|
||||
{
|
||||
this.RaiseItemSelectionChangedEvent();
|
||||
}
|
||||
|
||||
#endregion //IsSelected
|
||||
|
||||
#region ParentElement
|
||||
/// <summary>
|
||||
/// Gets the parent property grid element of this property.
|
||||
/// A PropertyItemBase instance if this is a sub-element,
|
||||
/// or the PropertyGrid itself if this is a first-level property.
|
||||
/// </summary>
|
||||
public FrameworkElement ParentElement
|
||||
{
|
||||
get { return this.ParentNode as FrameworkElement; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ParentNode
|
||||
|
||||
internal IPropertyContainer ParentNode
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parentNode;
|
||||
}
|
||||
set
|
||||
{
|
||||
_parentNode = value;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ValueContainer
|
||||
|
||||
internal ContentControl ValueContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
return _valueContainer;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Level
|
||||
|
||||
public int Level
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
#endregion //Level
|
||||
|
||||
#region Properties
|
||||
|
||||
public IList Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
return _containerHelper.Properties;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region PropertyContainerStyle
|
||||
/// <summary>
|
||||
/// Get the PropertyContainerStyle for sub items of this property.
|
||||
/// It return the value defined on PropertyGrid.PropertyContainerStyle.
|
||||
/// </summary>
|
||||
public Style PropertyContainerStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( ParentNode != null )
|
||||
? ParentNode.PropertyContainerStyle
|
||||
: null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ContainerHelper
|
||||
|
||||
internal ContainerHelperBase ContainerHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
return _containerHelper;
|
||||
}
|
||||
set
|
||||
{
|
||||
if( value == null )
|
||||
throw new ArgumentNullException( "value" );
|
||||
|
||||
_containerHelper = value;
|
||||
// Properties property relies on the "Properties" property of the helper
|
||||
// class. Raise a property-changed event.
|
||||
this.RaisePropertyChanged( () => this.Properties );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WillRefreshPropertyGrid
|
||||
|
||||
public static readonly DependencyProperty WillRefreshPropertyGridProperty =
|
||||
DependencyProperty.Register( "WillRefreshPropertyGrid", typeof( bool ), typeof( PropertyItemBase ), new UIPropertyMetadata( false ) );
|
||||
|
||||
public bool WillRefreshPropertyGrid
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( bool )GetValue( WillRefreshPropertyGridProperty );
|
||||
}
|
||||
set
|
||||
{
|
||||
SetValue( WillRefreshPropertyGridProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion //WillRefreshPropertyGrid
|
||||
|
||||
#endregion //Properties
|
||||
|
||||
#region Events
|
||||
|
||||
#region ItemSelectionChanged
|
||||
|
||||
internal static readonly RoutedEvent ItemSelectionChangedEvent = EventManager.RegisterRoutedEvent(
|
||||
"ItemSelectionChangedEvent", RoutingStrategy.Bubble, typeof( RoutedEventHandler ), typeof( PropertyItemBase ) );
|
||||
|
||||
private void RaiseItemSelectionChangedEvent()
|
||||
{
|
||||
RaiseEvent( new RoutedEventArgs( PropertyItemBase.ItemSelectionChangedEvent ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PropertyChanged event
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
internal void RaisePropertyChanged<TMember>( Expression<Func<TMember>> propertyExpression )
|
||||
{
|
||||
this.Notify( this.PropertyChanged, propertyExpression );
|
||||
}
|
||||
internal void RaisePropertyChanged( string name )
|
||||
{
|
||||
this.Notify( this.PropertyChanged, name );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion //Events
|
||||
|
||||
#region Constructors
|
||||
|
||||
static PropertyItemBase()
|
||||
{
|
||||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyItemBase ), new FrameworkPropertyMetadata( typeof( PropertyItemBase ) ) );
|
||||
}
|
||||
|
||||
internal PropertyItemBase()
|
||||
{
|
||||
_containerHelper = new ObjectContainerHelper( this, null );
|
||||
this.GotFocus += new RoutedEventHandler( PropertyItemBase_GotFocus );
|
||||
AddHandler( PropertyItemsControl.PreparePropertyItemEvent, new PropertyItemEventHandler( OnPreparePropertyItemInternal ) );
|
||||
AddHandler( PropertyItemsControl.ClearPropertyItemEvent, new PropertyItemEventHandler( OnClearPropertyItemInternal ) );
|
||||
}
|
||||
|
||||
#endregion //Constructors
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void OnPreparePropertyItemInternal( object sender, PropertyItemEventArgs args )
|
||||
{
|
||||
// This is the callback of the PreparePropertyItem comming from the template PropertyItemControl.
|
||||
args.PropertyItem.Level = this.Level + 1;
|
||||
_containerHelper.PrepareChildrenPropertyItem( args.PropertyItem, args.Item );
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnClearPropertyItemInternal( object sender, PropertyItemEventArgs args )
|
||||
{
|
||||
_containerHelper.ClearChildrenPropertyItem( args.PropertyItem, args.Item );
|
||||
// This is the callback of the PreparePropertyItem comming from the template PropertyItemControl.
|
||||
args.PropertyItem.Level = 0;
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
#endregion //Event Handlers
|
||||
|
||||
#region Methods
|
||||
|
||||
protected virtual Type GetPropertyItemType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual string GetPropertyItemName()
|
||||
{
|
||||
return this.DisplayName;
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_containerHelper.ChildrenItemsControl = GetTemplateChild( PropertyGrid.PART_PropertyItemsControl ) as PropertyItemsControl;
|
||||
_valueContainer = GetTemplateChild( PropertyItemBase.PART_ValueContainer ) as ContentControl;
|
||||
}
|
||||
|
||||
protected override void OnMouseDown( MouseButtonEventArgs e )
|
||||
{
|
||||
IsSelected = true;
|
||||
if( !this.IsKeyboardFocusWithin )
|
||||
{
|
||||
this.Focus();
|
||||
}
|
||||
// Handle the event; otherwise, the possible
|
||||
// parent property item will select itself too.
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void PropertyItemBase_GotFocus( object sender, RoutedEventArgs e )
|
||||
{
|
||||
IsSelected = true;
|
||||
// Handle the event; otherwise, the possible
|
||||
// parent property item will select itself too.
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
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 an Attached DP.
|
||||
if( ReflectionHelper.IsPublicInstanceProperty( GetType(), e.Property.Name ) )
|
||||
{
|
||||
this.RaisePropertyChanged( e.Property.Name );
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyDefinitionCollection GetPropertItemPropertyDefinitions()
|
||||
{
|
||||
if( (this.ParentNode != null) && (this.ParentNode.PropertyDefinitions != null) )
|
||||
{
|
||||
var name = this.GetPropertyItemName();
|
||||
foreach( var pd in this.ParentNode.PropertyDefinitions )
|
||||
{
|
||||
if( pd.TargetProperties.Contains( name ) )
|
||||
{
|
||||
// PropertyDefinitions contains a PropertyDefinition for this PropertyItem Name => return its PropertyDefinitions.
|
||||
return pd.PropertyDefinitions;
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = this.GetPropertyItemType();
|
||||
if( type != null )
|
||||
{
|
||||
foreach( var targetProperty in pd.TargetProperties )
|
||||
{
|
||||
var targetPropertyType = targetProperty as Type;
|
||||
// PropertyDefinitions contains a PropertyDefinition for this PropertyItem Type => return its PropertyDefinitions.
|
||||
if( (targetPropertyType != null) && targetPropertyType.IsAssignableFrom( type ) )
|
||||
return pd.PropertyDefinitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion //Methods
|
||||
|
||||
#region IPropertyContainer Members
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Style IPropertyContainer.PropertyContainerStyle
|
||||
{
|
||||
get { return this.PropertyContainerStyle; }
|
||||
}
|
||||
|
||||
EditorDefinitionCollection IPropertyContainer.EditorDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ParentNode != null) ? this.ParentNode.EditorDefinitions : null;
|
||||
}
|
||||
}
|
||||
|
||||
PropertyDefinitionCollection IPropertyContainer.PropertyDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.GetPropertItemPropertyDefinitions();
|
||||
}
|
||||
}
|
||||
|
||||
ContainerHelperBase IPropertyContainer.ContainerHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ContainerHelper;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPropertyContainer.IsCategorized
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isPropertyGridCategorized;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPropertyContainer.IsSortedAlphabetically
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isSortedAlphabetically;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPropertyContainer.AutoGenerateProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
if( this.ParentNode != null )
|
||||
{
|
||||
var propertyItemPropertyDefinitions = this.GetPropertItemPropertyDefinitions();
|
||||
// No PropertyDefinitions specified : show all properties of this PropertyItem.
|
||||
if( (propertyItemPropertyDefinitions == null) || (propertyItemPropertyDefinitions.Count == 0) )
|
||||
return true;
|
||||
|
||||
// A PropertyDefinitions is specified : show only the properties of the PropertyDefinitions from this PropertyItem.
|
||||
return this.ParentNode.AutoGenerateProperties;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool IPropertyContainer.HideInheritedProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FilterInfo IPropertyContainer.FilterInfo
|
||||
{
|
||||
get { return new FilterInfo(); }
|
||||
}
|
||||
|
||||
bool? IPropertyContainer.IsPropertyVisible( PropertyDescriptor pd )
|
||||
{
|
||||
if( _parentNode != null )
|
||||
{
|
||||
return _parentNode.IsPropertyVisible( pd );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Data;
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
#if !VS2008
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
#endif
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class PropertyItemCollection : ReadOnlyObservableCollection<PropertyItem>
|
||||
{
|
||||
internal static readonly string CategoryPropertyName;
|
||||
internal static readonly string CategoryOrderPropertyName;
|
||||
internal static readonly string PropertyOrderPropertyName;
|
||||
internal static readonly string DisplayNamePropertyName;
|
||||
|
||||
private bool _preventNotification;
|
||||
|
||||
static PropertyItemCollection()
|
||||
{
|
||||
PropertyItem p = null;
|
||||
CategoryPropertyName = ReflectionHelper.GetPropertyOrFieldName( () => p.Category );
|
||||
CategoryOrderPropertyName = ReflectionHelper.GetPropertyOrFieldName( () => p.CategoryOrder );
|
||||
PropertyOrderPropertyName = ReflectionHelper.GetPropertyOrFieldName( () => p.PropertyOrder );
|
||||
DisplayNamePropertyName = ReflectionHelper.GetPropertyOrFieldName( () => p.DisplayName );
|
||||
}
|
||||
|
||||
public PropertyItemCollection(ObservableCollection<PropertyItem> editableCollection)
|
||||
:base(editableCollection)
|
||||
{
|
||||
EditableCollection = editableCollection;
|
||||
}
|
||||
|
||||
internal Predicate<object> FilterPredicate
|
||||
{
|
||||
get { return GetDefaultView().Filter; }
|
||||
set { GetDefaultView().Filter = value; }
|
||||
}
|
||||
|
||||
public ObservableCollection<PropertyItem> EditableCollection { get; private set; }
|
||||
|
||||
private ICollectionView GetDefaultView()
|
||||
{
|
||||
return CollectionViewSource.GetDefaultView( this );
|
||||
}
|
||||
|
||||
public void GroupBy( string name )
|
||||
{
|
||||
GetDefaultView().GroupDescriptions.Add( new PropertyGroupDescription( name ) );
|
||||
}
|
||||
|
||||
public void SortBy( string name, ListSortDirection sortDirection )
|
||||
{
|
||||
GetDefaultView().SortDescriptions.Add( new SortDescription( name, sortDirection ) );
|
||||
}
|
||||
|
||||
public void Filter( string text )
|
||||
{
|
||||
Predicate<object> filter = PropertyItemCollection.CreateFilter( text );
|
||||
GetDefaultView().Filter = filter;
|
||||
}
|
||||
|
||||
protected override void OnCollectionChanged( NotifyCollectionChangedEventArgs args )
|
||||
{
|
||||
if( _preventNotification )
|
||||
return;
|
||||
|
||||
base.OnCollectionChanged( args );
|
||||
}
|
||||
|
||||
internal void UpdateItems( IEnumerable<PropertyItem> newItems )
|
||||
{
|
||||
if( newItems == null )
|
||||
throw new ArgumentNullException( "newItems" );
|
||||
|
||||
_preventNotification = true;
|
||||
using( GetDefaultView().DeferRefresh() )
|
||||
{
|
||||
EditableCollection.Clear();
|
||||
foreach( var item in newItems )
|
||||
{
|
||||
this.EditableCollection.Add( item );
|
||||
}
|
||||
}
|
||||
_preventNotification = false;
|
||||
OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) );
|
||||
}
|
||||
|
||||
internal void UpdateCategorization( GroupDescription groupDescription, bool isPropertyGridCategorized, bool sortAlphabetically )
|
||||
{
|
||||
// Compute Display Order relative to PropertyOrderAttributes on PropertyItem
|
||||
// which could be different in Alphabetical or Categorized mode.
|
||||
foreach( PropertyItem item in this.Items )
|
||||
{
|
||||
item.DescriptorDefinition.DisplayOrder = item.DescriptorDefinition.ComputeDisplayOrderInternal( isPropertyGridCategorized );
|
||||
item.PropertyOrder = item.DescriptorDefinition.DisplayOrder;
|
||||
}
|
||||
|
||||
// Clear view values
|
||||
ICollectionView view = this.GetDefaultView();
|
||||
using( view.DeferRefresh() )
|
||||
{
|
||||
view.GroupDescriptions.Clear();
|
||||
view.SortDescriptions.Clear();
|
||||
|
||||
// Update view values
|
||||
if( groupDescription != null )
|
||||
{
|
||||
view.GroupDescriptions.Add( groupDescription );
|
||||
if( sortAlphabetically )
|
||||
{
|
||||
SortBy( CategoryOrderPropertyName, ListSortDirection.Ascending );
|
||||
SortBy( CategoryPropertyName, ListSortDirection.Ascending );
|
||||
}
|
||||
}
|
||||
|
||||
if( sortAlphabetically )
|
||||
{
|
||||
SortBy( PropertyOrderPropertyName, ListSortDirection.Ascending );
|
||||
SortBy( DisplayNamePropertyName, ListSortDirection.Ascending );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void RefreshView()
|
||||
{
|
||||
GetDefaultView().Refresh();
|
||||
}
|
||||
|
||||
internal static Predicate<object> CreateFilter( string text )
|
||||
{
|
||||
Predicate<object> filter = null;
|
||||
|
||||
if( !string.IsNullOrEmpty( text ) )
|
||||
{
|
||||
filter = ( item ) =>
|
||||
{
|
||||
var property = item as PropertyItem;
|
||||
if( property.DisplayName != null )
|
||||
{
|
||||
#if !VS2008
|
||||
var displayAttribute = PropertyGridUtilities.GetAttribute<DisplayAttribute>( property.PropertyDescriptor );
|
||||
if( displayAttribute != null )
|
||||
{
|
||||
var canBeFiltered = displayAttribute.GetAutoGenerateFilter();
|
||||
if( canBeFiltered.HasValue && !canBeFiltered.Value )
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return property.DisplayName.ToLower().Contains( text.ToLower() );
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// This Control is intended to be used in the template of the
|
||||
/// PropertyItemBase and PropertyGrid classes to contain the
|
||||
/// sub-children properties.
|
||||
/// </summary>
|
||||
public class PropertyItemsControl : ItemsControl
|
||||
{
|
||||
|
||||
#region PreparePropertyItemEvent Attached Routed Event
|
||||
|
||||
internal static readonly RoutedEvent PreparePropertyItemEvent = EventManager.RegisterRoutedEvent( "PreparePropertyItem", RoutingStrategy.Bubble, typeof( PropertyItemEventHandler ), typeof( PropertyItemsControl ) );
|
||||
internal event PropertyItemEventHandler PreparePropertyItem
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler( PropertyItemsControl.PreparePropertyItemEvent, value );
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler( PropertyItemsControl.PreparePropertyItemEvent, value );
|
||||
}
|
||||
}
|
||||
|
||||
private void RaisePreparePropertyItemEvent( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
this.RaiseEvent( new PropertyItemEventArgs( PropertyItemsControl.PreparePropertyItemEvent, this, propertyItem, item ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ClearPropertyItemEvent Attached Routed Event
|
||||
|
||||
internal static readonly RoutedEvent ClearPropertyItemEvent = EventManager.RegisterRoutedEvent( "ClearPropertyItem", RoutingStrategy.Bubble, typeof( PropertyItemEventHandler ), typeof( PropertyItemsControl ) );
|
||||
internal event PropertyItemEventHandler ClearPropertyItem
|
||||
{
|
||||
add
|
||||
{
|
||||
AddHandler( PropertyItemsControl.ClearPropertyItemEvent, value );
|
||||
}
|
||||
remove
|
||||
{
|
||||
RemoveHandler( PropertyItemsControl.ClearPropertyItemEvent, value );
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseClearPropertyItemEvent( PropertyItemBase propertyItem, object item )
|
||||
{
|
||||
this.RaiseEvent( new PropertyItemEventArgs( PropertyItemsControl.ClearPropertyItemEvent, this, propertyItem, item ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride( object item )
|
||||
{
|
||||
return ( item is PropertyItemBase );
|
||||
}
|
||||
|
||||
|
||||
protected override void PrepareContainerForItemOverride( DependencyObject element, object item )
|
||||
{
|
||||
base.PrepareContainerForItemOverride( element, item );
|
||||
this.RaisePreparePropertyItemEvent( ( PropertyItemBase )element, item );
|
||||
}
|
||||
|
||||
protected override void ClearContainerForItemOverride( DependencyObject element, object item )
|
||||
{
|
||||
this.RaiseClearPropertyItemEvent( ( PropertyItemBase )element, item );
|
||||
base.ClearContainerForItemOverride( element, item );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public static class StringConstants
|
||||
{
|
||||
public static string Local
|
||||
{
|
||||
get { return "Local"; }
|
||||
}
|
||||
|
||||
public static string Resource
|
||||
{
|
||||
get { return "Resource"; }
|
||||
}
|
||||
|
||||
public static string Databinding
|
||||
{
|
||||
get { return "Databinding"; }
|
||||
}
|
||||
|
||||
public static string Inheritance
|
||||
{
|
||||
get { return "Inheritance"; }
|
||||
}
|
||||
|
||||
public static string StyleSetter
|
||||
{
|
||||
get { return "Style Setter"; }
|
||||
}
|
||||
|
||||
public static string AdvancedProperties
|
||||
{
|
||||
get { return "Advanced Properties"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using Xceed.Wpf.Toolkit.Core.Utilities;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is intended to provide the "Type" target
|
||||
/// for property definitions or editor definitions when
|
||||
/// using Property Element Syntax.
|
||||
/// </summary>
|
||||
public sealed class TargetPropertyType
|
||||
{
|
||||
private Type _type;
|
||||
private bool _sealed;
|
||||
|
||||
public Type Type
|
||||
{
|
||||
get { return _type; }
|
||||
set
|
||||
{
|
||||
if( _sealed )
|
||||
throw new InvalidOperationException(
|
||||
string.Format(
|
||||
"{0}.Type property cannot be modified once the instance is used",
|
||||
typeof( TargetPropertyType ) ) );
|
||||
|
||||
_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Seal()
|
||||
{
|
||||
if( _type == null )
|
||||
throw new InvalidOperationException(
|
||||
string.Format( "{0}.Type property must be initialized", typeof( TargetPropertyType ) ) );
|
||||
|
||||
_sealed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*************************************************************************************
|
||||
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Xceed.Wpf.Toolkit.PropertyGrid
|
||||
{
|
||||
public class TrimmedTextBlock : TextBlock
|
||||
{
|
||||
#region Constructor
|
||||
|
||||
public TrimmedTextBlock()
|
||||
{
|
||||
this.SizeChanged += this.TrimmedTextBlock_SizeChanged;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IsTextTrimmed Property
|
||||
|
||||
public static readonly DependencyProperty IsTextTrimmedProperty = DependencyProperty.Register( "IsTextTrimmed", typeof( bool ), typeof( TrimmedTextBlock ), new PropertyMetadata( false, OnIsTextTrimmedChanged ) );
|
||||
public bool IsTextTrimmed
|
||||
{
|
||||
get
|
||||
{
|
||||
return ( bool )GetValue( IsTextTrimmedProperty );
|
||||
}
|
||||
private set
|
||||
{
|
||||
SetValue( IsTextTrimmedProperty, value );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnIsTextTrimmedChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
|
||||
{
|
||||
var textBlock = d as TrimmedTextBlock;
|
||||
if( textBlock != null )
|
||||
{
|
||||
textBlock.OnIsTextTrimmedChanged( ( bool )e.OldValue, ( bool )e.NewValue );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnIsTextTrimmedChanged( bool oldValue, bool newValue )
|
||||
{
|
||||
this.ToolTip = ( newValue ) ? this.Text : null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handler
|
||||
|
||||
private void TrimmedTextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
var textBlock = sender as TextBlock;
|
||||
if( textBlock != null )
|
||||
{
|
||||
this.IsTextTrimmed = this.GetIsTextTrimmed( textBlock );
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private bool GetIsTextTrimmed( TextBlock textBlock )
|
||||
{
|
||||
if( textBlock == null )
|
||||
return false;
|
||||
if( textBlock.TextTrimming == TextTrimming.None )
|
||||
return false;
|
||||
if( textBlock.TextWrapping != TextWrapping.NoWrap )
|
||||
return false;
|
||||
|
||||
var textBlockActualWidth = textBlock.ActualWidth;
|
||||
textBlock.Measure( new Size( double.MaxValue, double.MaxValue ) );
|
||||
var textBlockDesiredWidth = textBlock.DesiredSize.Width;
|
||||
|
||||
return ( textBlockActualWidth < textBlockDesiredWidth );
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user