DataTrigger Binding in WPF Style
.net, c#, mvvm, wpf
Solution
could you provide me an example of what you explained?
Sure,
1 - Using Tag
In your `Style` have your `DataTrigger` as:
<DataTrigger Binding="{Binding Path=Tag,
RelativeSource={RelativeSource Self}}"
Value="{x:Static sys:String.Empty}">
...
</DataTrigger>
as for usage:
<Button x:Name="btnPosition"
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding PositionFilterCommand}"
Content="{l:Translate position}"
Tag="{Binding SelectedPositions}"
Style="{StaticResource NewButtonStyle}" />
2 - Using Attached Property:
"local:" refers to the xaml namespace alias of your application or if you use different namespaces, the namespace where `MyCustomPropertyCollection` is declared.
code-behind:
public class MyCustomPropertyCollection {
public static readonly DependencyProperty SomeStringProperty =
DependencyProperty.RegisterAttached(
"SomeString",
typeof(string),
typeof(MyCustomPropertyCollection),
new FrameworkPropertyMetadata(string.Empty));
public static void SetSomeString(UIElement element, string value) {
element.SetValue(SomeStringProperty, value);
}
public static string GetSomeString(UIElement element) {
return (string)element.GetValue(SomeStringProperty);
}
}
`Style.DataTrigger`
<DataTrigger Binding="{Binding Path=(local:MyCustomPropertyCollection.SomeString),
RelativeSource={RelativeSource Self}}"
Value="{x:Static sys:String.Empty}">
...
</DataTrigger>
usage:
<Button x:Name="btnPosition"
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding PositionFilterCommand}"
Content="{l:Translate position}"
local:MyCustomPropertyCollection.SomeString="{Binding SelectedPositions}"
Style="{StaticResource NewButtonStyle}" />
3 - Normal Dependency Property
custom `Button` class:
public class MyButton : Button {
public static readonly DependencyProperty SomeStringProperty =
DependencyProperty.Register(
"SomeString",
typeof(string),
typeof(MyButton),
new FrameworkPropertyMetadata(string.Empty));
public string SomeString {
get {
return (string)GetValue(SomeStringProperty);
}
set {
SetValue(SomeStringProperty, value);
}
}
}
Style in xaml not only needs `DataTrigger` updated but `Style` definition too.
so switch
<Style x:Key="NewButtonStyle" TargetType="{x:Type Button}">
to
<Style x:Key="NewButtonStyle" TargetType="{x:Type local:MyButton}">
`Style.DataTrigger`
<DataTrigger Binding="{Binding Path=SomeString,
RelativeSource={RelativeSource Self}}"
Value="{x:Static sys:String.Empty}">
...
</DataTrigger>
usage:
<local:MyButton x:Name="btnPosition"
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Command="{Binding PositionFilterCommand}"
Content="{l:Translate position}"
SomeString="{Binding SelectedPositions}"
Style="{StaticResource NewButtonStyle}" />
`Tag` approach is frowned upon. "Attached Property" is easier to implement but isn't as clear of a indicator of dependencies as a custom class with a normal DP and AP also gets way overused. Take your pick for what you'd prefer.
Problem
I have the following Button and Style in WPF and I need to generalize the Binding in the DataTrigger section because I have near 10 similar buttons in the same Window and each button should be binded to a different property (SelectedPositions, SelectedAgencies, ....). Is it possible to implement? ``` <Button x:Name="btnPosition" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" Command="{Binding PositionFilterCommand}" Content="{l:Translate position}" Style="{StaticResource NewButtonStyle}" /> <Style x:Key="NewButtonStyle" TargetType="{x:Type Button}"> <Setter Property="Foreground" Value="White" /> <Setter Property="Height" Value="22" /> <Setter Property="Width" Value="Auto" /> <Setter Property="FontFamily" Value="OpenSans" /> <Setter Property="FontSize" Value="13" /> <Setter Property="Cursor" Value="Hand" /> <Setter Property="Margin" Value="10,2,10,0" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border CornerRadius="3"> <Grid x:Name="gridButton" Background="#54728e"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Image x:Name="img" Grid.Column="0" Width="24" Height="24" Source="Img/tick-white.png" Visibility="Visible" /> <Rectangle x:Name="rect" Grid.Column="1" Fill="#54728e" RadiusX="3" RadiusY="3" /> <ContentPresenter Grid.Column="1" Margin="5,0,5,0" HorizontalAlignment="Stretch" VerticalAlignment="Center" /> </Grid> </Border> <ControlTemplate.Triggers> <DataTrigger Binding="{Binding SelectedPositions}" Value="{x:Static sys:String.Empty}"> <Setter TargetName="rect" Property="Fill" Value="#8bbcdf" /> <Setter TargetName="img" Property="Visibility" Value="Collapsed" /> <Setter TargetName="gridButton" Property="Background" Value="#8bbcdf" /> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> ```