Reputation: 5556
What I want to do, is set BorderBrush of editable ComboBox. I'm using slightly modified default WPF templates. They are structured like below:
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
...
<Grid x:Name="templateRoot" ...>
...
<ToggleButton x:Name="toggleButton" ... />
<Border x:Name="border" ...>
<TextBox x:Name="PART_EditableTextBox" ... />
<!-- textbox with IsFocused property which should be focus trigger -->
</Border>
</Grid>
...
</ControlTemplate>
ToggleButton template:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" ...> <!-- first border brush I want to set on focus -->
<Border x:Name="innerBorder" ...> <!-- second border brush I want to set on focus -->
<Border x:Name="splitBorder" ...>
<Path x:Name="arrow" ... />
</Border>
</Border>
</Border>
</ControlTemplate>
And now, what should happen.
When PART_EditableTextBox.IsFocused
is equal to true
then set templateRoot.BorderBrush
and innerBorder.BorderBrush
to another color (for example [removed: red] red and blue).
It would be very simple if there was only one BorderBrush
to set, because I could use TemplateBinding
to bind this property to ToggleButton
element.
For me, the problem are nested templates. I don't know how to refer to inside of another template.
Upvotes: 1
Views: 2397
Reputation: 5556
Finally, I found the solution by myself. I extended ToggleButton
class so it holds additional InnerBorderBrush
property.
So now, I'm able to set both outer and inner border with Setter
:
<Trigger SourceName="PART_EditableTextBox" Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="Red" TargetName="toggleButton">
<Setter Property="InnerBorderBrush" Value="Blue" TargetName="toggleButton"></Setter>
</Trigger>
This is how I extended ToggleButton class:
public class ComboBoxToggleButton : ToggleButton
{
// Dependency Property
public static readonly DependencyProperty InnerBorderBrushProperty =
DependencyProperty.Register("InnerBorderBrush", typeof(Brush),
typeof(ComboBoxToggleButton), new FrameworkPropertyMetadata(Brushes.Transparent));
// .NET Property wrapper
public Brush InnerBorderBrush
{
get
{
return (Brush)GetValue(InnerBorderBrushProperty);
}
set
{
SetValue(InnerBorderBrushProperty, value);
}
}
}
Upvotes: 0
Reputation: 5536
You could Use TemplateBinding in the ToggleButton parts and bind them to the same property. and then change it inside the trigger:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" >
<!-- first border brush I want to set on focus -->
<Border x:Name="innerBorder" BorderBrush="{TemplateBinding BorderBrush}">
<!-- second border brush I want to set on focus -->
<Border x:Name="splitBorder" >
<Path x:Name="arrow" />
</Border>
</Border>
</Border>
</ControlTemplate>
And then in your trigger inside combobox set the the borderbrush of the togglebutton:
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" >
<ToggleButton x:Name="toggleButton" />
<Border x:Name="border" >
<TextBox x:Name="PART_EditableTextBox" />
<!-- textbox with IsFocused property which should be focus trigger -->
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="PART_EditableTextBox" Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="Red" TargetName="toggleButton"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
UPDATE You can change the ControlTemplate of the ToggleButton to look like this:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" >
<!-- first border brush I want to set on focus -->
<Border x:Name="innerBorder" BorderBrush="{Binding ElementName=templateRoot, Path=BorderBrush, Converter={SomeColorConverter}}">
<!-- second border brush I want to set on focus -->
<Border x:Name="splitBorder" >
<Path x:Name="arrow" />
</Border>
</Border>
</Border>
</ControlTemplate>
This way you can trigger the binding once BorderBrush is changed through the trigger and use the converter to set a different color.
Upvotes: 1
Reputation: 1767
A trigger can take care of this for you
<UserControl x:Class="Sample2.ContactSearchControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="75" Width="300">
<Border>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=txtSearch}" Value="true">
<Setter Property="Background" Value="Black" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<StackPanel>
<TextBox x:Name="txtSearch" Text="Search" />
<TextBox Text="Other" />
</StackPanel>
</Border>
</UserControl>
Upvotes: 0