This project has moved and is read-only. For the latest updates, please go here.

How to force a call to ResolveEditor ( a function in ITypeEditor)

Apr 15, 2015 at 9:32 PM
I am using a custom editor with attributes for a read-only property which is of type double. The foreground color of the textbox for the property depends on whether the property is in or out a tolerance defined somewhere else. Currently I can fish out the tolerance value from the propertyItem argument in the ResolveEditior function and then decide the foreground color (which I am hoping to find a better way to do it). When the tolerance is modified, I could force a call to the getter of the property but the ResolveEditor was not called. As a result, the color of the property would not update if I change the tolerance value.

Any suggestion will be greatly appreciated.
Apr 16, 2015 at 9:29 PM
Hi,

In the Plus version of the Toolkit, you can use the "DependsOn" attribute, which calls the ResolveEditor method when the associated attribute is modified. Here's a sample :
 <StackPanel>
      <xctk:PropertyGrid x:Name="_propertyGrid" 
                         SelectedObject="{Binding Data}"/>
      <Button Content="Change Tolerance"
              Click="Button_Click_1" />
</StackPanel>

 public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();

      this.Data = new MyObject( "Tom Smith", 35, 40 );

      _propertyGrid.DataContext = this;
    }

    public MyObject Data
    {
      get;
      set;
    }

    private void Button_Click_1( object sender, RoutedEventArgs e )
    {
      this.Data.Tolerance = 30;
    }
  }

  public class MyObject : INotifyPropertyChanged
  {
    private string _name;
    public double _tolerance;
    public double _value;

    public MyObject( string name, double value, double tolerance )
    {
      this.Name = name;
      this.Value = value;
      this.Tolerance = tolerance;
    }

    public string Name
    {
      get
      {
        return _name;
      }
      set
      {
        _name = value;
        this.OnPropertyChanged( "Name" );
      }
    }

    [Editor( typeof( ValueEditor ), typeof( ValueEditor ) )]
    [DependsOn( "Tolerance" )]
    public double Value
    {
      get
      {
        return _value;
      }
      private set
      {
        _value = value;
        this.OnPropertyChanged( "Value" );
      }
    }

    public double Tolerance
    {
      get
      {
        return _tolerance;
      }
      set
      {
        _tolerance = value;
        this.OnPropertyChanged( "Tolerance" );
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged( string propertyName )
    {
      if( PropertyChanged != null )
      {
        PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
      }
    }
  }

  public class ValueEditor : ITypeEditor
  {
    public FrameworkElement ResolveEditor( PropertyItem propertyItem )
    {
      var textBlock = new TextBlock();

      MyObject myObject = (MyObject)propertyItem.Instance;
      if( myObject.Value >= myObject.Tolerance )
      {
        textBlock.Foreground = new SolidColorBrush( Colors.Green );
      }
      else
      {
        textBlock.Foreground = new SolidColorBrush( Colors.Red );
      }

      //create the binding from the bound property item to the editor
      var _binding = new Binding( "Value" ); //bind to the Value property of the PropertyItem
      _binding.Source = propertyItem;
      _binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;

      BindingOperations.SetBinding( textBlock, TextBlock.TextProperty, _binding );
      return textBlock;
    }
}