PropertyGrid: Reset button in context menu is always disabled

Grids for WPF Forum

Posted 2 years ago by Divyanshu
Version: 19.1.0687
Avatar

The build I am using is older than mentioned in the list i.e. v19.1.0687.

The property grid is bound to dataObject in code behind file. 

Upon right click on property grid items, the reset button in context menu always disabled(greyed-out) even after changing the values.

How can we enable it?

[Modified 2 years ago]

Comments (6)

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

Hello,

Is this a custom context menu you are showing, or at least menu items are custom in it?  I assume you are using commands on your context menu items.  When a handler for a command isn't successfully located, the related control bound to the command will be disabled.  The control can also be disabled if the command's CanExecute returns false.  But most often when people run into disabled controls that use commands, it's because a command handler isn't found.  

Are you using routed commands or delegate commands?  Can you provide more detail on the setup?  Thanks!


Actipro Software Support

Posted 2 years ago by Divyanshu
Avatar

Thanks for reply,

We are only binding DataObject with property grid. The context menu is default which shows Reset, copy name, copy value, paste value, and description button. Reset is disabled. It is the default context menu

[Modified 2 years ago]

Posted 2 years ago by Divyanshu
Avatar

Is it possible if we are using Custom Data Factory we won't get to see the activated reset button?

[Modified 2 years ago]

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

The built-in Reset menu item is bound to the ICommand in the related IPropertyModel.ResetValueCommand property.  That command should be wired up properly if you don't have customizations.  Its logic for determining whether it can execute is:

(!this.IsReadOnly) && (this.CanResetValue);

So it's effectively making sure the property or the entire data object is not read-only, and also whether the property indicates that reset is supported.

If you are using our default data factory, the check for CanResetValue is effectively based on what PropertyDescriptor tells us:

propertyDescriptor.CanResetValue(target)

Then in your followup, you mentioned a custom data factory.  Are you using one?  How are you creating your properties within that, via property descriptors or via the more manually-generated PropertyModel class?  If you are using the PropertyModel class, you'd need to inherit that class, override ResetValue method to have your reset logic, and set the CanResetValue property to true. 


Actipro Software Support

Posted 2 years ago by Divyanshu
Avatar

Hi, sorry for delay in Reply.. I analyzed further and found the following:

The resetButton is enabled now by calling the OverParam method. The CanResetValue is overridden from PropertyDescriptor class. In the propertyItem the overridden ResetValue value method sets the value to defaultValue which is evident and can be seen but the change won't be reflected in the PropertyGrid UI. We also called the PropertyService_ResetPropertyEventHandler to ensure it notifies but still no luck. Sharing code:

private void PropertyService_ResetPropertyEventHandler(object sender, EventArgs e)
    {
      string fullPath = null;
      if (sender is PropertyClass property)
      {
        fullPath = GetFullname(property);
        OnGridPropertyChanged(property.Name,property.Value,fullPath);
      }
      else if(sender is ComplexPropertyClass Comproperty)
      {
        fullPath = Comproperty.Name;
        OnGridPropertyChanged(Comproperty.Name, Comproperty.Value, fullPath);
      }
    }


public override void ResetValue(object component)
    {     
      if (CanResetValue(component))
      {  
        property.ResetValue();
        if (property is PropertyClass props && !string.IsNullOrEmpty(props.Validation) && !props.Value.Equals(props.DefaultValue))
        {
          var instance = GetInstanceFromAssembly<ICustomPropertyValidation>(props.Validation);
          if (instance is ICustomPropertyValidation customPropertyDialog)
          {
            if (customPropertyDialog.CanChangeValue(null, property.Value, true))
            {
              UpdateReset();
            }
          }
          return;
        }
        else
        {
          UpdateReset();
        }
      }
    }


 private void UpdateReset()
    {
      property.ResetValue();

      var serviceProvider = ServiceProvider.GetService(typeof(IDevicePropertiesService));
      if (serviceProvider is IDevicePropertiesService Service)
      {
        Service.ResetProperyOnValueChanged(property, new EventArgs());
      }
    }


public override void ResetValue()
    {
      Property.ResetValue();
    }

internal void ResetValue()
    {
      SetValue(DefaultValue);
      IsOverparam = false;
    }


 public void SetValue(string value)
    {
      if (value != this.valueField)
      {
        this.Value = value;
        this.ModifiedTime = DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture);
      }
    }

The Logic for determining is ResetButton can be enabled is following:

public override void Overparam(NamedProperty namedProperty, bool setOverparamFlag, string currentProfile = "")
    {
      if (namedProperty is ComplexProperty)
      {
        //If this property has an associated ProfileProperty, set its attributes and Value (if necessary, and as an override(bold))
        if (Profile != null && setOverparamFlag == false)
        {
          Profile.Overparam(setOverparamFlag, currentProfile, this);
        }

        this.Overparam(((ComplexProperty) namedProperty).Items, setOverparamFlag, currentProfile);
      }
    }

Please provide further assistance. 

[Modified 2 years ago]

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

Hello,

Since this is a pretty complex scenario, it's difficult to say why the UI isn't reflecting your property value change without debugging through it.  In general,

1) Updating IPropertyModel.Value should trigger the UI to update.

2) If you are using PropertyDescriptorPropertyModel (which our TypeDescriptorFactory generates), then it also watches for PropertyDescriptor.ValueChanged notifications.  And further, if PropertyDescriptor is INotifyPropertyChanged, it will look for PropertyChanged events on that too.  In response to value changes via either of those notifications, it should tell the core PropertyDescriptorPropertyModel that that Value changed too.

If you can't figure it out, please make a new simple sample project that shows the issue and send that to our support address, referencing this thread.  Be sure to exclude the bin/obj folders so the .zip you send doesn't get spam blocked.  Thanks!


Actipro Software Support

The latest build of this product (v24.1.3) was released 27 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.