Custom Editor, button stays disabled

Grids for WPF Forum

Posted 10 years ago by Arno Rouschen - Statistics Netherlands
Version: 4.5.0486
Avatar
Hi,

I'm trying to use a custom property editor for a property in my object, but I have not succeeded in doing this. I have implemented this according your sample with the ShowColorDialog where a PopupButton is being used to start a dialog. My problem is however that the button shows up but never gets enabled.

Here is the DataTemplate that is being used for the ValueTemplate. I have the defined this DataTemplate in App.xaml:
        <DataTemplate x:Key="selectClausePropertyGridTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <shared:PopupButton Grid.Column="0" Content="..." DisplayMode="ButtonOnly" 
                            HorizontalAlignment="Right" IsTransparencyModeEnabled="True" 
                            Command="{x:Static dbc:DataBrowseControl.ShowGroupByDialog}" 
                            CommandParameter="{Binding RelativeSource={RelativeSource 

AncestorType={x:Type propgrid:IPropertyDataAccessor}}}" />
            </Grid>
        </DataTemplate>
I assign my QuerySettings object, which has a property which uses a custom editor, by setting the SelectedObject property of the PropertyGrid. The property GroupByFieldDataClause has an editor atrribute set, specified like this:
        [Category("Aggregate settings"),
         DisplayName("Group by field data"),
         Description("Additional group by clause."),
         Editor(typeof(SelectClauseUIEditor), typeof(PropertyEditor)),
        DefaultValue("")]
        public string GroupByFieldDataClause
        {
            get { return _groupByFieldDataClause; }
            set
            { 
                _groupByFieldDataClause = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("GroupByFieldDataClause"));
            }
        }
 
The SelectClauseUIEditor is derived from PropertyEditor and I have overriden its ValueTemplate. If I debug the code then the get accessor of the ValueTemplate is triggered, the DataTmeplate is retrieved from the App's resources and the DataTemplate is returned.
    public class SelectClauseUIEditor : PropertyEditor
    {
        public SelectClauseUIEditor()
        {
        }

        public override DataTemplate ValueTemplate
        {
            get
            {
                DataTemplate dt = (DataTemplate)Application.Current.Resources["selectClausePropertyGridTemplate"];
                return dt;
            }
        }
    }
In my DatabaseBrowseControl I have, just like in your sample, defined a static method which creates and registers a RoutedCommand and also the OnShowGroupByDialogExecute and OnShowGroupByDialogCanExecute
        static DataBrowseControl()
        {
            // Initialize routed commands
            DataBrowseControl.ShowGroupByDialog = new RoutedCommand("ShowGroupByDialog", typeof                (DataBrowseControl));
            CommandManager.RegisterClassCommandBinding(typeof(DataBrowseControl),
                new CommandBinding(DataBrowseControl.ShowGroupByDialog,         OnShowGroupByDialogExecute, OnShowGroupByDialogCanExecute));
        }

      private static void OnShowGroupByDialogExecute(object sender, ExecutedRoutedEventArgs e)
        {
            IPropertyDataAccessor property = e.Parameter as IPropertyDataAccessor;
            if (null != property)
            {
                MessageBox.Show("Do whatever you want to do"); 
                /*
                MyColorDialog dlg = new MyColorDialog();
                if (property.Value is Color)
                    dlg.Color = (Color)property.Value;
                if (true == dlg.ShowDialog())
                    property.Value = dlg.Color;
                 */
                e.Handled = true;
            }
        }

        /// <summary>
        /// Occurs when the <see cref="RoutedCommand"/> needs to determine whether it can execute.
        /// </summary>
        /// <param name="sender">The sender of the event.</param>
        /// <param name="e">A <see cref="CanExecuteRoutedEventArgs"/> that contains the event data.</param>
        private static void OnShowGroupByDialogCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (e.Parameter is IPropertyDataAccessor)
            {
                e.CanExecute = true;
                e.Handled = true;
            }
        }
What I really try to achieve is that I have a property grid in my main application, that I can feed any object which is defined in a separate assembly, in this case a DataBrowseControl. Idealiter I want to define all my classes, custom editors and datatemplate for the propertygrid in the assembly that is referenced by the main application, so I want the property grid to read all the relevant information from that referenced assembly.

Do you have any idea why the button stays disabled or how to implement a solution in order to let the central property grid let react on any object, editor attribute, etc defined in a referenced assembly?

Comments (4)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Arno,

Most times the issue is the control that handles the command is not part of the targeted visual tree. In this case, the DataBrowseControl would need to be an ancestor of the PropertyGrid.

You should be able to change the first parameter of the call to CommandManager.RegisterClassCommandBinding to typeof(PropertyGrid). I haven't tried this, but I believe that would work.


Actipro Software Support

Posted 10 years ago by Arno Rouschen - Statistics Netherlands
Avatar
Hi,

Changing the first parameter to typeof(PropertyGrid) works! The button is enabled now. I really appreciate your help, since I'm relatively new to WPF and the RoutedCommand concepts. Many thanks.

My next step is to create a editor for a List<string> property. I guess I must create a typeconverter for this List<string> in order to convert to List to a string and vice versa. Or do you have better ideas how to build up the List with the Property Grid

Arno
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
If you want the list to be expandable, then you should be able to decorate your property with [TypeConverter(typeof(ExpandableObjectConverter))]. If you want this list to be a single entry in the PropertyGrid, but present it as "One,Two,Three", then you would need to implement as custom TypeConverter and again decorate your property with [TypeConverter(typeof(MyConverter))].


Actipro Software Support

Posted 10 years ago by Arno Rouschen - Statistics Netherlands
Avatar
Thank you very much for your recommendations. You have given me a push in the right direction. I can go on now. Thanks again.
The latest build of this product (v2019.1 build 0681) was released 10 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.