WPF ComboBox: как установить фокус на его кнопке - PullRequest
3 голосов
/ 14 октября 2010

Я пытаюсь получить 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 ]

4 голосов
/ 14 апреля 2011

Самый простой способ сделать это - привязать IsFocused к шаблонному родителю. Примечание. Режим = 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 >
0 голосов
/ 24 мая 2012

Привязка к свойству 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 >
0 голосов
/ 16 октября 2010

Вы установили Focusable=False для вашего ToggleButton в ControlTemplate, поэтому, когда он получает фокус, он передает его следующему внутреннему фокусируемому элементу UIElement.Если вы удалите это, ваша ToggleButton должна получить фокус вместо TextBox.

0 голосов
/ 14 октября 2010

Вы хотите настроить или выбрать FocusVisualStyle: Посмотреть здесь: MSDN: стили для фокуса в элементах управления и FocusVisualStyle

Я думаю, что синяя, которую вы хотите получить, относится к какой-то оригинальной теме Windows, возможно, она содержится в этой загрузке Стандартные темы WPF из Примеры Microsoft WPF .

...