在焦点上设置可编辑 ComboBox 的边框颜色

Set border color of editable ComboBox on focus

我要做的,是设置可编辑ComboBox的BorderBrush。 我正在使用稍微修改过的默认 WPF 模板。它们的结构如下:

<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>

切换按钮模板:

<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>

现在,应该发生什么。

PART_EditableTextBox.IsFocused等于true 然后将 templateRoot.BorderBrushinnerBorder.BorderBrush 设置为另一种颜色(例如 [已删除:红色] 红色和蓝色)。

如果只设置一个BorderBrush就很简单了,因为我可以用TemplateBinding把这个属性绑定到ToggleButton元素

对我来说,问题是嵌套模板。我不知道如何引用另一个模板的内部。

触发器可以为您解决这个问题

<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>

您可以在 ToggleButton 部件中使用 TemplateBinding 并将它们绑定到相同的 属性。然后在触发器内更改它:

 <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>

然后在组合框内的触发器中设置切换按钮的边框刷:

<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>

更新 您可以将 ToggleButton 的 ControlTemplate 更改为如下所示:

<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>

这样您就可以在通过触发器更改 BorderBrush 后触发绑定,并使用转换器设置不同的颜色。

最后,我自己找到了解决办法。我扩展了 ToggleButton class 所以它包含额外的 InnerBorderBrush 属性.

所以现在,我可以使用 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>

这就是我扩展 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);
        }
    }
}