|
Before Width: | Height: | Size: 682 B |
|
Before Width: | Height: | Size: 262 B |
|
Before Width: | Height: | Size: 822 B |
@ -1,712 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Input; |
|||
using Xceed.Wpf.Toolkit.Core.Utilities; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid; |
|||
using System.Windows.Threading; |
|||
using System.Reflection; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
[TemplatePart( Name = PART_NewItemTypesComboBox, Type = typeof( ComboBox ) )] |
|||
[TemplatePart( Name = PART_PropertyGrid, Type = typeof( PropertyGrid.PropertyGrid ) )] |
|||
[TemplatePart( Name = PART_ListBox, Type = typeof( ListBox ) )] |
|||
public class CollectionControl : Control |
|||
{ |
|||
private const string PART_NewItemTypesComboBox = "PART_NewItemTypesComboBox"; |
|||
private const string PART_PropertyGrid = "PART_PropertyGrid"; |
|||
private const string PART_ListBox = "PART_ListBox"; |
|||
|
|||
#region Private Members
|
|||
|
|||
private ComboBox _newItemTypesComboBox; |
|||
private PropertyGrid.PropertyGrid _propertyGrid; |
|||
private ListBox _listBox; |
|||
private bool _isCollectionUpdated; |
|||
|
|||
#endregion
|
|||
|
|||
#region Properties
|
|||
|
|||
#region IsReadOnly Property
|
|||
|
|||
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( CollectionControl ), new UIPropertyMetadata( false ) ); |
|||
public bool IsReadOnly |
|||
{ |
|||
get |
|||
{ |
|||
return ( bool )GetValue( IsReadOnlyProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( IsReadOnlyProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //Items
|
|||
|
|||
#region Items Property
|
|||
|
|||
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register( "Items", typeof( ObservableCollection<object> ), typeof( CollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public ObservableCollection<object> Items |
|||
{ |
|||
get |
|||
{ |
|||
return ( ObservableCollection<object> )GetValue( ItemsProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //Items
|
|||
|
|||
#region ItemsSource Property
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof( IEnumerable ), typeof( CollectionControl ), new UIPropertyMetadata( null, OnItemsSourceChanged ) ); |
|||
public IEnumerable ItemsSource |
|||
{ |
|||
get |
|||
{ |
|||
return (IEnumerable)GetValue( ItemsSourceProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceProperty, value ); |
|||
} |
|||
} |
|||
|
|||
private static void OnItemsSourceChanged( DependencyObject d, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
var CollectionControl = ( CollectionControl )d; |
|||
if( CollectionControl != null ) |
|||
CollectionControl.OnItemSourceChanged( (IEnumerable)e.OldValue, (IEnumerable)e.NewValue ); |
|||
} |
|||
|
|||
public void OnItemSourceChanged( IEnumerable oldValue, IEnumerable newValue ) |
|||
{ |
|||
if( newValue != null ) |
|||
{ |
|||
var dict = newValue as IDictionary; |
|||
if( dict != null ) |
|||
{ |
|||
// A Dictionary contains KeyValuePair that can't be edited.
|
|||
// We need to Add EditableKeyValuePairs from DictionaryEntries.
|
|||
foreach( DictionaryEntry item in dict ) |
|||
{ |
|||
var keyType = (item.Key != null) |
|||
? item.Key.GetType() |
|||
: (dict.GetType().GetGenericArguments().Count() > 0) ? dict.GetType().GetGenericArguments()[0] : typeof( object ); |
|||
var valueType = (item.Value != null) |
|||
? item.Value.GetType() |
|||
: (dict.GetType().GetGenericArguments().Count() > 1) ? dict.GetType().GetGenericArguments()[ 1 ] : typeof( object ); |
|||
var editableKeyValuePair = ListUtilities.CreateEditableKeyValuePair( item.Key |
|||
, keyType |
|||
, item.Value |
|||
, valueType ); |
|||
this.Items.Add( editableKeyValuePair ); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
foreach( var item in newValue ) |
|||
{ |
|||
if( item != null ) |
|||
{ |
|||
Items.Add( item ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemsSource
|
|||
|
|||
#region ItemsSourceType Property
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register( "ItemsSourceType", typeof( Type ), typeof( CollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public Type ItemsSourceType |
|||
{ |
|||
get |
|||
{ |
|||
return ( Type )GetValue( ItemsSourceTypeProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceTypeProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemsSourceType
|
|||
|
|||
#region NewItemType Property
|
|||
|
|||
public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register( "NewItemTypes", typeof( IList ), typeof( CollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public IList<Type> NewItemTypes |
|||
{ |
|||
get |
|||
{ |
|||
return ( IList<Type> )GetValue( NewItemTypesProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( NewItemTypesProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //NewItemType
|
|||
|
|||
#region PropertiesLabel Property
|
|||
|
|||
public static readonly DependencyProperty PropertiesLabelProperty = DependencyProperty.Register( "PropertiesLabel", typeof( object ), typeof( CollectionControl ), new UIPropertyMetadata( "Properties:" ) ); |
|||
public object PropertiesLabel |
|||
{ |
|||
get |
|||
{ |
|||
return ( object )GetValue( PropertiesLabelProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( PropertiesLabelProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //PropertiesLabel
|
|||
|
|||
#region SelectedItem Property
|
|||
|
|||
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem", typeof( object ), typeof( CollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public object SelectedItem |
|||
{ |
|||
get |
|||
{ |
|||
return ( object )GetValue( SelectedItemProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( SelectedItemProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //EditorDefinitions
|
|||
|
|||
#region TypeSelectionLabel Property
|
|||
|
|||
public static readonly DependencyProperty TypeSelectionLabelProperty = DependencyProperty.Register( "TypeSelectionLabel", typeof( object ), typeof( CollectionControl ), new UIPropertyMetadata( "Select type:" ) ); |
|||
public object TypeSelectionLabel |
|||
{ |
|||
get |
|||
{ |
|||
return ( object )GetValue( TypeSelectionLabelProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( TypeSelectionLabelProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //TypeSelectionLabel
|
|||
|
|||
#region EditorDefinitions Property
|
|||
|
|||
public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register( "EditorDefinitions", typeof( EditorDefinitionCollection ), typeof( CollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public EditorDefinitionCollection EditorDefinitions |
|||
{ |
|||
get |
|||
{ |
|||
return ( EditorDefinitionCollection )GetValue( EditorDefinitionsProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( EditorDefinitionsProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //EditorDefinitions
|
|||
|
|||
#endregion //Properties
|
|||
|
|||
#region Override Methods
|
|||
|
|||
public override void OnApplyTemplate() |
|||
{ |
|||
base.OnApplyTemplate(); |
|||
|
|||
if( _newItemTypesComboBox != null ) |
|||
{ |
|||
_newItemTypesComboBox.Loaded -= new RoutedEventHandler( this.NewItemTypesComboBox_Loaded ); |
|||
} |
|||
_newItemTypesComboBox = GetTemplateChild( PART_NewItemTypesComboBox ) as ComboBox; |
|||
if( _newItemTypesComboBox != null ) |
|||
{ |
|||
_newItemTypesComboBox.Loaded += new RoutedEventHandler( this.NewItemTypesComboBox_Loaded ); |
|||
} |
|||
|
|||
_listBox = this.GetTemplateChild( PART_ListBox ) as ListBox; |
|||
|
|||
if( _propertyGrid != null ) |
|||
{ |
|||
_propertyGrid.PropertyValueChanged -= this.PropertyGrid_PropertyValueChanged; |
|||
} |
|||
_propertyGrid = GetTemplateChild( PART_PropertyGrid ) as PropertyGrid.PropertyGrid; |
|||
if( _propertyGrid != null ) |
|||
{ |
|||
_propertyGrid.PropertyValueChanged += this.PropertyGrid_PropertyValueChanged; |
|||
} |
|||
} |
|||
|
|||
public PropertyGrid.PropertyGrid PropertyGrid |
|||
{ |
|||
get |
|||
{ |
|||
if( _propertyGrid == null ) |
|||
{ |
|||
this.ApplyTemplate(); |
|||
} |
|||
return _propertyGrid; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region Constructors
|
|||
|
|||
static CollectionControl() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( CollectionControl ), new FrameworkPropertyMetadata( typeof( CollectionControl ) ) ); |
|||
} |
|||
|
|||
public CollectionControl() |
|||
{ |
|||
Items = new ObservableCollection<object>(); |
|||
CommandBindings.Add( new CommandBinding( ApplicationCommands.New, this.AddNew, this.CanAddNew ) ); |
|||
CommandBindings.Add( new CommandBinding( ApplicationCommands.Delete, this.Delete, this.CanDelete ) ); |
|||
CommandBindings.Add( new CommandBinding( ApplicationCommands.Copy, this.Duplicate, this.CanDuplicate ) ); |
|||
CommandBindings.Add( new CommandBinding( ComponentCommands.MoveDown, this.MoveDown, this.CanMoveDown ) ); |
|||
CommandBindings.Add( new CommandBinding( ComponentCommands.MoveUp, this.MoveUp, this.CanMoveUp ) ); |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Events
|
|||
|
|||
#region ItemDeleting Event
|
|||
|
|||
public delegate void ItemDeletingRoutedEventHandler( object sender, ItemDeletingEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemDeletingEvent = EventManager.RegisterRoutedEvent( "ItemDeleting", RoutingStrategy.Bubble, typeof( ItemDeletingRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemDeletingRoutedEventHandler ItemDeleting |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemDeletingEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemDeletingEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemDeleting Event
|
|||
|
|||
#region ItemDeleted Event
|
|||
|
|||
public delegate void ItemDeletedRoutedEventHandler( object sender, ItemEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemDeletedEvent = EventManager.RegisterRoutedEvent( "ItemDeleted", RoutingStrategy.Bubble, typeof( ItemDeletedRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemDeletedRoutedEventHandler ItemDeleted |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemDeletedEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemDeletedEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemDeleted Event
|
|||
|
|||
#region ItemAdding Event
|
|||
|
|||
public delegate void ItemAddingRoutedEventHandler( object sender, ItemAddingEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemAddingEvent = EventManager.RegisterRoutedEvent( "ItemAdding", RoutingStrategy.Bubble, typeof( ItemAddingRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemAddingRoutedEventHandler ItemAdding |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemAddingEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemAddingEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemAdding Event
|
|||
|
|||
#region ItemAdded Event
|
|||
|
|||
public delegate void ItemAddedRoutedEventHandler( object sender, ItemEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemAddedEvent = EventManager.RegisterRoutedEvent( "ItemAdded", RoutingStrategy.Bubble, typeof( ItemAddedRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemAddedRoutedEventHandler ItemAdded |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemAddedEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemAddedEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemAdded Event
|
|||
|
|||
#region ItemMovedDown Event
|
|||
|
|||
public delegate void ItemMovedDownRoutedEventHandler( object sender, ItemEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemMovedDownEvent = EventManager.RegisterRoutedEvent( "ItemMovedDown", RoutingStrategy.Bubble, typeof( ItemMovedDownRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemMovedDownRoutedEventHandler ItemMovedDown |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemMovedDownEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemMovedDownEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemMovedDown Event
|
|||
|
|||
#region ItemMovedUp Event
|
|||
|
|||
public delegate void ItemMovedUpRoutedEventHandler( object sender, ItemEventArgs e ); |
|||
|
|||
public static readonly RoutedEvent ItemMovedUpEvent = EventManager.RegisterRoutedEvent( "ItemMovedUp", RoutingStrategy.Bubble, typeof( ItemMovedUpRoutedEventHandler ), typeof( CollectionControl ) ); |
|||
public event ItemMovedUpRoutedEventHandler ItemMovedUp |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( ItemMovedUpEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( ItemMovedUpEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemMovedUp Event
|
|||
|
|||
#endregion
|
|||
|
|||
#region EventHandlers
|
|||
|
|||
void NewItemTypesComboBox_Loaded( object sender, RoutedEventArgs e ) |
|||
{ |
|||
if( _newItemTypesComboBox != null ) |
|||
_newItemTypesComboBox.SelectedIndex = 0; |
|||
} |
|||
|
|||
private void PropertyGrid_PropertyValueChanged( object sender, PropertyGrid.PropertyValueChangedEventArgs e ) |
|||
{ |
|||
if( _listBox != null ) |
|||
{ |
|||
_isCollectionUpdated = true; |
|||
_listBox.Dispatcher.BeginInvoke( DispatcherPriority.Input, new Action( () => |
|||
{ |
|||
_listBox.Items.Refresh(); |
|||
} |
|||
) ); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Commands
|
|||
|
|||
private void AddNew( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var newItem = this.CreateNewItem( ( Type )e.Parameter ); |
|||
|
|||
this.AddNewCore( newItem ); |
|||
} |
|||
|
|||
private void CanAddNew( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
var t = e.Parameter as Type; |
|||
this.CanAddNewCore( t, e ); |
|||
} |
|||
|
|||
private void CanAddNewCore( Type t, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
if( ( t != null ) && !this.IsReadOnly ) |
|||
{ |
|||
var isComplexStruct = t.IsValueType && !t.IsEnum && !t.IsPrimitive; |
|||
|
|||
if( isComplexStruct || ( t.GetConstructor( Type.EmptyTypes ) != null ) ) |
|||
{ |
|||
e.CanExecute = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void AddNewCore( object newItem ) |
|||
{ |
|||
if( newItem == null ) |
|||
throw new ArgumentNullException( "newItem" ); |
|||
|
|||
var eventArgs = new ItemAddingEventArgs( ItemAddingEvent, newItem ); |
|||
this.RaiseEvent( eventArgs ); |
|||
if( eventArgs.Cancel ) |
|||
return; |
|||
newItem = eventArgs.Item; |
|||
|
|||
this.Items.Add( newItem ); |
|||
|
|||
this.RaiseEvent( new ItemEventArgs( ItemAddedEvent, newItem ) ); |
|||
_isCollectionUpdated = true; |
|||
|
|||
this.SelectedItem = newItem; |
|||
} |
|||
|
|||
private void Delete( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var eventArgs = new ItemDeletingEventArgs( ItemDeletingEvent, e.Parameter ); |
|||
this.RaiseEvent( eventArgs ); |
|||
if( eventArgs.Cancel ) |
|||
return; |
|||
|
|||
this.Items.Remove( e.Parameter ); |
|||
|
|||
this.RaiseEvent( new ItemEventArgs( ItemDeletedEvent, e.Parameter ) ); |
|||
_isCollectionUpdated = true; |
|||
} |
|||
|
|||
private void CanDelete( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
e.CanExecute = e.Parameter != null && !this.IsReadOnly; |
|||
} |
|||
|
|||
private void Duplicate( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var newItem = this.DuplicateItem( e ); |
|||
this.AddNewCore( newItem ); |
|||
} |
|||
|
|||
private void CanDuplicate( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
var t = (e.Parameter != null) ? e.Parameter.GetType() : null; |
|||
this.CanAddNewCore( t, e ); |
|||
} |
|||
|
|||
private object DuplicateItem( ExecutedRoutedEventArgs e ) |
|||
{ |
|||
if( e == null ) |
|||
throw new ArgumentNullException( "e" ); |
|||
|
|||
var baseItem = e.Parameter; |
|||
var newItemType = baseItem.GetType(); |
|||
var newItem = this.CreateNewItem( newItemType ); |
|||
|
|||
var type = newItemType; |
|||
while( type != null ) |
|||
{ |
|||
var baseProperties = type.GetFields( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance ); |
|||
foreach( var prop in baseProperties ) |
|||
{ |
|||
prop.SetValue( newItem, prop.GetValue( baseItem ) ); |
|||
} |
|||
type = type.BaseType; |
|||
} |
|||
|
|||
return newItem; |
|||
} |
|||
|
|||
private void MoveDown( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var selectedItem = e.Parameter; |
|||
var index = Items.IndexOf( selectedItem ); |
|||
Items.RemoveAt( index ); |
|||
Items.Insert( ++index, selectedItem ); |
|||
|
|||
this.RaiseEvent( new ItemEventArgs( ItemMovedDownEvent, selectedItem ) ); |
|||
_isCollectionUpdated = true; |
|||
|
|||
this.SelectedItem = selectedItem; |
|||
} |
|||
|
|||
private void CanMoveDown( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
if( e.Parameter != null && Items.IndexOf( e.Parameter ) < ( Items.Count - 1 ) && !this.IsReadOnly ) |
|||
e.CanExecute = true; |
|||
} |
|||
|
|||
private void MoveUp( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var selectedItem = e.Parameter; |
|||
var index = Items.IndexOf( selectedItem ); |
|||
this.Items.RemoveAt( index ); |
|||
this.Items.Insert( --index, selectedItem ); |
|||
|
|||
this.RaiseEvent( new ItemEventArgs( ItemMovedUpEvent, selectedItem ) ); |
|||
_isCollectionUpdated = true; |
|||
|
|||
this.SelectedItem = selectedItem; |
|||
} |
|||
|
|||
private void CanMoveUp( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
if( e.Parameter != null && Items.IndexOf( e.Parameter ) > 0 && !this.IsReadOnly ) |
|||
e.CanExecute = true; |
|||
} |
|||
|
|||
#endregion //Commands
|
|||
|
|||
#region Methods
|
|||
|
|||
public bool PersistChanges() |
|||
{ |
|||
this.PersistChanges( this.Items ); |
|||
return _isCollectionUpdated; |
|||
} |
|||
|
|||
internal void PersistChanges( IList sourceList ) |
|||
{ |
|||
var collection = ComputeItemsSource(); |
|||
if( collection == null ) |
|||
return; |
|||
|
|||
//IDictionary<T> and IDictionary
|
|||
if( collection is IDictionary ) |
|||
{ |
|||
//For a Dictionary, we need to parse the list of EditableKeyValuePair and add KeyValuePair to the Dictionary.
|
|||
var dict = (IDictionary)collection; |
|||
//the easiest way to persist changes to the source is to just clear the source list and then add all items to it.
|
|||
dict.Clear(); |
|||
|
|||
foreach( var item in sourceList ) |
|||
{ |
|||
var propInfoKey = item.GetType().GetProperty( "Key" ); |
|||
var propInfoValue = item.GetType().GetProperty( "Value" ); |
|||
if( (propInfoKey != null) && (propInfoValue != null) ) |
|||
{ |
|||
dict.Add( propInfoKey.GetValue( item, null ), propInfoValue.GetValue( item, null ) ); |
|||
} |
|||
} |
|||
} |
|||
//IList
|
|||
else if( collection is IList ) |
|||
{ |
|||
var list = (IList)collection; |
|||
|
|||
//the easiest way to persist changes to the source is to just clear the source list and then add all items to it.
|
|||
list.Clear(); |
|||
|
|||
if( list.IsFixedSize ) |
|||
{ |
|||
if( sourceList.Count > list.Count ) |
|||
throw new IndexOutOfRangeException("Exceeding array size."); |
|||
|
|||
for( int i = 0; i < sourceList.Count; ++i ) |
|||
list[ i ] = sourceList[ i ]; |
|||
} |
|||
else |
|||
{ |
|||
foreach( var item in sourceList ) |
|||
{ |
|||
list.Add( item ); |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
//ICollection<T> (or IList<T>)
|
|||
var collectionType = collection.GetType(); |
|||
var iCollectionOfTInterface = collectionType.GetInterfaces().FirstOrDefault( x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof( ICollection<> )) ); |
|||
if( iCollectionOfTInterface != null ) |
|||
{ |
|||
var argumentType = iCollectionOfTInterface.GetGenericArguments().FirstOrDefault(); |
|||
if( argumentType != null ) |
|||
{ |
|||
var iCollectionOfTType = typeof( ICollection<> ).MakeGenericType( argumentType ); |
|||
|
|||
//the easiest way to persist changes to the source is to just clear the source list and then add all items to it.
|
|||
iCollectionOfTType.GetMethod( "Clear" ).Invoke( collection, null ); |
|||
|
|||
foreach( var item in sourceList ) |
|||
{ |
|||
iCollectionOfTType.GetMethod( "Add" ).Invoke( collection, new object[] { item } ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private IEnumerable CreateItemsSource() |
|||
{ |
|||
IEnumerable collection = null; |
|||
|
|||
if( ItemsSourceType != null ) |
|||
{ |
|||
var constructor = ItemsSourceType.GetConstructor( Type.EmptyTypes ); |
|||
if( constructor != null ) |
|||
{ |
|||
collection = ( IEnumerable )constructor.Invoke( null ); |
|||
} |
|||
else if( ItemsSourceType.IsArray ) |
|||
{ |
|||
collection = Array.CreateInstance( ItemsSourceType.GetElementType(), Items.Count ); |
|||
} |
|||
} |
|||
|
|||
return collection; |
|||
} |
|||
|
|||
private object CreateNewItem( Type type ) |
|||
{ |
|||
return Activator.CreateInstance( type ); |
|||
} |
|||
|
|||
private IEnumerable ComputeItemsSource() |
|||
{ |
|||
if( ItemsSource == null ) |
|||
ItemsSource = CreateItemsSource(); |
|||
|
|||
return ItemsSource; |
|||
} |
|||
|
|||
#endregion //Methods
|
|||
} |
|||
} |
|||
|
Before Width: | Height: | Size: 822 B |
@ -1,178 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
using System.Windows.Data; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public class CollectionControlButton : Button |
|||
{ |
|||
#region Constructors
|
|||
|
|||
static CollectionControlButton() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( CollectionControlButton ), new FrameworkPropertyMetadata( typeof( CollectionControlButton ) ) ); |
|||
} |
|||
|
|||
public CollectionControlButton() |
|||
{ |
|||
this.Click += this.CollectionControlButton_Click; |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Properties
|
|||
|
|||
#region EditorDefinitions Property
|
|||
|
|||
public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register( "EditorDefinitions", typeof( EditorDefinitionCollection ), typeof( CollectionControlButton ), new UIPropertyMetadata( null ) ); |
|||
public EditorDefinitionCollection EditorDefinitions |
|||
{ |
|||
get |
|||
{ |
|||
return ( EditorDefinitionCollection )GetValue( EditorDefinitionsProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( EditorDefinitionsProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //EditorDefinitions
|
|||
|
|||
#region IsReadOnly Property
|
|||
|
|||
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( CollectionControlButton ), new UIPropertyMetadata( false ) ); |
|||
public bool IsReadOnly |
|||
{ |
|||
get |
|||
{ |
|||
return ( bool )GetValue( IsReadOnlyProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( IsReadOnlyProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //IsReadOnly
|
|||
|
|||
#region ItemsSource Property
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof( IEnumerable ), typeof( CollectionControlButton ), new UIPropertyMetadata( null ) ); |
|||
public IEnumerable ItemsSource |
|||
{ |
|||
get |
|||
{ |
|||
return ( IEnumerable )GetValue( ItemsSourceProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemsSource
|
|||
|
|||
#region ItemsSourceType Property
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register( "ItemsSourceType", typeof( Type ), typeof( CollectionControlButton ), new UIPropertyMetadata( null ) ); |
|||
public Type ItemsSourceType |
|||
{ |
|||
get |
|||
{ |
|||
return ( Type )GetValue( ItemsSourceTypeProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceTypeProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //ItemsSourceType
|
|||
|
|||
#region NewItemTypes Property
|
|||
|
|||
public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register( "NewItemTypes", typeof( IList ), typeof( CollectionControlButton ), new UIPropertyMetadata( null ) ); |
|||
public IList<Type> NewItemTypes |
|||
{ |
|||
get |
|||
{ |
|||
return ( IList<Type> )GetValue( NewItemTypesProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( NewItemTypesProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //NewItemTypes
|
|||
|
|||
#endregion
|
|||
|
|||
#region Base Class Overrides
|
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region Methods
|
|||
|
|||
private void CollectionControlButton_Click( object sender, RoutedEventArgs e ) |
|||
{ |
|||
var collectionControlDialog = new CollectionControlDialog(); |
|||
var binding = new Binding( "ItemsSource" ) { Source = this, Mode = BindingMode.TwoWay }; |
|||
BindingOperations.SetBinding( collectionControlDialog, CollectionControlDialog.ItemsSourceProperty, binding ); |
|||
collectionControlDialog.NewItemTypes = this.NewItemTypes; |
|||
collectionControlDialog.ItemsSourceType = this.ItemsSourceType; |
|||
collectionControlDialog.IsReadOnly = this.IsReadOnly; |
|||
collectionControlDialog.EditorDefinitions = this.EditorDefinitions; |
|||
var collectionUpdated = collectionControlDialog.ShowDialog(); |
|||
if( collectionUpdated.HasValue && collectionUpdated.Value ) |
|||
{ |
|||
this.RaiseEvent( new RoutedEventArgs( CollectionControlButton.CollectionUpdatedEvent, this ) ); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Events
|
|||
|
|||
#region CollectionUpdated Event
|
|||
|
|||
public static readonly RoutedEvent CollectionUpdatedEvent = EventManager.RegisterRoutedEvent( "CollectionUpdated", RoutingStrategy.Bubble, typeof( EventHandler ), typeof( CollectionControlButton ) ); |
|||
public event RoutedEventHandler CollectionUpdated |
|||
{ |
|||
add |
|||
{ |
|||
AddHandler( CollectionUpdatedEvent, value ); |
|||
} |
|||
remove |
|||
{ |
|||
RemoveHandler( CollectionUpdatedEvent, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //CollectionUpdated Event
|
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
<!--*********************************************************************************** |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md |
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ |
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids |
|||
|
|||
**********************************************************************************--> |
|||
|
|||
<local:CollectionControlDialogBase x:Class="Xceed.Wpf.Toolkit.CollectionControlDialog" |
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit" |
|||
Title="Collection Control" |
|||
Height="400" |
|||
Width="600" |
|||
WindowStartupLocation="CenterScreen"> |
|||
|
|||
<Grid Margin="10"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="*" /> |
|||
<RowDefinition Height="Auto" /> |
|||
</Grid.RowDefinitions> |
|||
|
|||
<local:CollectionControl x:Name="_collectionControl" |
|||
ItemsSourceType="{Binding ItemsSourceType, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" |
|||
ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Mode=TwoWay}" |
|||
NewItemTypes="{Binding NewItemTypes, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" |
|||
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" |
|||
EditorDefinitions="{Binding EditorDefinitions, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/> |
|||
|
|||
<StackPanel Orientation="Horizontal" |
|||
Grid.Row="1" |
|||
HorizontalAlignment="Right" |
|||
Margin="5"> |
|||
<Button Width="75" |
|||
Margin="2" |
|||
Click="OkButton_Click" |
|||
IsDefault="True">OK</Button> |
|||
<Button Width="75" |
|||
Margin="2" |
|||
Click="CancelButton_Click" |
|||
IsCancel="True">Cancel</Button> |
|||
</StackPanel> |
|||
|
|||
</Grid> |
|||
</local:CollectionControlDialogBase> |
|||
@ -1,353 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics; |
|||
using System.Windows; |
|||
using System.Windows.Media; |
|||
using Xceed.Wpf.Toolkit.Core.Utilities; |
|||
using System.Linq; |
|||
using System.Runtime.Serialization; |
|||
using System.Security; |
|||
using System.IO; |
|||
using System.Runtime.Serialization.Formatters.Binary; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public partial class CollectionControlDialogBase : |
|||
Window |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Interaction logic for CollectionControlDialog.xaml
|
|||
/// </summary>
|
|||
public partial class CollectionControlDialog : CollectionControlDialogBase |
|||
{ |
|||
#region Private Members
|
|||
|
|||
private IList originalData = new List<object>(); |
|||
|
|||
#endregion
|
|||
|
|||
#region Properties
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof( IEnumerable ), typeof( CollectionControlDialog ), new UIPropertyMetadata( null ) ); |
|||
public IEnumerable ItemsSource |
|||
{ |
|||
get |
|||
{ |
|||
return ( IEnumerable )GetValue( ItemsSourceProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceProperty, value ); |
|||
} |
|||
} |
|||
|
|||
public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register( "ItemsSourceType", typeof( Type ), typeof( CollectionControlDialog ), new UIPropertyMetadata( null ) ); |
|||
public Type ItemsSourceType |
|||
{ |
|||
get |
|||
{ |
|||
return ( Type )GetValue( ItemsSourceTypeProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceTypeProperty, value ); |
|||
} |
|||
} |
|||
|
|||
public static readonly DependencyProperty NewItemTypesProperty = DependencyProperty.Register( "NewItemTypes", typeof( IList ), typeof( CollectionControlDialog ), new UIPropertyMetadata( null ) ); |
|||
public IList<Type> NewItemTypes |
|||
{ |
|||
get |
|||
{ |
|||
return ( IList<Type> )GetValue( NewItemTypesProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( NewItemTypesProperty, value ); |
|||
} |
|||
} |
|||
|
|||
public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( CollectionControlDialog ), new UIPropertyMetadata( false ) ); |
|||
public bool IsReadOnly |
|||
{ |
|||
get |
|||
{ |
|||
return ( bool )GetValue( IsReadOnlyProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( IsReadOnlyProperty, value ); |
|||
} |
|||
} |
|||
|
|||
public static readonly DependencyProperty EditorDefinitionsProperty = DependencyProperty.Register( "EditorDefinitions", typeof( EditorDefinitionCollection ), typeof( CollectionControlDialog ), new UIPropertyMetadata( null ) ); |
|||
public EditorDefinitionCollection EditorDefinitions |
|||
{ |
|||
get |
|||
{ |
|||
return ( EditorDefinitionCollection )GetValue( EditorDefinitionsProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( EditorDefinitionsProperty, value ); |
|||
} |
|||
} |
|||
|
|||
public CollectionControl CollectionControl |
|||
{ |
|||
get |
|||
{ |
|||
return _collectionControl; |
|||
} |
|||
} |
|||
|
|||
#endregion //Properties
|
|||
|
|||
#region Constructors
|
|||
|
|||
public CollectionControlDialog() |
|||
{ |
|||
InitializeComponent(); |
|||
} |
|||
|
|||
public CollectionControlDialog( Type itemsourceType ) |
|||
: this() |
|||
{ |
|||
ItemsSourceType = itemsourceType; |
|||
} |
|||
|
|||
public CollectionControlDialog( Type itemsourceType, IList<Type> newItemTypes ) |
|||
: this( itemsourceType ) |
|||
{ |
|||
NewItemTypes = newItemTypes; |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Overrides
|
|||
|
|||
protected override void OnSourceInitialized( EventArgs e ) |
|||
{ |
|||
base.OnSourceInitialized( e ); |
|||
|
|||
//Backup data if case "Cancel" is clicked.
|
|||
if( this.ItemsSource != null ) |
|||
{ |
|||
foreach( var item in this.ItemsSource ) |
|||
{ |
|||
originalData.Add( this.Clone( item ) ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Event Handlers
|
|||
|
|||
private void OkButton_Click( object sender, RoutedEventArgs e ) |
|||
{ |
|||
if( this.ItemsSource is IDictionary ) |
|||
{ |
|||
if( !this.AreDictionaryKeysValid() ) |
|||
{ |
|||
MessageBox.Show( "All dictionary items should have distinct non-null Key values.", "Warning" ); |
|||
return; |
|||
} |
|||
} |
|||
|
|||
this.DialogResult = _collectionControl.PersistChanges(); |
|||
this.Close(); |
|||
} |
|||
|
|||
private void CancelButton_Click( object sender, RoutedEventArgs e ) |
|||
{ |
|||
_collectionControl.PersistChanges( originalData ); |
|||
this.DialogResult = false; |
|||
this.Close(); |
|||
} |
|||
|
|||
#endregion //Event Hanlders
|
|||
|
|||
#region Private Methods
|
|||
|
|||
[SecuritySafeCritical] |
|||
private object Clone( object source ) |
|||
{ |
|||
if( source == null ) |
|||
return null; |
|||
|
|||
object result = null; |
|||
var sourceType = source.GetType(); |
|||
|
|||
if( source is Array ) |
|||
{ |
|||
using( var stream = new MemoryStream() ) |
|||
{ |
|||
var formatter = new BinaryFormatter(); |
|||
formatter.Serialize( stream, source ); |
|||
stream.Seek( 0, SeekOrigin.Begin ); |
|||
result = ( Array )formatter.Deserialize( stream ); |
|||
} |
|||
} |
|||
// For IDictionary, we need to create EditableKeyValuePair to edit the Key-Value.
|
|||
else if( ( this.ItemsSource is IDictionary ) |
|||
&& sourceType.IsGenericType |
|||
&& typeof( KeyValuePair<,> ).IsAssignableFrom( sourceType.GetGenericTypeDefinition() ) ) |
|||
{ |
|||
result = this.GenerateEditableKeyValuePair( source ); |
|||
} |
|||
else |
|||
{ |
|||
// Initialized a new object with default values
|
|||
try |
|||
{ |
|||
result = FormatterServices.GetUninitializedObject( sourceType ); |
|||
} |
|||
catch( Exception ) |
|||
{ |
|||
} |
|||
|
|||
var constructor = sourceType.GetConstructor( Type.EmptyTypes ); |
|||
if( constructor != null ) |
|||
{ |
|||
constructor.Invoke( result, null ); |
|||
} |
|||
else |
|||
{ |
|||
result = source; |
|||
} |
|||
} |
|||
Debug.Assert( result != null ); |
|||
if( result != null ) |
|||
{ |
|||
var properties = sourceType.GetProperties(); |
|||
|
|||
foreach( var propertyInfo in properties ) |
|||
{ |
|||
try |
|||
{ |
|||
var parameters = propertyInfo.GetIndexParameters(); |
|||
var index = parameters.GetLength( 0 ) == 0 ? null : new object[] { parameters.GetLength( 0 ) - 1 }; |
|||
var propertyInfoValue = propertyInfo.GetValue( source, index ); |
|||
|
|||
if( propertyInfo.CanWrite ) |
|||
{ |
|||
// Look for nested object
|
|||
if( propertyInfo.PropertyType.IsClass |
|||
&& ( propertyInfo.PropertyType != typeof( Transform ) ) |
|||
&& !propertyInfo.PropertyType.Equals( typeof( string ) ) ) |
|||
{ |
|||
// We have a Collection/List of T.
|
|||
if( propertyInfo.PropertyType.IsGenericType ) |
|||
{ |
|||
// Clone sub-objects if the T are non-primitive types objects.
|
|||
var arg = propertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(); |
|||
if( ( arg != null ) && !arg.IsPrimitive && !arg.Equals( typeof( String ) ) && !arg.IsEnum ) |
|||
{ |
|||
var nestedObject = this.Clone( propertyInfoValue ); |
|||
propertyInfo.SetValue( result, nestedObject, null ); |
|||
} |
|||
else |
|||
{ |
|||
// copy object if the T are primitive types objects.
|
|||
propertyInfo.SetValue( result, propertyInfoValue, null ); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var nestedObject = this.Clone( propertyInfoValue ); |
|||
if( nestedObject != null ) |
|||
{ |
|||
// For T object included in List/Collections, Add it to the List/Collection of T.
|
|||
if( index != null ) |
|||
{ |
|||
result.GetType().GetMethod( "Add" ).Invoke( result, new[] { nestedObject } ); |
|||
} |
|||
else |
|||
{ |
|||
propertyInfo.SetValue( result, nestedObject, null ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// For T object included in List/Collections, Add it to the List/Collection of T.
|
|||
if( index != null ) |
|||
{ |
|||
result.GetType().GetMethod( "Add" ).Invoke( result, new[] { propertyInfoValue } ); |
|||
} |
|||
else |
|||
{ |
|||
// copy regular object
|
|||
propertyInfo.SetValue( result, propertyInfoValue, null ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
catch( Exception ) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private object GenerateEditableKeyValuePair( object source ) |
|||
{ |
|||
var sourceType = source.GetType(); |
|||
if( ( sourceType.GetGenericArguments() == null ) || ( sourceType.GetGenericArguments().GetLength( 0 ) != 2 ) ) |
|||
return null; |
|||
|
|||
var propInfoKey = sourceType.GetProperty( "Key" ); |
|||
var propInfoValue = sourceType.GetProperty( "Value" ); |
|||
if( ( propInfoKey != null ) && ( propInfoValue != null ) ) |
|||
{ |
|||
return ListUtilities.CreateEditableKeyValuePair( propInfoKey.GetValue( source, null ) |
|||
, sourceType.GetGenericArguments()[ 0 ] |
|||
, propInfoValue.GetValue( source, null ) |
|||
, sourceType.GetGenericArguments()[ 1 ] ); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private bool AreDictionaryKeysValid() |
|||
{ |
|||
var keys = _collectionControl.Items.Select( x => |
|||
{ |
|||
var keyType = x.GetType().GetProperty( "Key" ); |
|||
if( keyType != null ) |
|||
{ |
|||
return keyType.GetValue( x, null ); |
|||
} |
|||
return null; |
|||
} ); |
|||
|
|||
return ( keys.Distinct().Count() == _collectionControl.Items.Count ) |
|||
&& keys.All( x => x != null ); |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -1,74 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 Xceed.Wpf.Toolkit.Core.Utilities; |
|||
|
|||
namespace Xceed.Wpf.Toolkit.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// This multi-value converter is used in the CollectionControl template
|
|||
/// to determine the list of possible new item types that will be shown in the combo box.
|
|||
///
|
|||
/// If the second value (i.e., CollectionControl.NewItemTypes) is not null, this list will be used.
|
|||
/// Otherwise, if the first value (i.e., CollectionControl.ItemsSourceType) is a "IList<T>"
|
|||
/// type, the new item type list will contain "T".
|
|||
///
|
|||
/// </summary>
|
|||
public class NewItemTypesComboBoxConverter : IMultiValueConverter |
|||
{ |
|||
public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture ) |
|||
{ |
|||
|
|||
if( values.Length != 2 ) |
|||
throw new ArgumentException("The 'values' argument should contain 2 objects."); |
|||
|
|||
if( values[ 1 ] != null ) |
|||
{ |
|||
if( !values[ 1 ].GetType().IsGenericType || !(values[ 1 ].GetType().GetGenericArguments().First().GetType() is Type) ) |
|||
throw new ArgumentException( "The 'value' argument is not of the correct type." ); |
|||
|
|||
return values[ 1 ]; |
|||
} |
|||
else if( values[ 0 ] != null ) |
|||
{ |
|||
if( !( values[ 0 ].GetType() is Type ) ) |
|||
throw new ArgumentException( "The 'value' argument is not of the correct type." ); |
|||
|
|||
List<Type> types = new List<Type>(); |
|||
Type listType = ListUtilities.GetListItemType( ( Type )values[ 0 ] ); |
|||
if( listType != null ) |
|||
{ |
|||
types.Add( listType ); |
|||
} |
|||
|
|||
return types; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture ) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,52 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
using System.Windows; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public class ItemAddingEventArgs : CancelRoutedEventArgs |
|||
{ |
|||
#region Constructor
|
|||
|
|||
public ItemAddingEventArgs( RoutedEvent itemAddingEvent, object itemAdding ) |
|||
: base( itemAddingEvent ) |
|||
{ |
|||
Item = itemAdding; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Properties
|
|||
|
|||
#region Item Property
|
|||
|
|||
public object Item |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#endregion //Properties
|
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
using System.Windows; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public class ItemDeletingEventArgs : CancelRoutedEventArgs |
|||
{ |
|||
#region Private Members
|
|||
|
|||
private object _item; |
|||
|
|||
#endregion
|
|||
|
|||
#region Constructor
|
|||
|
|||
public ItemDeletingEventArgs( RoutedEvent itemDeletingEvent, object itemDeleting ) |
|||
: base( itemDeletingEvent ) |
|||
{ |
|||
_item = itemDeleting; |
|||
} |
|||
|
|||
#region Property Item
|
|||
|
|||
public object Item |
|||
{ |
|||
get |
|||
{ |
|||
return _item; |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -1,55 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 |
|||
{ |
|||
public class ItemEventArgs : RoutedEventArgs |
|||
{ |
|||
#region Protected Members
|
|||
|
|||
private object _item; |
|||
|
|||
#endregion
|
|||
|
|||
#region Constructor
|
|||
|
|||
internal ItemEventArgs( RoutedEvent routedEvent, object newItem ) |
|||
: base( routedEvent ) |
|||
{ |
|||
_item = newItem; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Property Item
|
|||
|
|||
public object Item |
|||
{ |
|||
get |
|||
{ |
|||
return _item; |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
|
Before Width: | Height: | Size: 822 B |
@ -1,314 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
using System.Windows; |
|||
using System.Windows.Controls; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public class PrimitiveTypeCollectionControl : ContentControl |
|||
{ |
|||
#region Members
|
|||
|
|||
bool _surpressTextChanged; |
|||
bool _conversionFailed; |
|||
|
|||
#endregion //Members
|
|||
|
|||
#region Properties
|
|||
|
|||
#region IsOpen
|
|||
|
|||
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register( "IsOpen", typeof( bool ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( false, OnIsOpenChanged ) ); |
|||
public bool IsOpen |
|||
{ |
|||
get |
|||
{ |
|||
return ( bool )GetValue( IsOpenProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( IsOpenProperty, value ); |
|||
} |
|||
} |
|||
|
|||
private static void OnIsOpenChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; |
|||
if( primitiveTypeCollectionControl != null ) |
|||
primitiveTypeCollectionControl.OnIsOpenChanged( ( bool )e.OldValue, ( bool )e.NewValue ); |
|||
} |
|||
|
|||
protected virtual void OnIsOpenChanged( bool oldValue, bool newValue ) |
|||
{ |
|||
|
|||
} |
|||
|
|||
#endregion //IsOpen
|
|||
|
|||
#region ItemsSource
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( "ItemsSource", typeof( IList ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( null, OnItemsSourceChanged ) ); |
|||
public IList ItemsSource |
|||
{ |
|||
get |
|||
{ |
|||
return ( IList )GetValue( ItemsSourceProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceProperty, value ); |
|||
} |
|||
} |
|||
|
|||
private static void OnItemsSourceChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; |
|||
if( primitiveTypeCollectionControl != null ) |
|||
primitiveTypeCollectionControl.OnItemsSourceChanged( ( IList )e.OldValue, ( IList )e.NewValue ); |
|||
} |
|||
|
|||
protected virtual void OnItemsSourceChanged( IList oldValue, IList newValue ) |
|||
{ |
|||
if( newValue == null ) |
|||
return; |
|||
|
|||
if( ItemsSourceType == null ) |
|||
ItemsSourceType = newValue.GetType(); |
|||
|
|||
if( ItemType == null && newValue.GetType().ContainsGenericParameters ) |
|||
ItemType = newValue.GetType().GetGenericArguments()[ 0 ]; |
|||
|
|||
SetText( newValue ); |
|||
} |
|||
|
|||
#endregion //ItemsSource
|
|||
|
|||
#region IsReadOnly
|
|||
|
|||
public static readonly DependencyProperty IsReadOnlyProperty = |
|||
DependencyProperty.Register( "IsReadOnly", typeof( bool ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( false ) ); |
|||
|
|||
public bool IsReadOnly |
|||
{ |
|||
get { return ( bool )GetValue( IsReadOnlyProperty ); } |
|||
set { SetValue( IsReadOnlyProperty, value ); } |
|||
} |
|||
|
|||
#endregion //IsReadOnly
|
|||
|
|||
#region ItemsSourceType
|
|||
|
|||
public static readonly DependencyProperty ItemsSourceTypeProperty = DependencyProperty.Register( "ItemsSourceType", typeof( Type ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public Type ItemsSourceType |
|||
{ |
|||
get |
|||
{ |
|||
return ( Type )GetValue( ItemsSourceTypeProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemsSourceTypeProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion ItemsSourceType
|
|||
|
|||
#region ItemType
|
|||
|
|||
public static readonly DependencyProperty ItemTypeProperty = DependencyProperty.Register( "ItemType", typeof( Type ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( null ) ); |
|||
public Type ItemType |
|||
{ |
|||
get |
|||
{ |
|||
return ( Type )GetValue( ItemTypeProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( ItemTypeProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion ItemType
|
|||
|
|||
#region Text
|
|||
|
|||
public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof( string ), typeof( PrimitiveTypeCollectionControl ), new UIPropertyMetadata( null, OnTextChanged ) ); |
|||
public string Text |
|||
{ |
|||
get |
|||
{ |
|||
return ( string )GetValue( TextProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( TextProperty, value ); |
|||
} |
|||
} |
|||
|
|||
private static void OnTextChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
PrimitiveTypeCollectionControl primitiveTypeCollectionControl = o as PrimitiveTypeCollectionControl; |
|||
if( primitiveTypeCollectionControl != null ) |
|||
primitiveTypeCollectionControl.OnTextChanged( ( string )e.OldValue, ( string )e.NewValue ); |
|||
} |
|||
|
|||
protected virtual void OnTextChanged( string oldValue, string newValue ) |
|||
{ |
|||
if( !_surpressTextChanged ) |
|||
PersistChanges(); |
|||
} |
|||
|
|||
#endregion //Text
|
|||
|
|||
#endregion //Properties
|
|||
|
|||
#region Constructors
|
|||
|
|||
static PrimitiveTypeCollectionControl() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PrimitiveTypeCollectionControl ), new FrameworkPropertyMetadata( typeof( PrimitiveTypeCollectionControl ) ) ); |
|||
} |
|||
|
|||
public PrimitiveTypeCollectionControl() |
|||
{ |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Overrides
|
|||
|
|||
|
|||
#endregion
|
|||
|
|||
#region Methods
|
|||
|
|||
private void PersistChanges() |
|||
{ |
|||
IList list = ComputeItemsSource(); |
|||
if( list == null ) |
|||
return; |
|||
|
|||
IList items = ComputeItems(); |
|||
|
|||
//the easiest way to persist changes to the source is to just clear the source list and then add all items to it.
|
|||
list.Clear(); |
|||
|
|||
int counter = 0; |
|||
foreach( var item in items ) |
|||
{ |
|||
if( list is Array ) |
|||
{ |
|||
( ( Array )list ).SetValue( item, counter++); |
|||
} |
|||
else |
|||
{ |
|||
list.Add( item ); |
|||
} |
|||
}; |
|||
|
|||
// if something went wrong during conversion we want to reload the text to show only valid entries
|
|||
if( _conversionFailed ) |
|||
SetText( list ); |
|||
} |
|||
|
|||
private IList ComputeItems() |
|||
{ |
|||
IList items = new List<object>(); |
|||
|
|||
if( ItemType == null ) |
|||
return items; |
|||
|
|||
string[] textArray = Text.Split( '\n' ); |
|||
|
|||
foreach( string s in textArray ) |
|||
{ |
|||
string valueString = s.TrimEnd( '\r' ); |
|||
if( !String.IsNullOrEmpty( valueString ) ) |
|||
{ |
|||
object value = null; |
|||
try |
|||
{ |
|||
if( ItemType.IsEnum ) |
|||
{ |
|||
value = Enum.Parse( ItemType, valueString ); |
|||
} |
|||
else |
|||
{ |
|||
value = Convert.ChangeType( valueString, ItemType ); |
|||
} |
|||
} |
|||
catch |
|||
{ |
|||
//a conversion failed
|
|||
_conversionFailed = true; |
|||
} |
|||
|
|||
if( value != null ) |
|||
items.Add( value ); |
|||
} |
|||
} |
|||
|
|||
return items; |
|||
} |
|||
|
|||
private IList ComputeItemsSource() |
|||
{ |
|||
if( ItemsSource == null ) |
|||
{ |
|||
// Save current text since creating the ItemsSource will reset it
|
|||
string currentText = this.Text; |
|||
ItemsSource = CreateItemsSource(); |
|||
this.Text = currentText; |
|||
} |
|||
|
|||
return ItemsSource; |
|||
} |
|||
|
|||
private IList CreateItemsSource() |
|||
{ |
|||
IList list = null; |
|||
|
|||
if( ItemsSourceType != null ) |
|||
{ |
|||
ConstructorInfo constructor = ItemsSourceType.GetConstructor( Type.EmptyTypes ); |
|||
list = ( IList )constructor.Invoke( null ); |
|||
} |
|||
|
|||
return list; |
|||
} |
|||
|
|||
private void SetText( IEnumerable collection ) |
|||
{ |
|||
_surpressTextChanged = true; |
|||
StringBuilder builder = new StringBuilder(); |
|||
foreach( object obj2 in collection ) |
|||
{ |
|||
builder.Append( obj2.ToString() ); |
|||
builder.AppendLine(); |
|||
} |
|||
Text = builder.ToString().Trim(); |
|||
_surpressTextChanged = false; |
|||
} |
|||
|
|||
#endregion //Methods
|
|||
} |
|||
} |
|||
@ -1,334 +0,0 @@ |
|||
<!--*********************************************************************************** |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md |
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ |
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids |
|||
|
|||
**********************************************************************************--> |
|||
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit" |
|||
xmlns:conv="clr-namespace:Xceed.Wpf.Toolkit.Core.Converters" |
|||
xmlns:colconv="clr-namespace:Xceed.Wpf.Toolkit.Converters" |
|||
xmlns:themes="clr-namespace:Xceed.Wpf.Toolkit.Themes" |
|||
xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes" |
|||
xmlns:pg="clr-namespace:Xceed.Wpf.Toolkit.PropertyGrid"> |
|||
|
|||
<ResourceDictionary.MergedDictionaries> |
|||
<ResourceDictionary Source="../../Themes/Aero2/Glyphs.xaml" /> |
|||
</ResourceDictionary.MergedDictionaries> |
|||
|
|||
<conv:InverseBoolConverter x:Key="InverseBoolConverter" /> |
|||
<conv:ObjectTypeToNameConverter x:Key="ObjectTypeToNameConverter" /> |
|||
<colconv:NewItemTypesComboBoxConverter x:Key="NewItemTypesComboBoxConverter" /> |
|||
|
|||
<Style x:Key="CollectionControlButtonStyle" |
|||
TargetType="{x:Type Button}"> |
|||
<Style.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="false"> |
|||
<Setter Property="Opacity" |
|||
Value="0.6" /> |
|||
</Trigger> |
|||
</Style.Triggers> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Height" |
|||
Value="26" /> |
|||
<Setter Property="Width" |
|||
Value="26" /> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:CollectionControl}"> |
|||
<Style.Resources> |
|||
<Style TargetType="ListBox"> |
|||
<Setter Property="ItemTemplate"> |
|||
<Setter.Value> |
|||
<DataTemplate> |
|||
<TextBlock Text="{Binding Converter={StaticResource ObjectTypeToNameConverter}}" /> |
|||
</DataTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
</Style.Resources> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:CollectionControl}"> |
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<Grid Margin="{TemplateBinding Padding}"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
<ColumnDefinition Width="1.5*" /> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition /> |
|||
</Grid.RowDefinitions> |
|||
<ContentControl Margin="0,0,0,5" |
|||
Content="{TemplateBinding TypeSelectionLabel}"> |
|||
</ContentControl> |
|||
<ComboBox x:Name="PART_NewItemTypesComboBox" |
|||
Grid.Row="1" |
|||
Margin="0,0,0,3" |
|||
HorizontalAlignment="Stretch"> |
|||
<ComboBox.ItemsSource> |
|||
<MultiBinding Converter="{StaticResource NewItemTypesComboBoxConverter}"> |
|||
<Binding RelativeSource="{RelativeSource TemplatedParent}" |
|||
Path="ItemsSourceType" /> |
|||
<Binding RelativeSource="{RelativeSource TemplatedParent}" |
|||
Path="NewItemTypes" /> |
|||
</MultiBinding> |
|||
</ComboBox.ItemsSource> |
|||
<ComboBox.ItemTemplate> |
|||
<DataTemplate> |
|||
<TextBlock Text="{Binding Converter={StaticResource ObjectTypeToNameConverter}}" /> |
|||
</DataTemplate> |
|||
</ComboBox.ItemTemplate> |
|||
</ComboBox> |
|||
<Button Margin="3,0,0,3" |
|||
Grid.Row="1" |
|||
Grid.Column="1" |
|||
Padding="5,0" |
|||
Content="Add" |
|||
Command="New" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_NewItemTypesComboBox}"> |
|||
</Button> |
|||
<ListBox x:Name="PART_ListBox" |
|||
Grid.Row="2" |
|||
Grid.ColumnSpan="2" |
|||
ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}" |
|||
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" |
|||
SelectedIndex="0"> |
|||
</ListBox> |
|||
<StackPanel Margin="7,2,0,0" |
|||
VerticalAlignment="Top" |
|||
Grid.Column="2" |
|||
Grid.Row="2"> |
|||
<Button Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="ComponentCommands.MoveUp" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Path Fill="#FF000000" |
|||
Data="F0 M 6,0 L 12,7 8,7 8,12 4,12 4,7 0,7 Z" /> |
|||
</Button> |
|||
<Button Margin="0,1,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="ComponentCommands.MoveDown" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Path Fill="#FF000000" |
|||
Data="F0 M 4,0 L 8,0 8,5 12,5 6,12 0,5 4,5 Z" /> |
|||
</Button> |
|||
<Button Margin="0,7,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="Delete" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Image Stretch="None" |
|||
Height="16" |
|||
Width="16" |
|||
Margin="1" |
|||
Source="./../Images/Delete16.png"> |
|||
</Image> |
|||
</Button> |
|||
<Button Margin="0,7,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="Copy" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Image Stretch="None" |
|||
Height="16" |
|||
Width="16" |
|||
Margin="1" |
|||
Source="./../Images/Duplicate.png"> |
|||
</Image> |
|||
</Button> |
|||
</StackPanel> |
|||
</Grid> |
|||
<Grid Column="1" |
|||
Margin="20,0,0,0"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition /> |
|||
</Grid.RowDefinitions> |
|||
<ContentControl Grid.Column="1" |
|||
Content="{TemplateBinding PropertiesLabel}"> |
|||
</ContentControl> |
|||
<pg:PropertyGrid x:Name="PART_PropertyGrid" |
|||
Grid.Row="1" |
|||
Grid.Column="1" |
|||
Margin="0,5,0,0" |
|||
HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Stretch" |
|||
SelectedObject="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" |
|||
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" |
|||
EditorDefinitions="{Binding EditorDefinitions, RelativeSource={RelativeSource TemplatedParent}}"/> |
|||
</Grid> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="False"> |
|||
<Setter Property="Foreground" |
|||
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" |
|||
TargetName="PART_NewItemTypesComboBox" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="PrimitiveTypeCollectionControl" |
|||
TargetType="{x:Type local:PrimitiveTypeCollectionControl}"> |
|||
<Setter Property="BorderBrush" |
|||
Value="{DynamicResource {x:Static themes:ResourceKeys.ControlNormalBorderKey}}" /> |
|||
<Setter Property="Background" |
|||
Value="Transparent" /> |
|||
<Setter Property="BorderThickness" |
|||
Value="1,1,0,1" /> |
|||
<Setter Property="IsTabStop" |
|||
Value="False" /> |
|||
<Setter Property="Padding" |
|||
Value="2,0,0,0" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:PrimitiveTypeCollectionControl}"> |
|||
<local:MultiLineTextEditor Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Content="{TemplateBinding Content}" |
|||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
Padding="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
IsOpen="{TemplateBinding IsOpen}" |
|||
IsReadOnly="{TemplateBinding IsReadOnly}" |
|||
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
DropDownWidth="{TemplateBinding ActualWidth}" /> |
|||
|
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsMouseOver" |
|||
Value="True"> |
|||
<Setter Property="BorderBrush" |
|||
Value="{DynamicResource {x:Static themes:ResourceKeys.ControlMouseOverBorderKey}}" /> |
|||
</Trigger> |
|||
<Trigger Property="IsKeyboardFocusWithin" |
|||
Value="True"> |
|||
<Setter Property="BorderBrush" |
|||
Value="{DynamicResource {x:Static themes:ResourceKeys.ControlSelectedBorderKey}}" /> |
|||
</Trigger> |
|||
<Trigger Property="IsEnabled" |
|||
Value="False"> |
|||
<Setter Property="Background" |
|||
Value="{DynamicResource {x:Static themes:ResourceKeys.ControlDisabledBackgroundKey}}" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
|
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:PrimitiveTypeCollectionControl}" |
|||
BasedOn="{StaticResource PrimitiveTypeCollectionControl}" /> |
|||
|
|||
<Style x:Key="CollectionControlButton" |
|||
TargetType="{x:Type local:CollectionControlButton}"> |
|||
<Setter Property="Background" |
|||
Value="White" /> |
|||
<Setter Property="BorderThickness" |
|||
Value="0" /> |
|||
<Setter Property="Padding" |
|||
Value="2,0,0,0" /> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Left" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Content" |
|||
Value="(Collection)" /> |
|||
<Setter Property="SnapsToDevicePixels" |
|||
Value="True" /> |
|||
<Setter Property="MinHeight" |
|||
Value="22" /> |
|||
<Setter Property="IsTabStop" |
|||
Value="True" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="Button"> |
|||
<Grid SnapsToDevicePixels="True"> |
|||
<Grid> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Padding="{TemplateBinding Padding}" |
|||
SnapsToDevicePixels="True"> |
|||
<ContentPresenter Content="{TemplateBinding Content}" |
|||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
|||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" /> |
|||
</Border> |
|||
|
|||
<chrome:ButtonChrome x:Name="ToggleButtonChrome" |
|||
Grid.Column="1" |
|||
CornerRadius="0,2.75,2.75,0" |
|||
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CollectionControlButton}}" |
|||
RenderMouseOver="{TemplateBinding IsMouseOver}"> |
|||
<Grid x:Name="arrowGlyph" |
|||
IsHitTestVisible="False" |
|||
Grid.Column="1" |
|||
Margin="5"> |
|||
<Path x:Name="Arrow" |
|||
Width="9" |
|||
Height="5" |
|||
Data="{StaticResource DownArrowGeometry}" |
|||
Fill="#FF000000" |
|||
Margin="0,1,0,0" /> |
|||
</Grid> |
|||
</chrome:ButtonChrome> |
|||
</Grid> |
|||
|
|||
</Grid> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="False"> |
|||
<Setter Property="Fill" |
|||
TargetName="Arrow" |
|||
Value="#AFAFAF" /> |
|||
<Setter Property="Foreground" |
|||
Value="Gray" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:CollectionControlButton}" |
|||
BasedOn="{StaticResource CollectionControlButton}" /> |
|||
|
|||
</ResourceDictionary> |
|||
@ -1,327 +0,0 @@ |
|||
<!--*********************************************************************************** |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md |
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ |
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids |
|||
|
|||
**********************************************************************************--> |
|||
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit" |
|||
xmlns:conv="clr-namespace:Xceed.Wpf.Toolkit.Core.Converters" |
|||
xmlns:colconv="clr-namespace:Xceed.Wpf.Toolkit.Converters" |
|||
xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes" |
|||
xmlns:pg="clr-namespace:Xceed.Wpf.Toolkit.PropertyGrid"> |
|||
|
|||
<ResourceDictionary.MergedDictionaries> |
|||
<ResourceDictionary Source="..\..\Themes\Generic\Glyphs.xaml" /> |
|||
</ResourceDictionary.MergedDictionaries> |
|||
|
|||
<conv:InverseBoolConverter x:Key="InverseBoolConverter" /> |
|||
<conv:ObjectTypeToNameConverter x:Key="ObjectTypeToNameConverter" /> |
|||
<colconv:NewItemTypesComboBoxConverter x:Key="NewItemTypesComboBoxConverter" /> |
|||
|
|||
<Style x:Key="CollectionControlButtonStyle" |
|||
TargetType="{x:Type Button}"> |
|||
<Style.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="false"> |
|||
<Setter Property="Opacity" |
|||
Value="0.6" /> |
|||
</Trigger> |
|||
</Style.Triggers> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Height" |
|||
Value="26" /> |
|||
<Setter Property="Width" |
|||
Value="26" /> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:CollectionControl}"> |
|||
<Style.Resources> |
|||
<Style TargetType="ListBox"> |
|||
<Setter Property="ItemTemplate"> |
|||
<Setter.Value> |
|||
<DataTemplate> |
|||
<TextBlock Text="{Binding Converter={StaticResource ObjectTypeToNameConverter}}" /> |
|||
</DataTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
</Style.Resources> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:CollectionControl}"> |
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}"> |
|||
<Grid Margin="{TemplateBinding Padding}"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
<ColumnDefinition Width="1.5*" /> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition /> |
|||
</Grid.RowDefinitions> |
|||
<ContentControl Margin="0,0,0,5" |
|||
Content="{TemplateBinding TypeSelectionLabel}"> |
|||
</ContentControl> |
|||
<ComboBox x:Name="PART_NewItemTypesComboBox" |
|||
Grid.Row="1" |
|||
Margin="0,0,0,3" |
|||
HorizontalAlignment="Stretch"> |
|||
<ComboBox.ItemsSource> |
|||
<MultiBinding Converter="{StaticResource NewItemTypesComboBoxConverter}"> |
|||
<Binding RelativeSource="{RelativeSource TemplatedParent}" |
|||
Path="ItemsSourceType" /> |
|||
<Binding RelativeSource="{RelativeSource TemplatedParent}" |
|||
Path="NewItemTypes" /> |
|||
</MultiBinding> |
|||
</ComboBox.ItemsSource> |
|||
<ComboBox.ItemTemplate> |
|||
<DataTemplate> |
|||
<TextBlock Text="{Binding Converter={StaticResource ObjectTypeToNameConverter}}" /> |
|||
</DataTemplate> |
|||
</ComboBox.ItemTemplate> |
|||
</ComboBox> |
|||
<Button Margin="3,0,0,3" |
|||
Grid.Row="1" |
|||
Grid.Column="1" |
|||
Padding="5,0" |
|||
Content="Add" |
|||
Command="New" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_NewItemTypesComboBox}" > |
|||
</Button> |
|||
<ListBox x:Name="PART_ListBox" |
|||
Grid.Row="2" |
|||
Grid.ColumnSpan="2" |
|||
ItemsSource="{Binding Items, RelativeSource={RelativeSource TemplatedParent}}" |
|||
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" |
|||
SelectedIndex="0"> |
|||
</ListBox> |
|||
<StackPanel Margin="7,2,0,0" |
|||
VerticalAlignment="Top" |
|||
Grid.Column="2" |
|||
Grid.Row="2"> |
|||
<Button Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="ComponentCommands.MoveUp" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Path Fill="#FF404040" |
|||
Data="F0 M 6,0 L 12,7 8,7 8,12 4,12 4,7 0,7 Z" /> |
|||
</Button> |
|||
<Button Margin="0,1,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="ComponentCommands.MoveDown" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Path Fill="#FF404040" |
|||
Data="F0 M 4,0 L 8,0 8,5 12,5 6,12 0,5 4,5 Z" /> |
|||
</Button> |
|||
<Button Margin="0,7,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="Delete" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Image Stretch="None" |
|||
Height="16" |
|||
Width="16" |
|||
Margin="1" |
|||
Source="./../Images/Delete16.png" > |
|||
</Image> |
|||
</Button> |
|||
<Button Margin="0,7,0,0" |
|||
Style="{StaticResource CollectionControlButtonStyle}" |
|||
Command="Copy" |
|||
CommandParameter="{Binding SelectedItem, ElementName=PART_ListBox}"> |
|||
<Image Stretch="None" |
|||
Height="16" |
|||
Width="16" |
|||
Margin="1" |
|||
Source="./../Images/Duplicate.png"> |
|||
</Image> |
|||
</Button> |
|||
</StackPanel> |
|||
</Grid> |
|||
<Grid Column="1" |
|||
Margin="20,0,0,0"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition Height="Auto" /> |
|||
<RowDefinition /> |
|||
</Grid.RowDefinitions> |
|||
<ContentControl Grid.Column="1" |
|||
Content="{TemplateBinding PropertiesLabel}"> |
|||
</ContentControl> |
|||
<pg:PropertyGrid x:Name="PART_PropertyGrid" |
|||
Grid.Row="1" |
|||
Grid.Column="1" |
|||
Margin="0,5,0,0" |
|||
HorizontalAlignment="Stretch" |
|||
VerticalAlignment="Stretch" |
|||
SelectedObject="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" |
|||
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" |
|||
EditorDefinitions="{Binding EditorDefinitions, RelativeSource={RelativeSource TemplatedParent}}"/> |
|||
</Grid> |
|||
</Grid> |
|||
</Border> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="False"> |
|||
<Setter Property="Foreground" |
|||
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" |
|||
TargetName="PART_NewItemTypesComboBox" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style x:Key="PrimitiveTypeCollectionControl" |
|||
TargetType="{x:Type local:PrimitiveTypeCollectionControl}"> |
|||
<Setter Property="BorderBrush"> |
|||
<Setter.Value> |
|||
<LinearGradientBrush EndPoint="0.5,1" |
|||
StartPoint="0.5,0"> |
|||
<GradientStop Color="#FFA3AEB9" |
|||
Offset="0" /> |
|||
<GradientStop Color="#FF8399A9" |
|||
Offset="0.375" /> |
|||
<GradientStop Color="#FF718597" |
|||
Offset="0.375" /> |
|||
<GradientStop Color="#FF617584" |
|||
Offset="1" /> |
|||
</LinearGradientBrush> |
|||
</Setter.Value> |
|||
</Setter> |
|||
<Setter Property="Background" |
|||
Value="Transparent" /> |
|||
<Setter Property="BorderThickness" |
|||
Value="1,1,0,1" /> |
|||
<Setter Property="IsTabStop" |
|||
Value="False" /> |
|||
<Setter Property="Padding" |
|||
Value="2,0,0,0" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:PrimitiveTypeCollectionControl}"> |
|||
<local:MultiLineTextEditor Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Content="{TemplateBinding Content}" |
|||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
Padding="{TemplateBinding Padding}" |
|||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
|||
IsOpen="{TemplateBinding IsOpen}" |
|||
IsReadOnly="{TemplateBinding IsReadOnly}" |
|||
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
|||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
DropDownWidth="{TemplateBinding ActualWidth}" /> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:PrimitiveTypeCollectionControl}" |
|||
BasedOn="{StaticResource PrimitiveTypeCollectionControl}" /> |
|||
|
|||
<Style x:Key="CollectionControlButton" |
|||
TargetType="{x:Type local:CollectionControlButton}"> |
|||
<Setter Property="Background" |
|||
Value="White" /> |
|||
<Setter Property="BorderThickness" |
|||
Value="0" /> |
|||
<Setter Property="Padding" |
|||
Value="2,0,0,0" /> |
|||
<Setter Property="HorizontalContentAlignment" |
|||
Value="Left" /> |
|||
<Setter Property="VerticalContentAlignment" |
|||
Value="Center" /> |
|||
<Setter Property="Content" |
|||
Value="(Collection)" /> |
|||
<Setter Property="SnapsToDevicePixels" |
|||
Value="True" /> |
|||
<Setter Property="MinHeight" |
|||
Value="22" /> |
|||
<Setter Property="IsTabStop" |
|||
Value="True" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="Button"> |
|||
<Grid SnapsToDevicePixels="True"> |
|||
<Grid> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="*" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<Border Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
Padding="{TemplateBinding Padding}" |
|||
SnapsToDevicePixels="True"> |
|||
<ContentPresenter Content="{TemplateBinding Content}" |
|||
ContentTemplate="{TemplateBinding ContentTemplate}" |
|||
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
|||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
|||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" /> |
|||
</Border> |
|||
|
|||
<chrome:ButtonChrome x:Name="ToggleButtonChrome" |
|||
Grid.Column="1" |
|||
CornerRadius="0,2.75,2.75,0" |
|||
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CollectionControlButton}}" |
|||
RenderMouseOver="{TemplateBinding IsMouseOver}"> |
|||
<Grid x:Name="arrowGlyph" |
|||
IsHitTestVisible="False" |
|||
Grid.Column="1" |
|||
Margin="5"> |
|||
<Path x:Name="Arrow" |
|||
Width="9" |
|||
Height="5" |
|||
Data="{StaticResource DownArrowGeometry}" |
|||
Fill="#FF000000" |
|||
Margin="0,1,0,0" /> |
|||
</Grid> |
|||
</chrome:ButtonChrome> |
|||
</Grid> |
|||
|
|||
</Grid> |
|||
<ControlTemplate.Triggers> |
|||
<Trigger Property="IsEnabled" |
|||
Value="False"> |
|||
<Setter Property="Fill" |
|||
TargetName="Arrow" |
|||
Value="#AFAFAF" /> |
|||
<Setter Property="Foreground" |
|||
Value="Gray" /> |
|||
</Trigger> |
|||
</ControlTemplate.Triggers> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
<Style TargetType="{x:Type local:CollectionControlButton}" |
|||
BasedOn="{StaticResource CollectionControlButton}" /> |
|||
|
|||
</ResourceDictionary> |
|||
@ -1,75 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System.Windows; |
|||
using System.Windows.Media; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid; |
|||
|
|||
namespace Xceed.Wpf.Toolkit.Core.Utilities |
|||
{ |
|||
public class ContextMenuUtilities |
|||
{ |
|||
public static readonly DependencyProperty OpenOnMouseLeftButtonClickProperty = DependencyProperty.RegisterAttached( "OpenOnMouseLeftButtonClick", typeof( bool ), typeof( ContextMenuUtilities ), new FrameworkPropertyMetadata( false, OpenOnMouseLeftButtonClickChanged ) ); |
|||
public static void SetOpenOnMouseLeftButtonClick( FrameworkElement element, bool value ) |
|||
{ |
|||
element.SetValue( OpenOnMouseLeftButtonClickProperty, value ); |
|||
} |
|||
public static bool GetOpenOnMouseLeftButtonClick( FrameworkElement element ) |
|||
{ |
|||
return ( bool )element.GetValue( OpenOnMouseLeftButtonClickProperty ); |
|||
} |
|||
|
|||
public static void OpenOnMouseLeftButtonClickChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
var control = sender as FrameworkElement; |
|||
if( control != null ) |
|||
{ |
|||
if( ( bool )e.NewValue ) |
|||
{ |
|||
control.PreviewMouseLeftButtonDown += ContextMenuUtilities.Control_PreviewMouseLeftButtonDown; |
|||
} |
|||
else |
|||
{ |
|||
control.PreviewMouseLeftButtonDown -= ContextMenuUtilities.Control_PreviewMouseLeftButtonDown; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void Control_PreviewMouseLeftButtonDown( object sender, System.Windows.Input.MouseButtonEventArgs e ) |
|||
{ |
|||
var control = sender as FrameworkElement; |
|||
if( (control != null) && (control.ContextMenu != null) ) |
|||
{ |
|||
// Get PropertyItemBase parent
|
|||
var parent = VisualTreeHelper.GetParent( control ); |
|||
while( parent != null ) |
|||
{ |
|||
var propertyItemBase = parent as PropertyItemBase; |
|||
if( propertyItemBase != null ) |
|||
{ |
|||
// Set the ContextMenu.DataContext to the PropertyItem associated to the clicked image.
|
|||
control.ContextMenu.DataContext = propertyItemBase; |
|||
break; |
|||
} |
|||
parent = VisualTreeHelper.GetParent( parent ); |
|||
} |
|||
|
|||
control.ContextMenu.PlacementTarget = control; |
|||
control.ContextMenu.IsOpen = true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,80 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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.Text; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors; |
|||
|
|||
namespace Xceed.Wpf.Toolkit.Core.Utilities |
|||
{ |
|||
internal class ListUtilities |
|||
{ |
|||
internal static Type GetListItemType( Type listType ) |
|||
{ |
|||
Type iListOfT = listType.GetInterfaces().FirstOrDefault( |
|||
( i ) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof( IList<> ) ); |
|||
|
|||
return ( iListOfT != null ) |
|||
? iListOfT.GetGenericArguments()[ 0 ] |
|||
: null; |
|||
} |
|||
|
|||
internal static Type GetCollectionItemType( Type colType ) |
|||
{ |
|||
Type iCollectionOfT = null; |
|||
var isCollectionOfT = colType.IsGenericType && (colType.GetGenericTypeDefinition() == typeof( ICollection<> ) ); |
|||
if( isCollectionOfT ) |
|||
{ |
|||
iCollectionOfT = colType; |
|||
} |
|||
else |
|||
{ |
|||
iCollectionOfT = colType.GetInterfaces().FirstOrDefault(( i ) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof( ICollection<> ) ); |
|||
} |
|||
|
|||
return (iCollectionOfT != null) |
|||
? iCollectionOfT.GetGenericArguments()[ 0 ] |
|||
: null; |
|||
} |
|||
|
|||
internal static Type[] GetDictionaryItemsType( Type dictType ) |
|||
{ |
|||
var isDict = dictType.IsGenericType |
|||
&& ((dictType.GetGenericTypeDefinition() == typeof( Dictionary<,>) ) || (dictType.GetGenericTypeDefinition() == typeof( IDictionary<,>) )); |
|||
|
|||
return isDict |
|||
? new Type[] { dictType.GetGenericArguments()[ 0 ], dictType.GetGenericArguments()[ 1 ] } |
|||
: null; |
|||
} |
|||
|
|||
internal static object CreateEditableKeyValuePair( object key, Type keyType, object value, Type valueType ) |
|||
{ |
|||
var itemType = ListUtilities.CreateEditableKeyValuePairType( keyType, valueType ); |
|||
return Activator.CreateInstance( itemType, key, value ); |
|||
} |
|||
|
|||
internal static Type CreateEditableKeyValuePairType( Type keyType, Type valueType ) |
|||
{ |
|||
//return an EditableKeyValuePair< TKey, TValue> Type from keyType and valueType
|
|||
var itemGenType = typeof( EditableKeyValuePair<,> ); |
|||
Type[] itemGenTypeArgs = { keyType, valueType }; |
|||
return itemGenType.MakeGenericType( itemGenTypeArgs ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,105 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.ComponentModel; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public class AutoCompletingMaskEventArgs : CancelEventArgs |
|||
{ |
|||
public AutoCompletingMaskEventArgs( MaskedTextProvider maskedTextProvider, int startPosition, int selectionLength, string input ) |
|||
{ |
|||
m_autoCompleteStartPosition = -1; |
|||
|
|||
m_maskedTextProvider = maskedTextProvider; |
|||
m_startPosition = startPosition; |
|||
m_selectionLength = selectionLength; |
|||
m_input = input; |
|||
} |
|||
|
|||
#region MaskedTextProvider PROPERTY
|
|||
|
|||
private MaskedTextProvider m_maskedTextProvider; |
|||
|
|||
public MaskedTextProvider MaskedTextProvider |
|||
{ |
|||
get { return m_maskedTextProvider; } |
|||
} |
|||
|
|||
#endregion MaskedTextProvider PROPERTY
|
|||
|
|||
#region StartPosition PROPERTY
|
|||
|
|||
private int m_startPosition; |
|||
|
|||
public int StartPosition |
|||
{ |
|||
get { return m_startPosition; } |
|||
} |
|||
|
|||
#endregion StartPosition PROPERTY
|
|||
|
|||
#region SelectionLength PROPERTY
|
|||
|
|||
private int m_selectionLength; |
|||
|
|||
public int SelectionLength |
|||
{ |
|||
get { return m_selectionLength; } |
|||
} |
|||
|
|||
#endregion SelectionLength PROPERTY
|
|||
|
|||
#region Input PROPERTY
|
|||
|
|||
private string m_input; |
|||
|
|||
public string Input |
|||
{ |
|||
get { return m_input; } |
|||
} |
|||
|
|||
#endregion Input PROPERTY
|
|||
|
|||
|
|||
#region AutoCompleteStartPosition PROPERTY
|
|||
|
|||
private int m_autoCompleteStartPosition; |
|||
|
|||
public int AutoCompleteStartPosition |
|||
{ |
|||
get { return m_autoCompleteStartPosition; } |
|||
set { m_autoCompleteStartPosition = value; } |
|||
} |
|||
|
|||
#endregion AutoCompleteStartPosition PROPERTY
|
|||
|
|||
#region AutoCompleteText PROPERTY
|
|||
|
|||
private string m_autoCompleteText; |
|||
|
|||
public string AutoCompleteText |
|||
{ |
|||
get { return m_autoCompleteText; } |
|||
set { m_autoCompleteText = value; } |
|||
} |
|||
|
|||
#endregion AutoCompleteText PROPERTY
|
|||
} |
|||
} |
|||
@ -1,29 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public enum InsertKeyMode |
|||
{ |
|||
Default = 0, |
|||
Insert = 1, |
|||
Overwrite = 2 |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
public enum MaskFormat |
|||
{ |
|||
ExcludePromptAndLiterals, |
|||
IncludeLiterals, |
|||
IncludePrompt, |
|||
IncludePromptAndLiterals |
|||
} |
|||
} |
|||
|
Before Width: | Height: | Size: 822 B |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 822 B |
@ -1,27 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
namespace Xceed.Wpf.Toolkit |
|||
{ |
|||
internal static partial class VisualStates |
|||
{ |
|||
public const string MessageBoxButtonsGroup = "MessageBoxButtonsGroup"; |
|||
public const string OK = "OK"; |
|||
public const string OKCancel = "OKCancel"; |
|||
public const string YesNo = "YesNo"; |
|||
public const string YesNoCancel = "YesNoCancel"; |
|||
} |
|||
} |
|||
@ -1,238 +0,0 @@ |
|||
<!--*********************************************************************************** |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md |
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ |
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids |
|||
|
|||
**********************************************************************************--> |
|||
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit" |
|||
xmlns:prim="clr-namespace:Xceed.Wpf.Toolkit.Primitives"> |
|||
|
|||
<ResourceDictionary.MergedDictionaries> |
|||
<ResourceDictionary Source="../../Themes/Aero2/Common.xaml" /> |
|||
<ResourceDictionary Source="../../Primitives/Themes/Aero2/WindowControl.xaml" /> |
|||
</ResourceDictionary.MergedDictionaries> |
|||
|
|||
<!-- =============================================================================== --> |
|||
<!-- MessageBox --> |
|||
<!-- =============================================================================== --> |
|||
|
|||
<ControlTemplate x:Key="MessageBoxTemplate" |
|||
TargetType="{x:Type local:MessageBox}"> |
|||
<Grid> |
|||
<VisualStateManager.VisualStateGroups> |
|||
<VisualStateGroup x:Name="group1"> |
|||
<VisualState x:Name="OK"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="OKCancel"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="YesNo"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="YesNoCancel"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
</VisualStateGroup> |
|||
</VisualStateManager.VisualStateGroups> |
|||
|
|||
<prim:WindowControl x:Name="PART_WindowControl" |
|||
Caption="{TemplateBinding Caption}" |
|||
CaptionFontSize="{TemplateBinding CaptionFontSize}" |
|||
CaptionForeground="{TemplateBinding CaptionForeground}" |
|||
CaptionShadowBrush="{TemplateBinding CaptionShadowBrush}" |
|||
CaptionIcon="{TemplateBinding CaptionIcon}" |
|||
Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
IsActive="{TemplateBinding IsActive}" |
|||
WindowBackground="{TemplateBinding WindowBackground}" |
|||
WindowInactiveBackground="{TemplateBinding WindowInactiveBackground}" |
|||
WindowBorderBrush="{TemplateBinding WindowBorderBrush}" |
|||
WindowBorderThickness="{TemplateBinding WindowBorderThickness}" |
|||
CloseButtonStyle="{TemplateBinding CloseButtonStyle}" |
|||
WindowOpacity="{TemplateBinding WindowOpacity}"> |
|||
<prim:WindowControl.Content> |
|||
<Grid MinWidth="350"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition /> |
|||
<RowDefinition Height="Auto" /> |
|||
</Grid.RowDefinitions> |
|||
|
|||
<Grid Margin="24,16,24,22"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="*" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<!-- Message Image --> |
|||
<Image x:Name="MessageBoxImage" |
|||
VerticalAlignment="Top" |
|||
SnapsToDevicePixels="True" |
|||
Stretch="None" |
|||
Source="{TemplateBinding ImageSource}"> |
|||
</Image> |
|||
|
|||
<!-- Message Text --> |
|||
<ScrollViewer Grid.Column="1" |
|||
VerticalScrollBarVisibility="Auto"> |
|||
<TextBlock x:Name="MessageText" |
|||
TextWrapping="Wrap" |
|||
VerticalAlignment="Center" |
|||
MaxWidth="450" |
|||
Text="{TemplateBinding Text}" |
|||
FontFamily="{TemplateBinding FontFamily}" |
|||
FontSize="{TemplateBinding FontSize}" |
|||
FontStyle="{TemplateBinding FontStyle}" |
|||
FontWeight="{TemplateBinding FontWeight}" |
|||
Foreground="{TemplateBinding Foreground}" |
|||
Margin="10,0,0,0" /> |
|||
</ScrollViewer> |
|||
</Grid> |
|||
|
|||
<!-- Buttons --> |
|||
<Border Grid.Row="1" |
|||
Background="{TemplateBinding ButtonRegionBackground}"> |
|||
<Grid HorizontalAlignment="Right" |
|||
Margin="12"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<Button Grid.Column="0" |
|||
x:Name="PART_YesButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding YesButtonContent}" |
|||
Style="{TemplateBinding YesButtonStyle}" /> |
|||
<Button Grid.Column="1" |
|||
x:Name="PART_NoButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding NoButtonContent}" |
|||
Style="{TemplateBinding NoButtonStyle}" /> |
|||
<Button Grid.Column="2" |
|||
x:Name="PART_OkButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding OkButtonContent}" |
|||
Style="{TemplateBinding OkButtonStyle}" /> |
|||
<Button Grid.Column="3" |
|||
x:Name="PART_CancelButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding CancelButtonContent}" |
|||
Style="{TemplateBinding CancelButtonStyle}" |
|||
IsCancel="True" /> |
|||
</Grid> |
|||
</Border> |
|||
</Grid> |
|||
</prim:WindowControl.Content> |
|||
</prim:WindowControl> |
|||
</Grid> |
|||
</ControlTemplate> |
|||
|
|||
<Style TargetType="{x:Type local:MessageBox}" |
|||
BasedOn="{StaticResource {x:Type prim:WindowControl}}"> |
|||
<Setter Property="ButtonRegionBackground" |
|||
Value="#FFF0F0F0" /> |
|||
<Setter Property="Focusable" |
|||
Value="False" /> |
|||
<Setter Property="MinWidth" |
|||
Value="350" /> |
|||
<Setter Property="MinHeight" |
|||
Value="50" /> |
|||
<Setter Property="MaxHeight" |
|||
Value="250" /> |
|||
<Setter Property="Template" |
|||
Value="{StaticResource MessageBoxTemplate}" /> |
|||
</Style> |
|||
|
|||
</ResourceDictionary> |
|||
@ -1,238 +0,0 @@ |
|||
<!--*********************************************************************************** |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md |
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/ |
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids |
|||
|
|||
**********************************************************************************--> |
|||
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit" |
|||
xmlns:prim="clr-namespace:Xceed.Wpf.Toolkit.Primitives"> |
|||
|
|||
<ResourceDictionary.MergedDictionaries> |
|||
<ResourceDictionary Source="../../Themes/Generic/Common.xaml" /> |
|||
<ResourceDictionary Source="../../Primitives/Themes/Generic/WindowControl.xaml" /> |
|||
</ResourceDictionary.MergedDictionaries> |
|||
|
|||
<!-- =============================================================================== --> |
|||
<!-- MessageBox --> |
|||
<!-- =============================================================================== --> |
|||
|
|||
<Style TargetType="{x:Type local:MessageBox}" |
|||
BasedOn="{StaticResource {x:Type prim:WindowControl}}"> |
|||
<Setter Property="ButtonRegionBackground" |
|||
Value="#FFF0F0F0" /> |
|||
<Setter Property="Focusable" |
|||
Value="False" /> |
|||
<Setter Property="MinWidth" |
|||
Value="350" /> |
|||
<Setter Property="MinHeight" |
|||
Value="50" /> |
|||
<Setter Property="MaxHeight" |
|||
Value="250" /> |
|||
<Setter Property="Template"> |
|||
<Setter.Value> |
|||
<ControlTemplate TargetType="{x:Type local:MessageBox}"> |
|||
<Grid> |
|||
<VisualStateManager.VisualStateGroups> |
|||
<VisualStateGroup x:Name="group1"> |
|||
<VisualState x:Name="OK"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="OKCancel"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="YesNo"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
<VisualState x:Name="YesNoCancel"> |
|||
<Storyboard> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" |
|||
Storyboard.TargetProperty="Visibility"> |
|||
<DiscreteObjectKeyFrame KeyTime="0"> |
|||
<DiscreteObjectKeyFrame.Value> |
|||
<Visibility>Visible</Visibility> |
|||
</DiscreteObjectKeyFrame.Value> |
|||
</DiscreteObjectKeyFrame> |
|||
</ObjectAnimationUsingKeyFrames> |
|||
</Storyboard> |
|||
</VisualState> |
|||
</VisualStateGroup> |
|||
</VisualStateManager.VisualStateGroups> |
|||
|
|||
<prim:WindowControl x:Name="PART_WindowControl" |
|||
Caption="{TemplateBinding Caption}" |
|||
CaptionFontSize="{TemplateBinding CaptionFontSize}" |
|||
CaptionForeground="{TemplateBinding CaptionForeground}" |
|||
CaptionShadowBrush="{TemplateBinding CaptionShadowBrush}" |
|||
CaptionIcon="{TemplateBinding CaptionIcon}" |
|||
Background="{TemplateBinding Background}" |
|||
BorderBrush="{TemplateBinding BorderBrush}" |
|||
BorderThickness="{TemplateBinding BorderThickness}" |
|||
IsActive="{TemplateBinding IsActive}" |
|||
WindowBackground="{TemplateBinding WindowBackground}" |
|||
WindowInactiveBackground="{TemplateBinding WindowInactiveBackground}" |
|||
WindowBorderBrush="{TemplateBinding WindowBorderBrush}" |
|||
WindowBorderThickness="{TemplateBinding WindowBorderThickness}" |
|||
CloseButtonStyle="{TemplateBinding CloseButtonStyle}" |
|||
WindowOpacity="{TemplateBinding WindowOpacity}"> |
|||
<prim:WindowControl.Content> |
|||
<Grid MinWidth="350"> |
|||
<Grid.RowDefinitions> |
|||
<RowDefinition /> |
|||
<RowDefinition Height="Auto" /> |
|||
</Grid.RowDefinitions> |
|||
|
|||
<Grid Margin="24,16,24,22"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="*" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<!-- Message Image --> |
|||
<Image x:Name="MessageBoxImage" |
|||
VerticalAlignment="Top" |
|||
SnapsToDevicePixels="True" |
|||
Stretch="None" |
|||
Source="{TemplateBinding ImageSource}" > |
|||
</Image> |
|||
|
|||
<!-- Message Text --> |
|||
<ScrollViewer Grid.Column="1" |
|||
VerticalScrollBarVisibility="Auto"> |
|||
<TextBlock x:Name="MessageText" |
|||
TextWrapping="Wrap" |
|||
VerticalAlignment="Center" |
|||
MaxWidth="450" |
|||
Text="{TemplateBinding Text}" |
|||
FontFamily="{TemplateBinding FontFamily}" |
|||
FontSize="{TemplateBinding FontSize}" |
|||
FontStyle="{TemplateBinding FontStyle}" |
|||
FontWeight="{TemplateBinding FontWeight}" |
|||
Foreground="{TemplateBinding Foreground}" |
|||
Margin="10,0,0,0" /> |
|||
</ScrollViewer> |
|||
</Grid> |
|||
|
|||
<!-- Buttons --> |
|||
<Border Grid.Row="1" |
|||
Background="{TemplateBinding ButtonRegionBackground}"> |
|||
<Grid HorizontalAlignment="Right" |
|||
Margin="12"> |
|||
<Grid.ColumnDefinitions> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
<ColumnDefinition Width="Auto" /> |
|||
</Grid.ColumnDefinitions> |
|||
|
|||
<Button Grid.Column="0" |
|||
x:Name="PART_YesButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding YesButtonContent}" |
|||
Style="{TemplateBinding YesButtonStyle}" /> |
|||
<Button Grid.Column="1" |
|||
x:Name="PART_NoButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding NoButtonContent}" |
|||
Style="{TemplateBinding NoButtonStyle}" /> |
|||
<Button Grid.Column="2" |
|||
x:Name="PART_OkButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding OkButtonContent}" |
|||
Style="{TemplateBinding OkButtonStyle}" /> |
|||
<Button Grid.Column="3" |
|||
x:Name="PART_CancelButton" |
|||
MinWidth="65" |
|||
Margin="6,0,0,0" |
|||
Visibility="Collapsed" |
|||
Content="{TemplateBinding CancelButtonContent}" |
|||
Style="{TemplateBinding CancelButtonStyle}" |
|||
IsCancel="True" /> |
|||
</Grid> |
|||
</Border> |
|||
</Grid> |
|||
</prim:WindowControl.Content> |
|||
</prim:WindowControl> |
|||
</Grid> |
|||
</ControlTemplate> |
|||
</Setter.Value> |
|||
</Setter> |
|||
</Style> |
|||
|
|||
</ResourceDictionary> |
|||
|
Before Width: | Height: | Size: 156 B |
|
Before Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 794 B |
|
Before Width: | Height: | Size: 201 B |
|
Before Width: | Height: | Size: 205 B |
|
Before Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 340 B |
|
Before Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 303 B |
@ -1,76 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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
|
|||
} |
|||
} |
|||
|
|||
@ -1,39 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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
|
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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
|
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 != null) && !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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,238 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
|
|||
internal bool IsCleaning |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public virtual void ClearHelper() |
|||
{ |
|||
this.IsCleaning = true; |
|||
|
|||
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(); |
|||
} |
|||
this.IsCleaning = false; |
|||
} |
|||
|
|||
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 ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,52 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,36 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,40 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,105 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,43 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,87 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Globalization; |
|||
using System.Windows; |
|||
using System.Windows.Controls.Primitives; |
|||
using System.Windows.Data; |
|||
|
|||
namespace Xceed.Wpf.Toolkit.PropertyGrid.Converters |
|||
{ |
|||
public class PropertyItemEditorConverter : IMultiValueConverter |
|||
{ |
|||
public object Convert( object[] values, Type targetType, object parameter, CultureInfo culture ) |
|||
{ |
|||
if( ( values == null ) || ( values.Length != 2 ) ) |
|||
return null; |
|||
|
|||
var editor = values[ 0 ]; |
|||
var isReadOnly = values[ 1 ] as bool?; |
|||
|
|||
if( ( editor == null ) || !isReadOnly.HasValue ) |
|||
return editor; |
|||
|
|||
// Get Editor.IsReadOnly
|
|||
var editorType = editor.GetType(); |
|||
var editorIsReadOnlyPropertyInfo = editorType.GetProperty( "IsReadOnly" ); |
|||
if( editorIsReadOnlyPropertyInfo != null ) |
|||
{ |
|||
if( !this.IsPropertySetLocally( editor, TextBoxBase.IsReadOnlyProperty ) ) |
|||
{ |
|||
// Set Editor.IsReadOnly to PropertyGrid.IsReadOnly.
|
|||
editorIsReadOnlyPropertyInfo.SetValue( editor, isReadOnly, null ); |
|||
} |
|||
} |
|||
// No Editor.IsReadOnly property, set the Editor.IsEnabled property.
|
|||
else |
|||
{ |
|||
var editorIsEnabledPropertyInfo = editorType.GetProperty( "IsEnabled" ); |
|||
if( editorIsEnabledPropertyInfo != null ) |
|||
{ |
|||
if( !this.IsPropertySetLocally( editor, UIElement.IsEnabledProperty ) ) |
|||
{ |
|||
// Set Editor.IsEnabled to !PropertyGrid.IsReadOnly.
|
|||
editorIsEnabledPropertyInfo.SetValue( editor, !isReadOnly, null ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return editor; |
|||
} |
|||
|
|||
public object[] ConvertBack( object value, Type[] targetTypes, object parameter, CultureInfo culture ) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
private bool IsPropertySetLocally( object editor, DependencyProperty dp ) |
|||
{ |
|||
if( dp == null ) |
|||
return false; |
|||
|
|||
var editorObject = editor as DependencyObject; |
|||
if( editorObject == null ) |
|||
return false; |
|||
|
|||
var valueSource = DependencyPropertyHelper.GetValueSource( editorObject, dp ); |
|||
if( valueSource == null ) |
|||
return false; |
|||
|
|||
return ( valueSource.BaseValueSource == BaseValueSource.Local ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,116 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
|
|||
//ICustomTypeProvider is only available in .net 4.5 and over. Use reflection so the .net 4.0 and .net 3.5 still works.
|
|||
if( newType.GetInterface( "ICustomTypeProvider", true ) != null ) |
|||
{ |
|||
var methodInfo = newType.GetMethod( "GetCustomType" ); |
|||
newType = methodInfo.Invoke( value, null ) as Type; |
|||
} |
|||
|
|||
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
|
|||
} |
|||
} |
|||
@ -1,182 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) |
|||
{ |
|||
_isPropertyGridCategorized = isPropertyGridCategorized; |
|||
_isSortedAlphabetically = 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; |
|||
} |
|||
|
|||
//case 166547 : Do not overwrite a custom Editor's DataContext set by the user.
|
|||
if( ( newValue != null ) && ( newValue.DataContext == null ) ) |
|||
{ |
|||
newValue.DataContext = this; |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -1,64 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,113 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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
|
|||
} |
|||
} |
|||
@ -1,267 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
#if !VS2008
|
|||
using System.ComponentModel.DataAnnotations; |
|||
#endif
|
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors; |
|||
using System.Globalization; |
|||
|
|||
namespace Xceed.Wpf.Toolkit.PropertyGrid |
|||
{ |
|||
internal class DescriptorPropertyDefinition : DescriptorPropertyDefinitionBase |
|||
{ |
|||
#region Members
|
|||
|
|||
private object _selectedObject; |
|||
private PropertyDescriptor _propertyDescriptor; |
|||
private DependencyPropertyDescriptor _dpDescriptor; |
|||
private static Dictionary<string, Type> _dictEditorTypeName = new Dictionary<string, Type>(); |
|||
|
|||
#endregion
|
|||
|
|||
#region Constructor
|
|||
|
|||
internal DescriptorPropertyDefinition( PropertyDescriptor propertyDescriptor, object selectedObject, IPropertyContainer propertyContainer ) |
|||
: base( propertyContainer.IsCategorized |
|||
) |
|||
{ |
|||
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() |
|||
{ |
|||
if( !PropertyDescriptor.IsReadOnly ) |
|||
{ |
|||
var defaultValue = this.ComputeDefaultValueAttribute(); |
|||
if( defaultValue != null) |
|||
return !defaultValue.Equals( this.Value ); // can Reset if different from defaultValue.
|
|||
|
|||
return PropertyDescriptor.CanResetValue( SelectedObject ); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
protected override object ComputeAdvancedOptionsTooltip() |
|||
{ |
|||
object tooltip; |
|||
UpdateAdvanceOptionsForItem( 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 object ComputeDefaultValueAttribute() |
|||
{ |
|||
return this.ComputeDefaultValueAttributeForItem( 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() |
|||
{ |
|||
this.PropertyDescriptor.ResetValue( this.SelectedObject ); |
|||
base.ResetValue(); |
|||
} |
|||
|
|||
internal override ITypeEditor CreateAttributeEditor() |
|||
{ |
|||
var editorAttribute = GetAttribute<EditorAttribute>(); |
|||
if( editorAttribute != null ) |
|||
{ |
|||
Type type = null; |
|||
if( !_dictEditorTypeName.TryGetValue( editorAttribute.EditorTypeName, out type ) ) |
|||
{ |
|||
#if VS2008
|
|||
type = Type.GetType( editorAttribute.EditorTypeName ); |
|||
#else
|
|||
try |
|||
{ |
|||
var typeDef = editorAttribute.EditorTypeName.Split( new char[] { ',' } ); |
|||
if( typeDef.Length >= 2 ) |
|||
{ |
|||
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault( a => a.FullName.Contains( typeDef[ 1 ].Trim() ) ); |
|||
if( assembly != null ) |
|||
{ |
|||
type = assembly.GetTypes().FirstOrDefault( t => (t != null) && (t.FullName != null) && t.FullName.Contains( typeDef[ 0 ] ) ); |
|||
} |
|||
} |
|||
} |
|||
catch( Exception ) |
|||
{ |
|||
} |
|||
#endif
|
|||
if( type == null ) |
|||
{ |
|||
type = Type.GetType( editorAttribute.EditorTypeName ); |
|||
} |
|||
_dictEditorTypeName.Add( editorAttribute.EditorTypeName, type ); |
|||
} |
|||
|
|||
// 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 ); |
|||
} |
|||
|
|||
#endregion //Private Methods
|
|||
|
|||
} |
|||
} |
|||
@ -1,693 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Windows; |
|||
using System.Windows.Input; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Commands; |
|||
using System.Windows.Media; |
|||
using Xceed.Wpf.Toolkit.PropertyGrid.Editors; |
|||
using System.Diagnostics; |
|||
using System.ComponentModel; |
|||
using System.Windows.Markup.Primitives; |
|||
using System.Windows.Data; |
|||
#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 object _defaultValue; |
|||
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 virtual object ComputeDefaultValueAttribute() |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
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() |
|||
{ |
|||
var binding = BindingOperations.GetBindingExpressionBase( this, DescriptorPropertyDefinition.ValueProperty ); |
|||
if( binding != null ) |
|||
{ |
|||
binding.UpdateTarget(); |
|||
} |
|||
} |
|||
|
|||
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( DependencyObject dependencyObject, DependencyPropertyDescriptor dpDescriptor, out object tooltip ) |
|||
{ |
|||
tooltip = StringConstants.Default; |
|||
|
|||
bool isResource = false; |
|||
bool isDynamicResource = false; |
|||
|
|||
//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( this.PropertyType ); |
|||
isDynamicResource = typeof( DynamicResourceExtension ).IsAssignableFrom( this.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; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// When the Value is diferent from the DefaultValue, use the local icon.
|
|||
if( !object.Equals( this.Value, this.DefaultValue ) ) |
|||
{ |
|||
if( this.DefaultValue != null ) |
|||
{ |
|||
tooltip = StringConstants.Local; |
|||
} |
|||
else |
|||
{ |
|||
if( this.PropertyType.IsValueType ) |
|||
{ |
|||
var defaultValue = Activator.CreateInstance( this.PropertyType ); |
|||
// When the Value is diferent from the DefaultValue, use the local icon.
|
|||
if( !object.Equals( this.Value, defaultValue ) ) |
|||
{ |
|||
tooltip = StringConstants.Local; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// When the Value is diferent from null, use the local icon.
|
|||
if( this.Value != null ) |
|||
{ |
|||
tooltip = StringConstants.Local; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
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.ComputeIsExpandable() |
|||
&& ( this.ExpandableAttribute |
|||
); |
|||
} |
|||
|
|||
internal void UpdateValueFromSource() |
|||
{ |
|||
var bindingExpr = BindingOperations.GetBindingExpressionBase( this, DescriptorPropertyDefinitionBase.ValueProperty ); |
|||
if( bindingExpr != null ) |
|||
{ |
|||
bindingExpr.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; |
|||
} |
|||
|
|||
internal object ComputeDefaultValueAttributeForItem( object item ) |
|||
{ |
|||
var pd = ( PropertyDescriptor )item; |
|||
|
|||
var defaultValue = PropertyGridUtilities.GetAttribute<DefaultValueAttribute>( pd ); |
|||
return ( defaultValue != null ) ? defaultValue.Value : null; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Private Methods
|
|||
|
|||
private static void ExecuteResetValueCommand( object sender, ExecutedRoutedEventArgs e ) |
|||
{ |
|||
var affectedPropertyItem = e.Parameter as PropertyItem; |
|||
if( affectedPropertyItem == null ) |
|||
{ |
|||
affectedPropertyItem = sender as PropertyItem; |
|||
} |
|||
|
|||
if( ( affectedPropertyItem != null ) && ( affectedPropertyItem.DescriptorDefinition != null ) ) |
|||
{ |
|||
if( affectedPropertyItem.DescriptorDefinition.ComputeCanResetValue() ) |
|||
{ |
|||
affectedPropertyItem.DescriptorDefinition.ResetValue(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void CanExecuteResetValueCommand( object sender, CanExecuteRoutedEventArgs e ) |
|||
{ |
|||
var affectedPropertyItem = e.Parameter as PropertyItem; |
|||
if( affectedPropertyItem == null ) |
|||
{ |
|||
affectedPropertyItem = sender as PropertyItem; |
|||
} |
|||
|
|||
e.CanExecute = ( (affectedPropertyItem != null) && ( affectedPropertyItem.DescriptorDefinition != null) ) |
|||
? affectedPropertyItem.DescriptorDefinition.ComputeCanResetValue() |
|||
: false; |
|||
} |
|||
|
|||
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 object DefaultValue |
|||
{ |
|||
get |
|||
{ |
|||
return _defaultValue; |
|||
} |
|||
set |
|||
{ |
|||
_defaultValue = 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(); |
|||
_defaultValue = ComputeDefaultValueAttribute(); |
|||
_displayOrder = ComputeDisplayOrder( this.IsPropertyGridCategorized ); |
|||
_expandableAttribute = ComputeExpandableAttribute(); |
|||
|
|||
|
|||
_newItemTypes = ComputeNewItemTypes(); |
|||
_commandBindings = new CommandBinding[] { new CommandBinding( PropertyItemCommands.ResetValue, ExecuteResetValueCommand, CanExecuteResetValueCommand ) }; |
|||
|
|||
|
|||
BindingBase valueBinding = this.CreateValueBinding(); |
|||
BindingOperations.SetBinding( this, DescriptorPropertyDefinitionBase.ValueProperty, valueBinding ); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -1,100 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,112 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 CollectionControlButton CreateEditor() |
|||
{ |
|||
return new PropertyGridEditorCollectionControl(); |
|||
} |
|||
|
|||
protected override void SetControlProperties( PropertyItem propertyItem ) |
|||
{ |
|||
|
|||
var propertyGrid = propertyItem.ParentElement as PropertyGrid; |
|||
if( propertyGrid != null ) |
|||
{ |
|||
// Use the PropertyGrid.EditorDefinitions for the CollectionControl's propertyGrid.
|
|||
this.Editor.EditorDefinitions = propertyGrid.EditorDefinitions; |
|||
} |
|||
} |
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,59 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,42 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
} |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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"; |
|||
if( propertyItem != null ) |
|||
{ |
|||
Editor.IsEnabled = !propertyItem.IsReadOnly; |
|||
} |
|||
} |
|||
|
|||
private void SetItemsSource() |
|||
{ |
|||
Editor.ItemsSource = CreateItemsSource(); |
|||
} |
|||
|
|||
private System.Collections.IEnumerable CreateItemsSource() |
|||
{ |
|||
var instance = Activator.CreateInstance( _attribute.Type ); |
|||
return ( instance as IItemsSource ).GetValues(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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.Editors |
|||
{ |
|||
public class MaskedTextBoxEditor : TypeEditor<MaskedTextBox> |
|||
{ |
|||
public string Mask |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
public Type ValueDataType |
|||
{ |
|||
get; |
|||
set; |
|||
} |
|||
|
|||
protected override MaskedTextBox CreateEditor() |
|||
{ |
|||
return new PropertyGridEditorMaskedTextBox(); |
|||
} |
|||
|
|||
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; |
|||
} |
|||
} |
|||
|
|||
public class PropertyGridEditorMaskedTextBox : MaskedTextBox |
|||
{ |
|||
static PropertyGridEditorMaskedTextBox() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorMaskedTextBox ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorMaskedTextBox ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 PrimitiveTypeCollectionControl CreateEditor() |
|||
{ |
|||
return new PropertyGridEditorPrimitiveTypeCollectionControl(); |
|||
} |
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,79 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -1,48 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
Editor.TextTrimming = TextTrimming.CharacterEllipsis; |
|||
} |
|||
} |
|||
|
|||
public class PropertyGridEditorTextBlock : TextBlock |
|||
{ |
|||
static PropertyGridEditorTextBlock() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorTextBlock ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorTextBlock ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) ) ); |
|||
} |
|||
} |
|||
} |
|||
@ -1,84 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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
|
|||
} |
|||
} |
|||
@ -1,389 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using Xceed.Wpf.Toolkit.Primitives; |
|||
using System; |
|||
using System.Windows; |
|||
using System.Windows.Data; |
|||
#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 NumericUpDownEditor<TEditor, TType> : UpDownEditor<TEditor, TType> where TEditor : UpDownBase<TType>, new() |
|||
{ |
|||
protected override void SetControlProperties( PropertyItem propertyItem ) |
|||
{ |
|||
base.SetControlProperties( propertyItem ); |
|||
|
|||
var binding = new Binding( "IsInvalid" ); |
|||
binding.Source = this.Editor; |
|||
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; |
|||
binding.Mode = BindingMode.TwoWay; |
|||
BindingOperations.SetBinding( propertyItem, PropertyItem.IsInvalidProperty, binding ); |
|||
} |
|||
} |
|||
|
|||
public class ByteUpDownEditor : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 : NumericUpDownEditor<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 ) ) ); |
|||
} |
|||
} |
|||
|
|||
[CLSCompliantAttribute( false )] |
|||
public class PropertyGridEditorSByteUpDown : SByteUpDown |
|||
{ |
|||
static PropertyGridEditorSByteUpDown() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorSByteUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorSByteUpDown ) ) ); |
|||
} |
|||
} |
|||
|
|||
[CLSCompliantAttribute( false )] |
|||
public class PropertyGridEditorUIntegerUpDown : UIntegerUpDown |
|||
{ |
|||
static PropertyGridEditorUIntegerUpDown() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorUIntegerUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorUIntegerUpDown ) ) ); |
|||
} |
|||
} |
|||
|
|||
[CLSCompliantAttribute( false )] |
|||
public class PropertyGridEditorULongUpDown : ULongUpDown |
|||
{ |
|||
static PropertyGridEditorULongUpDown() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorULongUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorULongUpDown ) ) ); |
|||
} |
|||
} |
|||
|
|||
[CLSCompliantAttribute( false )] |
|||
public class PropertyGridEditorUShortUpDown : UShortUpDown |
|||
{ |
|||
static PropertyGridEditorUShortUpDown() |
|||
{ |
|||
DefaultStyleKeyProperty.OverrideMetadata( typeof( PropertyGridEditorUShortUpDown ), new FrameworkPropertyMetadata( typeof( PropertyGridEditorUShortUpDown ) ) ); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,29 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
@ -1,57 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
|
|||
} |
|||
} |
|||
@ -1,168 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 void GenerateSubPropertiesCore( Action<IEnumerable<PropertyItem>> updatePropertyItemsCallback ) |
|||
{ |
|||
var propertyItems = new List<PropertyItem>(); |
|||
|
|||
if( SelectedObject != null ) |
|||
{ |
|||
try |
|||
{ |
|||
var 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 ); |
|||
} |
|||
} |
|||
|
|||
updatePropertyItemsCallback.Invoke( propertyItems ); |
|||
} |
|||
|
|||
|
|||
private PropertyItem CreatePropertyItem( PropertyDescriptor property, PropertyDefinition propertyDef ) |
|||
{ |
|||
DescriptorPropertyDefinition definition = new DescriptorPropertyDefinition( property, SelectedObject, this.PropertyContainer ); |
|||
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; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
} |
|||
} |
|||
@ -1,565 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
using System.Windows.Controls; |
|||
|
|||
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 = this.PropertyContainer.FilterInfo; |
|||
|
|||
this.PropertyItems.FilterPredicate = filterInfo.Predicate |
|||
?? PropertyItemCollection.CreateFilter( filterInfo.InputString, this.PropertyItems, this.PropertyContainer ); |
|||
} |
|||
|
|||
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 void GenerateSubPropertiesCore( Action<IEnumerable<PropertyItem>> updatePropertyItemsCallback ); |
|||
|
|||
private void RegenerateProperties() |
|||
{ |
|||
this.GenerateSubPropertiesCore( this.UpdatePropertyItemsCallback ); |
|||
} |
|||
|
|||
protected internal virtual void UpdatePropertyItemsCallback( IEnumerable<PropertyItem> subProperties ) |
|||
{ |
|||
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; |
|||
} |
|||
|
|||
if( ObjectsGenerated != null ) |
|||
{ |
|||
ObjectsGenerated( this, EventArgs.Empty ); |
|||
} |
|||
} |
|||
|
|||
protected static List<PropertyDescriptor> GetPropertyDescriptors( object instance, bool hideInheritedProperties ) |
|||
{ |
|||
PropertyDescriptorCollection descriptors = null; |
|||
|
|||
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 |
|||
{ |
|||
try |
|||
{ |
|||
descriptors = tc.GetProperties( instance ); |
|||
} |
|||
catch( Exception ) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
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 object GetTypeDefaultValue( Type type ) |
|||
{ |
|||
if( type.IsGenericType && type.GetGenericTypeDefinition() == typeof( Nullable<> ) ) |
|||
{ |
|||
type = type.GetProperty( "Value" ).PropertyType; |
|||
} |
|||
|
|||
return ( type.IsValueType ? Activator.CreateInstance( type ) : null ) ; |
|||
} |
|||
|
|||
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) && ( propertyItem.PropertyDescriptor != null ) ) |
|||
editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyDescriptor.Name, propertyItem ); |
|||
|
|||
if( editorElement == null && definitionKeyAsType == null ) |
|||
editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyType, propertyItem ); |
|||
|
|||
if( editorElement == null ) |
|||
{ |
|||
if( propertyItem.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 ); |
|||
} |
|||
|
|||
internal event EventHandler ObjectsGenerated; |
|||
} |
|||
} |
|||
@ -1,122 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,124 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ); |
|||
} |
|||
} |
|||
} |
|||
|
Before Width: | Height: | Size: 822 B |
@ -1,211 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 ) |
|||
&& !( typeConverter is ReferenceConverter ) |
|||
&& (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
|
|||
} |
|||
} |
|||
@ -1,335 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
using System.Globalization; |
|||
|
|||
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, OnIsReadOnlyChanged ) ); |
|||
|
|||
public bool IsReadOnly |
|||
{ |
|||
get { return ( bool )GetValue( IsReadOnlyProperty ); } |
|||
set { SetValue( IsReadOnlyProperty, value ); } |
|||
} |
|||
|
|||
private static void OnIsReadOnlyChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
var propertyItem = o as PropertyItem; |
|||
if( propertyItem != null ) |
|||
propertyItem.OnIsReadOnlyChanged( (bool)e.OldValue, (bool)e.NewValue ); |
|||
} |
|||
|
|||
protected virtual void OnIsReadOnlyChanged( bool oldValue, bool newValue ) |
|||
{ |
|||
if( this.IsLoaded ) |
|||
{ |
|||
this.RebuildEditor(); |
|||
} |
|||
} |
|||
|
|||
|
|||
#endregion //IsReadOnly
|
|||
|
|||
#region IsInValid
|
|||
|
|||
/// <summary>
|
|||
/// Identifies the IsInvalid dependency property
|
|||
/// </summary>
|
|||
public static readonly DependencyProperty IsInvalidProperty = |
|||
DependencyProperty.Register( "IsInvalid", typeof( bool ), typeof( PropertyItem ), new UIPropertyMetadata( false, OnIsInvalidChanged ) ); |
|||
|
|||
public bool IsInvalid |
|||
{ |
|||
get |
|||
{ |
|||
return ( bool )GetValue( IsInvalidProperty ); |
|||
} |
|||
internal set |
|||
{ |
|||
SetValue( IsInvalidProperty, value ); |
|||
} |
|||
} |
|||
|
|||
private static void OnIsInvalidChanged( DependencyObject o, DependencyPropertyChangedEventArgs e ) |
|||
{ |
|||
var propertyItem = o as PropertyItem; |
|||
if( propertyItem != null ) |
|||
propertyItem.OnIsInvalidChanged( ( bool )e.OldValue, ( bool )e.NewValue ); |
|||
} |
|||
|
|||
protected virtual void OnIsInvalidChanged( bool oldValue, bool newValue ) |
|||
{ |
|||
var be = this.GetBindingExpression( PropertyItem.ValueProperty ); |
|||
|
|||
if( newValue ) |
|||
{ |
|||
var validationError = new ValidationError( new InvalidValueValidationRule(), be ); |
|||
validationError.ErrorContent = "Value could not be converted."; |
|||
Validation.MarkInvalid( be, validationError ); |
|||
} |
|||
else |
|||
{ |
|||
Validation.ClearInvalid( be ); |
|||
} |
|||
} |
|||
|
|||
|
|||
#endregion // IsInvalid
|
|||
|
|||
#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; |
|||
} |
|||
|
|||
protected override void OnIsExpandedChanged( bool oldValue, bool newValue ) |
|||
{ |
|||
if( newValue && this.IsLoaded ) |
|||
{ |
|||
this.GenerateExpandedPropertyItems(); |
|||
} |
|||
} |
|||
|
|||
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 ); |
|||
|
|||
// A Default Value is defined and newValue is null => set the Default Value
|
|||
if( ( newValue == null ) && ( this.DescriptorDefinition != null ) && ( this.DescriptorDefinition.DefaultValue != null ) ) |
|||
{ |
|||
#if VS2008
|
|||
this.Value = this.DescriptorDefinition.DefaultValue; |
|||
#else
|
|||
this.SetCurrentValue( PropertyItem.ValueProperty, this.DescriptorDefinition.DefaultValue ); |
|||
#endif
|
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Internal Methods
|
|||
|
|||
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 ] ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal void RebuildEditor() |
|||
{ |
|||
var objectContainerHelperBase = this.ContainerHelper as ObjectContainerHelperBase; |
|||
//Re-build the editor to update this propertyItem
|
|||
var editor = objectContainerHelperBase.GenerateChildrenEditorElement( this ); |
|||
if( editor != null ) |
|||
{ |
|||
// Tag the editor as generated to know if we should clear it.
|
|||
ContainerHelperBase.SetIsGenerated( editor, true ); |
|||
this.Editor = editor; |
|||
|
|||
//Update Source of binding and Validation of PropertyItem to update
|
|||
var be = this.GetBindingExpression( PropertyItem.ValueProperty ); |
|||
if( be != null ) |
|||
{ |
|||
be.UpdateSource(); |
|||
this.SetRedInvalidBorder( be ); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Private Methods
|
|||
|
|||
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 ); |
|||
this.Loaded += this.PropertyItem_Loaded; |
|||
} |
|||
|
|||
private void GenerateExpandedPropertyItems() |
|||
{ |
|||
if( this.IsExpanded ) |
|||
{ |
|||
// This withholds the generation of all PropertyItem instances (recursively)
|
|||
// until the PropertyItem is expanded.
|
|||
var objectContainerHelper = ContainerHelper as ObjectContainerHelperBase; |
|||
if( objectContainerHelper != null ) |
|||
{ |
|||
objectContainerHelper.GenerateProperties(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Event Handlers
|
|||
|
|||
private void PropertyItem_Loaded( object sender, RoutedEventArgs e ) |
|||
{ |
|||
this.GenerateExpandedPropertyItems(); |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Constructors
|
|||
|
|||
internal PropertyItem( DescriptorPropertyDefinitionBase definition ) |
|||
: base( definition.IsPropertyGridCategorized, !definition.PropertyType.IsArray ) |
|||
{ |
|||
this.Init( definition ); |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
private class InvalidValueValidationRule : ValidationRule |
|||
{ |
|||
public override ValidationResult Validate( object value, CultureInfo cultureInfo ) |
|||
{ |
|||
// Will always return an error.
|
|||
return new ValidationResult( false, null ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,602 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
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; |
|||
|
|||
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 HighlightedText
|
|||
|
|||
public static readonly DependencyProperty HighlightedTextProperty = DependencyProperty.Register( "HighlightedText", typeof( string ), typeof( PropertyItemBase ), new UIPropertyMetadata( null ) ); |
|||
|
|||
public string HighlightedText |
|||
{ |
|||
get |
|||
{ |
|||
return ( string )GetValue( HighlightedTextProperty ); |
|||
} |
|||
set |
|||
{ |
|||
SetValue( HighlightedTextProperty, value ); |
|||
} |
|||
} |
|||
|
|||
#endregion //HighlightedText
|
|||
|
|||
#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 |
|||
{ |
|||
if( _containerHelper == null ) |
|||
{ |
|||
_containerHelper = new ObjectContainerHelper( this, null ); |
|||
} |
|||
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() |
|||
{ |
|||
this.GotFocus += new RoutedEventHandler( PropertyItemBase_GotFocus ); |
|||
this.RequestBringIntoView += this.PropertyItemBase_RequestBringIntoView; |
|||
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; |
|||
} |
|||
|
|||
private void PropertyItemBase_RequestBringIntoView( object sender, RequestBringIntoViewEventArgs e ) |
|||
{ |
|||
e.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.IsLoaded |
|||
&& (_parentNode != null) |
|||
&& !_parentNode.ContainerHelper.IsCleaning) |
|||
{ |
|||
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
|
|||
|
|||
} |
|||
} |
|||
@ -1,227 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
using System.Reflection; |
|||
#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, this.Items, null ); |
|||
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, IList<PropertyItem> PropertyItems, IPropertyContainer propertyContainer ) |
|||
{ |
|||
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
|
|||
property.HighlightedText = property.DisplayName.ToLower().Contains( text.ToLower() ) ? text : null; |
|||
return (property.HighlightedText != null); |
|||
} |
|||
|
|||
return false; |
|||
}; |
|||
} |
|||
else |
|||
{ |
|||
ClearFilterSubItems( PropertyItems.ToList() ); |
|||
} |
|||
|
|||
return filter; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
private static void ClearFilterSubItems( IList items ) |
|||
{ |
|||
foreach( var item in items ) |
|||
{ |
|||
var propertyItem = item as PropertyItemBase; |
|||
if( propertyItem != null ) |
|||
{ |
|||
propertyItem.HighlightedText = null; |
|||
|
|||
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,109 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
|
|||
|
|||
***********************************************************************************/ |
|||
|
|||
using System; |
|||
using System.Windows.Controls; |
|||
using System.Windows; |
|||
using System.ComponentModel; |
|||
|
|||
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 |
|||
{ |
|||
public PropertyItemsControl() |
|||
{ |
|||
var propertyItemsControlProperties = TypeDescriptor.GetProperties( this, new Attribute[] { new PropertyFilterAttribute( PropertyFilterOptions.All ) } ); |
|||
var prop1 = propertyItemsControlProperties.Find( "VirtualizingPanel.IsVirtualizingWhenGrouping", false ); |
|||
if( prop1 != null ) |
|||
{ |
|||
prop1.SetValue( this, true ); |
|||
} |
|||
var prop2 = propertyItemsControlProperties.Find( "VirtualizingPanel.CacheLengthUnit", false ); |
|||
if( prop2 != null ) |
|||
{ |
|||
prop2.SetValue( this, Enum.ToObject( prop2.PropertyType, 1 ) ); |
|||
} |
|||
} |
|||
|
|||
#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 ); |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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 Default |
|||
{ |
|||
get { return "Default"; } |
|||
} |
|||
} |
|||
} |
|||
@ -1,59 +0,0 @@ |
|||
/************************************************************************************* |
|||
|
|||
Toolkit for WPF |
|||
|
|||
Copyright (C) 2007-2019 Xceed Software Inc. |
|||
|
|||
This program is provided to you under the terms of the Microsoft Public |
|||
License (Ms-PL) as published at https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md
|
|||
|
|||
For more features, controls, and fast professional support, |
|||
pick up the Plus Edition at https://xceed.com/xceed-toolkit-plus-for-wpf/
|
|||
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||