I have a Style
in a custom control, in which I am trying to set an attached property on a Label
.
The Style
<Style x:Key="DayNumberStyle" TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="local:DateRangePickerHelper.SelectionType" Value="Selected"></Setter>
</Style>
The Attached Property
public class DateRangePickerHelper : FrameworkElement
{
public static readonly DependencyProperty SelectionTypeProperty = DependencyProperty.RegisterAttached(
"DateSelectionType", typeof(DateSelectionType), typeof(DateRangePickerHelper),
new PropertyMetadata(DateSelectionType.NotSelected));
public static void SetSelectionType(DependencyObject element, DateSelectionType value)
{
element.SetValue(SelectionTypeProperty, value);
}
public static DateSelectionType GetSelectionType(DependencyObject element)
{
return (DateSelectionType)element.GetValue(SelectionTypeProperty);
}
}
The Enum
public enum DateSelectionType
{
NotSelected,
Selected,
StartDate,
EndDate
}
The Label
<Label Style="{StaticResource DayNumberStyle}" Grid.Column="0" Content="{Binding Sunday}">
<b:Interaction.Triggers>
<b:EventTrigger EventName="MouseLeftButtonUp">
<b:InvokeCommandAction Command="{Binding Path=LabelClickedCommand, RelativeSource={RelativeSource AncestorType=local:DateRangePicker}}" CommandParameter="{Binding Sunday}"></b:InvokeCommandAction>
</b:EventTrigger>
</b:Interaction.Triggers>
</Label>
The Error
Value cannot be null. (Parameter 'property')
When I remove the attached property from the Setter
everything works correctly.
Can someone explain why I cannot set this with the Style
Setter
?
CodePudding user response:
You define a dependency property SelectionTypeProperty
, so its name must be SelectionType
, as your can read in the documentation: How to implement a dependency property (WPF .NET)
The identifier field must follow the naming convention
<property name>Property
. For instance, if you register a dependency property with the nameLocation
, then the identifier field should be namedLocationProperty
.
However, in your definition, you pass DateSelectionType
name, which is the name of the type of the property, but not the name of the property itself.
If you fail to follow this naming pattern, then WPF designers might not report your property correctly, and aspects of the property system style application might not behave as expected.
Change the name to SelectionType
and it works as expected.
public static readonly DependencyProperty SelectionTypeProperty = DependencyProperty.RegisterAttached(
"SelectionType", typeof(DateSelectionType), typeof(DateRangePickerHelper),
new PropertyMetadata(DateSelectionType.NotSelected));
In case you ever implement a regular dependency property that has property wrappers instead of methods, you could use nameof(<YourProperty>)
to prevent this and renaming issues.