views:

550

answers:

1

I've been working with the WPF DataGrid and trying to centralize my cell style. During this refactor, I came across a need for my cell style to know validation logic that is different for each column. I decided to provide an attached property on my column object, which would contain the result of my validation logic (with the logic being different per column) and be accessable in my DataGridCell style. Unfortunately, the MultiBinding that I've tied to the Attached Property doesn't work.

My cell style includes a DataTrigger, where the trigger's binding path is an Attached Property. (Note that the style's TargetType is DataGridCell, which has a Column property)

        <DataTrigger 

            Value="Error"

            >

            <DataTrigger.Binding>

                <Binding Converter="{StaticResource debugConverter}" RelativeSource="{RelativeSource Self}" Path="Column.ValidationValue" Mode="OneWay"/>

            </DataTrigger.Binding>

            <Setter 

                Property="BorderBrush" 

                Value="{StaticResource errorBrush}"

                />

        </DataTrigger>

I've defined the Attached Property in my DataGrid class (which is named ValidatingDataGrid and extends the DataGrid) as follows:

    public static readonly DependencyProperty ValidationValueProperty =

        DependencyProperty.RegisterAttached(

            "ValidationValue",

            typeof(object),

            typeof(DataGridColumn)

            );



    public static void SetValidationValue(DependencyObject element, object value)

    {

        element.SetValue(ValidationValueProperty, value);

    }



    public static object GetValidationValue(DependencyObject element)

    {

        return (object)element.GetValue(ValidationValueProperty);

    }

Finally, in my WPF Page, I have a DataGridTextColumn, where I attempt to bind ValidationValue (the Column's AttachedProperty) to a MultiBinding.

               <vfc:ValidatingDataGrid> 

                    <vfc:ValidatingDataGrid.Columns>

                        <tk:DataGridTextColumn

                            Header="Name"

                            Width="1.5*"

                            >

                            <tk:DataGridTextColumn.Binding>

                                <Binding Path="Name"/>

                            </tk:DataGridTextColumn.Binding>

                            <vfc:ValidatingDataGrid.ValidationValue>

                                <MultiBinding Converter="{StaticResource validityConverter}" ConverterParameter="Name">

                                    <Binding Mode="OneWay"/>

                                    <Binding Path="Name" UpdateSourceTrigger="PropertyChanged"/>

                                </MultiBinding>

                            </vfc:ValidatingDataGrid.ValidationValue>

When I try to run this, however, I consistently get a XAML Parse Exception:

System.Windows.Markup.XamlParseException occurred

Message="A 'MultiBinding' cannot be set on the 'SetValidationValue' property of type 'DataGridTextColumn'. A 'MultiBinding' can only be set on a DependencyProperty of a DependencyObject."

Source="PresentationFramework"

LineNumber=0

LinePosition=0

StackTrace: at MS.Internal.Helper.CheckCanReceiveMarkupExtension(MarkupExtension markupExtension, IProvideValueTarget provideValueTarget, DependencyObject& targetDependencyObject, DependencyProperty& targetDependencyProperty)

InnerException: Null

I know that if I set ValidationValue to a static value (for example, Error), the value is properly stored and accessed in the DataTrigger.

  1. Can anyone explain what the problem actually is? I don't understand what the exception message means since the AttachedProperty is a DependencyProperty, and DataGrid and DataGridColumn are both DependencyObjects.

  2. Is there a way to bind the ValidationValue AttachedProperty to the MultiBinding? If not, is there some other WPF mechanism that will let me store the result of a binding so my DataGridCell style can read it?

Thanks very much,

-Craig

A: 

I just ran in to the same problem with the same confusing exception. You need to set the owner type of the depenency property to be the class that has the Setxxx and Getxxx methods, not the class that you want to use the property on. If the methods are in ValidatingDataGrid, you should register the property like this:

public class ValidatingDataGrid
{
 ... 

 public static readonly DependencyProperty ValidationValueProperty =
  DependencyProperty.RegisterAttached(
   "ValidationValue",
   typeof(object),
   typeof(ValidatingDataGrid)
   );

 public static void SetValidationValue(DependencyObject element, object value)
 {
  element.SetValue(ValidationValueProperty, value);
 }

 public static object GetValidationValue(DependencyObject element)
 {
  return (object)element.GetValue(ValidationValueProperty);
 }

 ...
}
will-mvn