I'm experimenting the attribute Telerik.Windows.Controls.Data.PropertyGrid.Editor, and in your example, you show the usage of a RadColorEditor as a cusom editor.
I'm doing the same thing with a control (which currently only shows the color), but the template is not being applied. I have put the style with the template in the Themes\Generic.xaml and still nothing.
If I put an instance of that control on the XAML directory, then I see it.
Here is my View Model:
public class Person : DependencyObject , INotifyPropertyChanged{ public Person() { currentColor = Colors.Red; } private string _firstName = "Sponge"; [Display(Name="First Name", GroupName="Details", Order = 1, Prompt="tttt"), CustomValidation(typeof(Person), "blabla"), Browsable(true)] public string FirstName { get { return _firstName; } set { _firstName = value; } } private string _lastName = "Bob"; [DisplayName("Last Name"), Category("Details"), Browsable(true)] public string LastName { get { return _lastName; } set { _lastName = value; } } private string _blabla; public string Blabla { get { return _blabla; } set { _blabla = value; } } [Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(MyEditor), "SelectedColor", Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.None), Browsable(true)] public Color CurrentColor { get { return this.currentColor; } set { if (this.currentColor != value) { this.currentColor = value; this.OnPropertyChanged("CurrentColor"); } } } public void blabla() { } public Visibility Visibility { get { return (Visibility)GetValue(VisibilityProperty); } set { SetValue(VisibilityProperty, value); } } // Using a DependencyProperty as the backing store for Visibility. This enables animation, styling, binding, etc... public static readonly DependencyProperty VisibilityProperty = DependencyProperty.Register("Visibility", typeof(Visibility), typeof(Person), new UIPropertyMetadata(Visibility.Visible)); private Color currentColor { get; set; } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (propertyName != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }}
This is the XAML:
<Window x:Class="TelerikPropertyGrid.MainWindow" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:myEditors="clr-namespace:MyEditors;assembly=MyEditors" xmlns:local="clr-namespace:TelerikPropertyGrid" Title="MainWindow" Height="350" Width="525"> <Grid> <telerik:RadPropertyGrid x:Name="pg" DescriptionPanelVisibility="Collapsed" Item="{Binding Item}" telerik:StyleManager.Theme="Windows8" AutoGeneratingPropertyDefinition="pg_AutoGeneratingPropertyDefinition" BeginningEdit="pg_BeginningEdit" EditEnded="pg_EditEnded" FieldLoaded="pg_FieldLoaded" Grouped="pg_Grouped" ItemChanged="pg_ItemChanged" SelectionChanged="pg_SelectionChanged" SourceUpdated="pg_SourceUpdated" /> </Grid></Window>
This is the code-behind of that window:
public partial class MainWindow : Window{ private Person _person = new Person(); public MainWindow() { InitializeComponent(); this.DataContext = this; } public Person Item { get { return _person; } } private void pg_AutoGeneratingPropertyDefinition(object sender, Telerik.Windows.Controls.Data.PropertyGrid.AutoGeneratingPropertyDefinitionEventArgs e) { var pd = e.PropertyDefinition; var desc = pd.SourceProperty.Descriptor as PropertyDescriptor; bool canAdd = false; for (int i = 0; i < desc.Attributes.Count; i++) { var att = desc.Attributes[i]; if (att is BrowsableAttribute && (att as BrowsableAttribute).Browsable) { canAdd = true; } } if (!canAdd) e.Cancel = true; if (pd.DisplayName == "First Name") { pd.DisplayName = "First[Name2]"; Binding binding = new Binding("Visibility"); binding.Source = Item; BindingOperations.SetBinding(pd, PropertyDefinition.VisibilityProperty, binding); } } private void pg_BeginningEdit(object sender, Telerik.Windows.Controls.Data.PropertyGrid.PropertyGridBeginningEditEventArgs e) { } private void pg_EditEnded(object sender, Telerik.Windows.Controls.Data.PropertyGrid.PropertyGridEditEndedEventArgs e) { } private void pg_FieldLoaded(object sender, Telerik.Windows.Controls.Data.PropertyGrid.FieldEventArgs e) { } private void pg_Grouped(object sender, Telerik.Windows.RadRoutedEventArgs e) { } private void pg_ItemChanged(object sender, Telerik.Windows.Controls.Data.PropertyGrid.PropertyGridItemChangedEventArgs e) { } private void pg_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangeEventArgs e) { } private void pg_SourceUpdated(object sender, DataTransferEventArgs e) { } }
The Editor, MyEditor is located on a different DLL:
MyEditor.cs... the break point of the OnApplyTemplate is never reached:
public class MyEditor : Control{ static MyEditor() { FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(MyEditor), new FrameworkPropertyMetadata(typeof(MyEditor))); } public MyEditor() { this.SetValue(FrameworkElement.DefaultStyleKeyProperty, typeof(MyEditor)); } public Color SelectedColor { get { return (Color)GetValue(SelectedColorProperty); } set { SetValue(SelectedColorProperty, value); } } // Using a DependencyProperty as the backing store for SelectedColor. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(MyEditor), new UIPropertyMetadata(Colors.White, onSelectedColorChanged)); public override void OnApplyTemplate() { base.OnApplyTemplate(); } public static void onSelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
// This is the code of the converter
public class ColorToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Color)
{
return new SolidColorBrush((Color)value);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Generic.xaml located under the Themes directory
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:local="clr-namespace:MyEditors" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <local:ColorToBrushConverter x:Key="ctb" /> <Style TargetType="{x:Type local:MyEditor}" x:Key="{x:Type local:MyEditor}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:MyEditor}"> <Border x:Name="border" Background="{TemplateBinding SelectedColor, Converter={StaticResource ctb}}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style></ResourceDictionary>
I can do the following code once, when the LayoutUpdated is called for the first time, but it looks dirty, and I'm sure that there are better ways:
Style ts = Application.Current.FindResource(typeof(MyEditor)) as Style;
this.Style = ts;
What am I doing wrong?
What am I missing, and should I do in order to see the editor in the property grid.
Thanks.