http://wpftoolkit.codeplex.com/workitem/18854
Comments: ** Comment from web user: BoucherS **
The PropertyGrid will contain a TimeSpanEditor that supports timeSpan greater than 24h in v2.2.
The PropertyGrid will contain a TimeSpanEditor that supports timeSpan greater than 24h in v2.2.
<Style x:Key="comboItemContanerStyle" TargetType="{x:Type xctk:SelectorItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type xctk:SelectorItem}">
<Border x:Name="_background"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}"
Grid.Column="0"/>
<ContentPresenter Content="{TemplateBinding Content}"
Grid.Column="1"
Margin="5,0,0,0"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="_background" Property="Background" Value="#FFB8E0F3" />
<Setter TargetName="_background" Property="BorderBrush" Value="#FF26A0DA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="WrappingComboTemplate">
<TextBlock Text="{Binding Converter={StaticResource convert}}" />
</DataTemplate>
<xctk:CheckComboBox VerticalAlignment="Bottom"
MaxHeight="50"
Visibility="Collapsed"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemContainerStyle="{StaticResource comboItemContanerStyle}"
ItemTemplate="{StaticResource WrappingComboTemplate}"/>
ContentTemplate="{TemplateBinding ContentTemplate}"
to it. It will do the job.<Window x:Class="WpfApplication88.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:WpfApplication88"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="comboItemContanerStyle"
TargetType="{x:Type xctk:SelectorItem}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type xctk:SelectorItem}">
<Border x:Name="_background"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}"
Grid.Column="0" />
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Grid.Column="1"
Margin="5,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter TargetName="_background"
Property="Background"
Value="#FFB8E0F3" />
<Setter TargetName="_background"
Property="BorderBrush"
Value="#FF26A0DA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<local:MyConverter x:Key="convert" />
<DataTemplate x:Key="WrappingComboTemplate">
<TextBlock Text="{Binding Converter={StaticResource convert}}" />
</DataTemplate>
</Window.Resources>
<Grid>
<xctk:CheckComboBox x:Name="_checkComboBox"
VerticalAlignment="Bottom"
MaxHeight="50"
Visibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemContainerStyle="{StaticResource comboItemContanerStyle}"
ItemTemplate="{StaticResource WrappingComboTemplate}"/>
</Grid>
</Window>
I found how to overcome this bug!
private bool _isMouseDown; //mouse button is pressed
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if( _popup != null )
_popup.Opened -= Popup_Opened;
_popup = GetTemplateChild( PART_Popup ) as Popup;
if( _popup != null )
_popup.Opened += Popup_Opened;
if (_calendar != null)
{
_calendar.SelectedDatesChanged -= Calendar_SelectedDatesChanged;
_calendar.PreviewMouseDown -= Calendar_PreviewMouseDown;
_calendar.PreviewMouseUp -= Calendar_PreviewMouseUp;
}
_calendar = GetTemplateChild( PART_Calendar ) as Calendar;
if( _calendar != null )
{
_calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged;
_calendar.PreviewMouseDown += new MouseButtonEventHandler(Calendar_PreviewMouseDown);
_calendar.PreviewMouseUp += new MouseButtonEventHandler(Calendar_PreviewMouseUp);
_calendar.SelectedDate = Value ?? null;
_calendar.DisplayDate = Value ?? DateTime.Now;
}
_timePicker = GetTemplateChild( PART_TimeUpDown ) as TimePicker;
}
void Calendar_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
_isMouseDown = true;
}
void Calendar_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
_isMouseDown = false;
}
protected override void OnValueChanged( DateTime? oldValue, DateTime? newValue )
{
if( _calendar != null && _calendar.SelectedDate != newValue )
{
_calendar.SelectedDate = newValue;
if (!_isMouseDown) // we do not need to update dispay if mouse is pressed
_calendar.DisplayDate = newValue ?? DateTime.Now;
}
base.OnValueChanged( oldValue, newValue );
}
This issue will be fixed in v2.2.
In XAML :
<Grid>
<xctk:PropertyGrid x:Name="_propertyGrid" />
</Grid>
In Code-Behind :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
_propertyGrid.SelectedObject = new MyTest()
{
EditorFont = new Font()
{
MyFontFamily = new FontFamily("Stencil"),
Size = 13
}
};
}
}
public class MyTest
{
// Property in class
private Font _editorFont;
[Category( "Workspace" ),
Description( "The font used for editing documents." ),
DisplayName( "Editor Font" ),
ExpandableObject()]
public Font EditorFont
{
get
{
return _editorFont;
}
set
{
_editorFont = value;
}
}
}
[TypeConverter(typeof(FontConverter))]
public class Font
{
public FontFamily MyFontFamily
{
get;
set;
}
public int Size
{
get;
set;
}
}
public class FontConverter : TypeConverter
{
public FontConverter()
{
}
public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType )
{
return ( destinationType == typeof( string ) )
|| base.CanConvertTo( context, destinationType );
}
public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )
{
return ( sourceType == typeof( string ) )
|| base.CanConvertFrom( context, sourceType );
}
public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType )
{
if( ( destinationType == typeof( string ) ) )
{
return "My Font";
}
return base.ConvertTo( context, culture, value, destinationType );
}
public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo currentCulture, object value )
{
if( value != null && ( value is string ) )
{
return new Font();
}
return base.ConvertFrom( context, currentCulture, value );
}
}
[Serializable]
public class Preferences
{
private WpFFont _editorFont = new WpFFont(
new FontFamily("Segoe UI"),
9.75F, FontWeights.Normal,
FontStyles.Normal, FontStretches.Normal );
[Category("Editor"),
DisplayName("Font"),
Description("The font used for the editor.")]
public WpFFont EditorFont
{
get { return _editorFont; }
set { _editorFont = value; }
}
}
The custom font class: [Serializable, ExpandableObject]
public class WpFFont
{
private FontFamily _family;
private FontStyle _style;
private FontStretch _stretch;
private FontWeight _weight;
private double _size;
public FontFamily Family
{
get { return _family; }
set { _family = value; }
}
public FontWeight Weight
{
get { return _weight; }
set { _weight = value; }
}
public FontStretch Stretch
{
get { return _stretch; }
set { _stretch = value; }
}
public double FontSize
{
get { return _size; }
set { _size = value; }
}
public FontStyle Style
{
get { return _style; }
set { _style = value; }
}
public WpFFont() { }
public WpFFont( FontFamily family, double fontSize, FontWeight weight, FontStyle style, FontStretch stretch )
{
this.Family = family;
this.FontSize = fontSize;
this.Weight = weight;
this.Style = style;
this.Stretch = stretch;
}
public override string ToString()
{
return string.Format( "{0},{1},{2},{3},{4}", Family, FontSize, Weight, Style, Stretch );
}
}
I have written help documentation myself and it can be a arduous task. Too bad there is not better documentation for the Toolkit.Preferences pref = null;
pref = new Preferences();
_propertyGrid.SelectedObject = pref;
private void Button_Click_1( object sender, RoutedEventArgs e )
{
pref.EditorFont = new WpFFont( new FontFamily( "Arial" ), 17F, FontWeights.Bold,
FontStyles.Italic, FontStretches.Normal );
}
You have 2 options to reflect the changes in the propertyGrid: public class Preferences : INotifyPropertyChanged
{
private WpFFont _editorFont = new WpFFont( new FontFamily( "Segoe UI" ), 9.75F, FontWeights.Normal,
FontStyles.Normal, FontStretches.Normal );
[Category( "Editor" ),
DisplayName( "Font" ),
Description( "The font used for the editor." )]
public WpFFont EditorFont
{
get
{
return _editorFont;
}
set
{
_editorFont = value;
this.OnPropertyChanged( "EditorFont" );
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged( string name )
{
if( PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( name ) );
}
}
#endregion
}
This way, the PropertyGrid will be notified of a propertyChange on its selectedObject and will update. private void testPropertyGrid_PropertyValueChanged( object sender, Xceed.Wpf.Toolkit.PropertyGrid.PropertyValueChangedEventArgs e )
{
if ( e.OldValue != e.NewValue )
{
try
{
// A lot of code just to update a font in a control.
testStringTextBox.FontFamily = preferences.EditorFont.Family;
testStringTextBox.FontSize = preferences.EditorFont.FontSize;
testStringTextBox.FontStretch = preferences.EditorFont.Stretch;
testStringTextBox.FontStyle = preferences.EditorFont.Style;
testStringTextBox.FontWeight = preferences.EditorFont.Weight;
}
catch(Exception ex)
{
MessageBox.Show( ex.Message, "Exception Error", MessageBoxButton.OK, MessageBoxImage.Error );
}
}
}
A new property will be added in v2.2 : ColorPicker.AvailableColorsSortingMode which will be
-Alphabetical
-HueSaturationBrightness
2 different modes of Color sort.