DataPropertyAccessor and the validation application block

Grids for WPF Forum

Posted 14 years ago by Rick Edwards - UK
Version: 10.1.0522
Avatar
Hi all,

I've implemented the Enterprise Library Validation Application Block (VAB) in our code to use validators in the Actipro WPF property grid. We create a validator attribute on our properties which controls the validation when we edit the property in the property grid. This all appears to be working fine with the validators correctly validating the value and showing error messages etc.

However, whenever I add a validator attribute to a property of an object edited through the property grid I get an inner exception thrown on any property (not just the one with the attribute) when edited. When I don't have a validator attribute present the property grid acts normally.

The inner exception is being thrown by the data property accessor when it attempts to set a value:

ActiproSoftware.Windows.Controls.PropertyGrid.Primitives.PropertyGridDataAccessorItem.set_Value

We actually use a custom data property accessor but that simply wraps the set value method on the actipro class and does nothing special.

The exception is:

"A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=Value; DataItem='PropertyGridDataAccessorItem' (Name=''); target element is 'TextBox' (Name='textBox'); target property is 'Text' (type 'String') TargetInvocationException:'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Object must be of type Int32."

So it's expecting an Int32 object irrespective of what the actual property underlying type is. This only happens when I have a VAB attribute present on any property in the object being edited.

I've traced the code through and the call path is

PropertyGridDataAccessorItem.Value -> CustomDataPropertyAccessor.Value -> CustomPropertyDescriptor.SetValue(component, value)

Our custom classes don't actually change anything here and simply wrap the base behaviour. I've checked the component and value objects when we use the VAB attributes and when we don't and they appear to be identical. IDataErrorInfo is null, validation results count is zero and the component is flagged as being valid so it looks like the VAB is working correctly in both cases.

I'm now a little stumped as to what the issue is so was wondering whether you have any pointers?

I'm using the latest demo version of the WPF studio with the editors and the property grid editor interop. Note that I get the problem even when editing a string in a TextBox editor so nothing complex involved.

Cheers

Rick Edwards

Comments (2)

Posted 14 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Rick,

It's hard to say without seeing an example, but in general you need to "convert" the values before setting the underlying object. The PropertyDescriptor has a TypeConverter property, which you'd need to use to convert the string to an int. I'm not sure how you implemented CustomDataPropertyAccessor, but I'd probably recommend you derive it from PropertyDescriptorDataAccessor and simply override ValueInternal. But I'm not sure if that would fit in with what you are trying to do. Our version of ValueInternal looks like:
protected override object ValueInternal {
    get {
        return this.PropertyDescriptor.GetValue(this.Target);
    }
    set {
        object instanceValue = value;

        if (null != instanceValue) {
            // See if we need to convert the value and if we can
            TypeConverter converter = this.PropertyDescriptor.Converter;
            Type sourceType = instanceValue.GetType();
            ITypeDescriptorContext context = this as ITypeDescriptorContext;
            if (null != converter && converter.CanConvertFrom(context, sourceType))
                instanceValue = converter.ConvertFrom(context, null, instanceValue);
        }

        this.PropertyDescriptor.SetValue(this.Target, instanceValue);
    }
}
If this doesn't help, please send a small sample project to our support address then we can take a closer look.


Actipro Software Support

Posted 14 years ago by Rick Edwards - UK
Avatar
Found the problem! It was with the custom validator attribute for a range validator. The range values were set as integers (eg. 10, 100) rather than doubles (eg. 10.0, 100.0) which matched the property type. The VAB was interpreting the validator incorrectly and trying to set an Int32, this manifested itself as an inner exception because all validation code is called whenever an individual property was set and hence showed as an error on whatever property box was being edited at the time.

Now fixed and validation appears ok. One thing which I've asked in the "Editors" forum is how to apply a tooltip to the Actipro editor controls used in the Property grid (DoublePropertyEditor for example)? I don't want to cross-post but wasn't sure which forum was best qualified to answer the query.

Thanks, and in answer to your question we implement the IPropertyDataAccessor interface on our custom object and set the base PropertyDataAccessor as a property on construction rather than inheriting directly from the base object itself.

Apart from the error tooltip issue we now appear to have a working property grid that supports the Validation Application Block attributes and is fully localisable including categories, display names and error messages. If there is interested in this I can create a test app for demo purposes somewhere.

Thanks for all your help and sorry if I'd wasted your time.

Regards

Rick Edwards
The latest build of this product (v24.1.1) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.