WPF ComboBox:如何设置焦点的togglebutton

时间:2010-10-14 16:28:43

标签: wpf combobox focus styles controltemplate

我正在尝试使用ComboBox来匹配视觉设计,因此当ToggleButton具有焦点时,ComboBox的边框会为蓝色。我无法弄清楚如何做到这一点,无法找到一个例子。

ComboBox获得焦点时,TextBox内部获得虚线焦点视觉效果。如何将ComboBox焦点状态向下传递到ToggleButton,以便打开蓝色边框样式?

以下是我的ComboBox模板:

<ControlTemplate x:Key="ComboBoxCT" TargetType="{x:Type ComboBox}">
    <Grid x:Name="gLayoutRoot"
        Margin="{TemplateBinding Margin}" 
        HorizontalAlignment="{TemplateBinding HorizontalAlignment}" 
        VerticalAlignment="{TemplateBinding VerticalAlignment}" 
        MinWidth="{TemplateBinding MinWidth}" 
        MinHeight="{TemplateBinding MinHeight}" 
        MaxWidth="{TemplateBinding MaxWidth}" 
        MaxHeight="{TemplateBinding MaxHeight}" 
        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
        <ToggleButton x:Name="ToggleButton" 
            Grid.Column="2" 
            Focusable="false"
            IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
            ClickMode="Press" 
            Style="{DynamicResource ComboBoxToggleStyle}" 
            />
        <AccessText x:Name="ContentSite" 
            Style="{StaticResource ComboBoxAccessTextStyle}" 
            Text="{TemplateBinding SelectionBoxItem}" 
            Foreground="{TemplateBinding Foreground}"/>
        <TextBox x:Name="PART_EditableTextBox"
            Style="{x:Null}" 
            HorizontalAlignment="{TemplateBinding HorizontalAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalAlignment}" 
            Margin="2,3,17,2"
            Focusable="True" 
            Background="{DynamicResource InnerBgLight}"
            Visibility="Hidden"
            IsReadOnly="{TemplateBinding IsReadOnly}">
            <TextBox.Template>
                <ControlTemplate TargetType="TextBox">
                    <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
                </ControlTemplate>
            </TextBox.Template>
        </TextBox>
        <Popup x:Name="Popup"
            Placement="Bottom"
            IsOpen="{TemplateBinding IsDropDownOpen}"
            AllowsTransparency="True" 
            Focusable="False"
            PopupAnimation="Slide">
                <Grid x:Name="DropDown"
                    SnapsToDevicePixels="True"                
                    MinWidth="{TemplateBinding ActualWidth}"
                    MaxHeight="{TemplateBinding MaxDropDownHeight}">
                        <Border x:Name="OuterBorder"
                            Style="{DynamicResource OuterBorderBottomRestStyle}"
                            Background="{DynamicResource InnerBorder}">
                            <Border x:Name="InnerBorder" 
                                Style="{DynamicResource InnerBottomBorderStyle}">
                                <ScrollViewer x:Name="scvCbxItems" SnapsToDevicePixels="True">
                                    <StackPanel x:Name="spCbxItemsPanel" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Border>
                        </Border>
                </Grid>
            </Popup>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="HasItems" Value="false">
                <Setter TargetName="InnerBorder" Property="MinHeight" Value="95"/>
            </Trigger>
            <Trigger Property="IsGrouping" Value="true">
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </Trigger>
            <Trigger Property="IsEditable" Value="true">
                <Setter Property="IsTabStop" Value="false"/>
                <Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
                <Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Foreground" Value="{DynamicResource FgDisabledBrush}"/>
                <Setter Property="OpacityMask" TargetName="OuterBorder" Value="{DynamicResource OuterBgDisabledOpacityMask}"/>
            </Trigger>  
        </ControlTemplate.Triggers>
    </ControlTemplate>

这是我的ToggleButton模板:

    <ControlTemplate x:Key="ComboBoxToggleCT" TargetType="{x:Type ToggleButton}">
    <Border x:Name="OuterBorder" 
        Style="{DynamicResource OuterBorderTopRestStyle}">
        <Border x:Name="InnerBorder" 
            Style="{DynamicResource InnerTopBorderStyle}">
                <Path x:Name="Arrow" 
                    HorizontalAlignment="Right" VerticalAlignment="Center"
                    Margin="5"
                    Fill="{DynamicResource FgBrush}"
                    Data="{DynamicResource DownArrowGeometry}"/>
        </Border>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderTopSelectStyle}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="OpacityMask" TargetName="OuterBorder" Value="{DynamicResource OuterBgDisabledOpacityMask}"/>
            <Setter Property="Fill" TargetName="Arrow" Value="{DynamicResource FgDisabledBrush}"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderTopSelectStyle}"/>
            <Setter Property="Style" TargetName="InnerBorder" Value="{DynamicResource InnerBorderTopFocusStyle}"/>
        </Trigger>
        <!--<Trigger Property="IsKeyboardFocused" Value="True">-->
        <Trigger Property="IsKeyboardFocused" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsFocused}">
            <Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderBottomFocusStyle}"/>
            <Setter Property="Style" TargetName="InnerBorder" Value="{DynamicResource InnerBorderTopFocusStyle}"/>
        </Trigger>
    </ControlTemplate.Triggers>

</ControlTemplate>

正如您所看到的,我尝试绑定到ComboBox的焦点状态,但这在Trigger内部不起作用。

任何帮助表示赞赏。抱歉,这个菜鸟问题。谢谢!

4 个答案:

答案 0 :(得分:4)

最简单的方法是绑定Templated Parent的IsFocused。注意:Mode = OneWay非常重要,因为IsFocused是只读的。你可以这样做:

<DataTrigger Binding="{Binding IsFocused, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneWay}" Value="True">
   <Setter Property="Style" TargetName="OuterBorder" Value="{DynamicResource OuterBorderBottomFocusStyle}"/>
   <Setter Property="Style" TargetName="InnerBorder" Value="{DynamicResource InnerBorderTopFocusStyle}"/>
</DataTrigger >

答案 1 :(得分:0)

您想要自定义或选择FocusVisualStyle: 看这里: MSDN: Styling for Focus in Controls, and FocusVisualStyle

我认为你想要的蓝色主题来自一些原始的windows主题,也许它包含在Default WPF ThemesMicrosoft WPF Samples下载中。

答案 2 :(得分:0)

您已在ControlTemplate中为ToggleButton设置Focusable=False,因此当它收到焦点时,会将其传递给下一个内部可聚焦UIElement。 如果你删除它,你的ToggleButton应该得到焦点而不是TextBox。

答案 3 :(得分:0)

当您将IsFocused属性设置为ComboBox.IsEditable时,绑定到模板化父级的True属性不起作用。相反,您可以使用IsKeyboardFocusWithin,请检查以下内容:

<DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneWay}" Value="True">
    <Setter Property="Background" TargetName="Border" Value="{DynamicResource MainColorLight}" />
    <Setter Property="BorderBrush" TargetName="Border" Value="{DynamicResource MainColorLight}" />
    <Setter Property="BorderBrush" TargetName="Border2" Value="{DynamicResource MainColorLight}" />
    <Setter Property="Fill" TargetName="Arrow" Value="White" />
</DataTrigger >