I have a style that I re-use for multiple textboxes. Within the style, I define a control template - and within that control template, I have some triggers. I want to be able to pass a Data Property into one of those triggers from the View.
Here is a shortened version of my current style defined in a Resource Dictionary:
<Style x:Key="TextBoxTheme" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding PARAMETER}" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="Red"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
There is one DataTrigger "(Binding PARAMETER}" that will determine if the border is set to red or not. Depending on where I use this textbox, I want to bind that to a different variable.
I want to be able to pass that as a parameter from my View. I'm imagining something like this (just an idea of how I think it should work, but this doesn't work):
<TextBox Style="{StaticResource TextBoxTheme, Parameter={Binding PARAMETER}}"/>
<TextBox Style="{StaticResource TextBoxTheme, Parameter={Binding DIFFERENT_PARAMETER}}"/>
Since I can't figure out how to do that yet, I am almost rewriting the same code every time I call it.
Example (Using this style with my 'Name' textbox):
<TextBox Text="{Binding Name}">
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource TextBoxTheme}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding DuplicateName}" Value="False">
<Setter Property="BorderBrush" TargetName="border" Value="Green"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
Example (When I want to use this same style with a different binding):
<TextBox Text="{Binding IpAddress}">
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource TextBoxTheme}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding DuplicateIP}" Value="False">
<Setter Property="BorderBrush" TargetName="border" Value="Green"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
Is there a better way of doing this? I found an article that shows you how to pass a property into a style (https://thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/) but I don't see it working with passing a data property.
In general, for reusing an existing Style, Style.Triggers are better than ControlTemplate.Triggers because Style.Triggers can be defined at an derived Style.
A simple base Style would be like:
<Style x:Key="TextBoxTheme" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderThickness" Value="2"/>
</Style>
Then you can define two derived Styles of different Style.Triggers.
<Style x:Key="TextBoxTheme1" TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxTheme}">
<Style.Triggers>
<DataTrigger Binding="{Binding PARAMETER}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="TextBoxTheme2" TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxTheme}">
<Style.Triggers>
<DataTrigger Binding="{Binding DuplicateName}" Value="False">
<Setter Property="BorderBrush" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
Or if you want to specify Style.Triggers for each TextBox, it would be easier to define a Style inside each TextBox.
<TextBox Text="example">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource TextBoxTheme}">
<Style.Triggers>
<DataTrigger Binding="{Binding DuplicateIP}" Value="False">
<Setter Property="BorderBrush" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>