Custom PropertyEditor for a property of type ICommand (aka DelegateCommand)

Grids for WPF Forum

Posted 3 years ago by Tom P.
Version: 19.1.0686
Avatar

I have a class with a property of type ICommand (actually DelegateCommand). I want it to render as a Button in the PropertyGrid.

When it gets rendered by Actipro, it displays the full type name as expected. For other properties, I have successfully used the EditorAttribute to specify a custom Property Editor. Using the same mechanism, the PropertyGrid instead seems to ignore my EditorAttribute, and instead appears to call CommandConverter for some reason.

What am I missing?

Here is my code in C#

    public class DelegateCommandPropertyEditor : PropertyEditor
    {
        public DelegateCommandPropertyEditor()
        {
            ValueTemplateKey = "DelegateCommandPropertyEditorValueTemplate";
        }
    }

    [System.ComponentModel.Editor(typeof(DelegateCommandPropertyEditor), typeof(PropertyEditor))]
    public class DelegateCommand : ICommand
    {
...
    }

Here is my ValueTemplate in the XAML (which is definitely being loaded)

  <DataTemplate
    x:Uid="DelegateCommandPropertyEditorValueTemplate"
    x:Key="DelegateCommandPropertyEditorValueTemplate">
    <Button
      x:Uid="DelegateCommandPropertyEditorValueTemplateButton"
      Margin="5,3,0,3"
      VerticalAlignment="Center"
      DataContext="{Binding Value}"
      Command="{Binding}"
      Content="{Binding DisplayName}" />
  </DataTemplate>

[Modified 3 years ago]

Comments (4)

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Tom,

For scenario questions like this, it's best to make a new simple sample project that shows the issue happening and send that to our support address.  Then we can debug with it and investigate.  Be sure to remove the bin/obj folders from the .zip you send so it doesn't get spam blocked.

One thing I'm confused about is that you said it's ignoring your EditorAttribute but then down lower you said it's definitely loading your DataTemplate.  The PropertyEditor you specified in the EditorAttribute is what references that DataTemplate.  So the DataTemplate wouldn't load without it.

One thing about your Button... an IPropertyModel instance is the data context coming into the property editor DataTemplate.  I believe you are effectively setting that IPropertyModel instance to your Button.Command, which won't work correctly since it expects an ICommand.


Actipro Software Support

Posted 3 years ago by Tom P.
Avatar

For scenario questions like this, it's best to make a new simple sample project that shows the issue happening and send that to our support address.  Then we can debug with it and investigate.  Be sure to remove the bin/obj folders from the .zip you send so it doesn't get spam blocked.

Will do.

One thing I'm confused about is that you said it's ignoring your EditorAttribute but then down lower you said it's definitely loading your DataTemplate.  The PropertyEditor you specified in the EditorAttribute is what references that DataTemplate.  So the DataTemplate wouldn't load without it.

What I should have said it that the XAML file that contains the ValueTemplate is definitely being loaded because the other ValueTemplates are in the same XAML file.

One thing about your Button... an IPropertyModel instance is the data context coming into the property editor DataTemplate.  I believe you are effectively setting that IPropertyModel instance to your Button.Command, which won't work correctly since it expects an ICommand.

Yeah, I see your point, my binding is wrong. 

Posted 3 years ago by Tom P.
Avatar

Ok, I think I understand what is happening now. Basically Actipro seems to use the explicit type of the Property to figure out what PropertyEditor to use.

So if I do this it fails:

public ICommand MyCommand { get; set; }

If I do this it works:

public DelegateCommand MyCommand { get; set; }

I was expecting that Actipro would use the fact that MyCommand is actually a DelegateCommand (from the constructor).

I really don't want to expose DelegateCommand in my ViewModel properties, I want to expose ICommand.

Another solution is to use this in XAML:

    <grids:PropertyGrid 
      DataObject="{Binding}">
      <!-- Uncomment this and everything works. It does mean ALL ICommand implementations will use the same ValueTemplate. -->
      <grids:PropertyGrid.PropertyEditors>
        <grids:PropertyEditor
          PropertyType="{x:Type ICommand}"
          ValueTemplateKey="DelegateCommandPropertyEditorValueTemplate" />
      </grids:PropertyGrid.PropertyEditors>
    </grids:PropertyGrid>

I can send you the full example with source if my explanation isn't sufficiently clear.

[Modified 3 years ago]

Answer - Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Tom,

Property editors can use declared types and property names to determine which one to pull.  Type matching is done based on the API type instead of whatever instance is there at run-time, since the run-time value and its type can change (like to null or to other Brush-inherited types in the case of brushes).

Using EditorAttribute should override default property editor selection logic for a particular property and force the PropertyEditor you specify.  I wouldn't think offhand that the return type of the property would affect how EditorAttribute behaves at all.  But again, without a simple sample to test with, it's tough to say what's causing the issue.

And I agree that it is not good to have to declare your property types as DeleteComment instead of ICommand in your API.


Actipro Software Support

The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.