How do I target an AttachedProperty to a MultiBinding?
I have been working with WPF DataGrid and am trying to centralize my cell style. During this refactoring, I was faced with the need for my cell style to know the validation logic that is different for each column. I decided to provide an attached property on my column object that will contain the result of my validation logic (with logic different for each column) and be available in my DataGridCell style. Unfortunately the MultiBinding I have bound to the Attached Property does not work.
My cell style includes a DataTrigger where the trigger binding path is Attached Property. (Note that the TargetType is a 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 have defined Attached Property in my DataGrid class (which is called ValidatingDataGrid and extends DataGrid) as follows:
public static readonly DependencyProperty ValidationValueProperty =
DependencyProperty.RegisterAttached("ValidationValue", typeof(object),
typeof(DataGridColumn));
public static object GetValidationValue(DependencyObject element)
{
return element.GetValue(ValidationValueProperty);
}
public static void SetValidationValue(DependencyObject element, object value)
{
element.SetValue(ValidationValueProperty, value);
}
Finally, in my WPF page, I have a DataGridTextColumn where I am trying to bind the ValidationValue (Column AttachedProperty) to the 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 parsing exception:
System.Windows.Markup.XamlParseException event has occurred
Message = "A" MultiBinding "cannot be set in the 'SetValidationValue' property of type 'DataGridTextColumn'." MultiBinding "can only be set to the 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 the ValidationValue to a static value (like Error) the value is stored correctly and available in the DataTrigger.
-
Can anyone explain what the problem really is? I don't understand what the exception message means, as AttachedProperty is a DependencyProperty and DataGrid and DataGridColumn are DependencyObjects.
-
Is there a way to bind the ValidationValue AttachedProperty to a MultiBinding? If not, is there some other WPF mechanism that will allow me to save the binding result so that my DataGridCell style can read it?
I just ran into the same problem with the same confusing exception. You need to set the owner type of the depenency property to be a class that has Setxxx and Getxxx methods, not the class you want to use the property in. If the methods are in the ValidatingDataGrid, you must 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);
}
...
}
a source to share