WPF自定义样式的ComboBox,无法在单击ComboBox内部后展开DropDown

4
我已经包含了下面这个样式给ComboBox,这个样式我在一年前偶然发现的,是WPFToolkit的一部分。
它缺少一个基本功能,就是如果我点击ComboBoxTextBox,我希望下拉菜单像通常一样展开。在这个模板中,下拉菜单只能通过直接点击ComboBoxToggleButton来打开。
我不知道在模板样式中该查找什么,你能否指导我一些呢?
模板样式:
<ControlTemplate x:Key="ComboBoxToggleButton"
                 TargetType="{x:Type ToggleButton}">
    <ControlTemplate.Resources>
        <Storyboard x:Key="HoverOn">
            <DoubleAnimation Duration="00:00:00.1000000"
                             Storyboard.TargetName="rectangleOver"
                             Storyboard.TargetProperty="Opacity"
                             To="0.8" />
            <ColorAnimation Duration="00:00:00.1000000"
                            Storyboard.TargetName="Background"
                            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                            To="#FFFFFFFF" />
        </Storyboard>
        <Storyboard x:Key="HoverOff">
            <DoubleAnimation Duration="00:00:00.4000000"
                             Storyboard.TargetName="rectangleOver"
                             Storyboard.TargetProperty="Opacity"
                             To="0" />
            <ColorAnimation Duration="00:00:00.4000000"
                            Storyboard.TargetName="Background"
                            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                            To="#FFffffff" />
        </Storyboard>
        <Storyboard x:Key="PressedOn">
            <DoubleAnimation Duration="00:00:00.1000000"
                             Storyboard.TargetName="rectanglePress"
                             Storyboard.TargetProperty="Opacity"
                             To="0.8" />
            <ColorAnimation Duration="00:00:00.1000000"
                            Storyboard.TargetName="Background"
                            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                            To="#FFFFFFFF" />
        </Storyboard>
        <Storyboard x:Key="PressedOff">
            <DoubleAnimation Duration="00:00:00.4000000"
                             Storyboard.TargetName="rectanglePress"
                             Storyboard.TargetProperty="Opacity"
                             To="0" />
            <ColorAnimation Duration="00:00:00.4000000"
                            Storyboard.TargetName="Background"
                            Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                            To="#FFffffff" />
        </Storyboard>
        <Storyboard x:Key="CheckedOn">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="BackgroundChecked"
                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.1000000"
                                      Value="1" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="CheckedOff">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="BackgroundChecked"
                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000"
                                      Value="0" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </ControlTemplate.Resources>
    <Grid x:Name="grid">
        <Rectangle x:Name="Background"
                   Fill="#ffffff"
                   Stroke="#ffc6c6c6"
                   RadiusX="3"
                   RadiusY="3"
                   IsHitTestVisible="false" />
        <Rectangle x:Name="BackgroundChecked"
                   Margin="1"
                   IsHitTestVisible="false"
                   Opacity="0">
            <Rectangle.Fill>
                <SolidColorBrush Color="{DynamicResource WhiteColor}" />
            </Rectangle.Fill>
        </Rectangle>
        <Rectangle x:Name="rectangleOver"
                   Width="15"
                   Stroke="#FFE8E8E8"
                   HorizontalAlignment="Right"
                   Opacity="0"
                   Fill="{DynamicResource MouseOverBrush}" />
        <Rectangle x:Name="rectanglePress"
                   Width="15"
                   Stroke="#FC9E9D9B"
                   HorizontalAlignment="Right"
                   Opacity="0"
                   Fill="{DynamicResource PressedBrush}" />
        <Rectangle x:Name="DisabledVisualElement"
                   Margin="1"
                   Fill="{DynamicResource DisabledBackgroundBrush}"
                   IsHitTestVisible="false"
                   Visibility="Collapsed" />
        <Path x:Name="BtnArrow"
              Margin="0,0,4,0"
              Width="6"
              Fill="{DynamicResource GlyphBrush}"
              Stretch="Uniform"
              HorizontalAlignment="Right"
              Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z " />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsPressed"
                 Value="True">
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource PressedOff}"
                                 x:Name="PressedOff_BeginStoryboard" />
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource PressedOn}"
                                 x:Name="PressedOn_BeginStoryboard" />
            </Trigger.EnterActions>
        </Trigger>
        <Trigger Property="IsMouseOver"
                 Value="true">
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource HoverOff}"
                                 x:Name="HoverOff_BeginStoryboard" />
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource HoverOn}" />
            </Trigger.EnterActions>

        </Trigger>
        <Trigger Property="IsChecked"
                 Value="true">
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource CheckedOff}"
                                 x:Name="CheckedOff_BeginStoryboard" />
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource CheckedOn}"
                                 x:Name="CheckedOn_BeginStoryboard" />
            </Trigger.EnterActions>
        </Trigger>
        <Trigger Property="IsEnabled"
                 Value="False">
            <Setter Property="Foreground"
                    Value="{DynamicResource DisabledForegroundBrush}" />
            <Setter Property="Visibility"
                    TargetName="DisabledVisualElement"
                    Value="Visible" />
            <Setter Property="Fill"
                    TargetName="Background"
                    Value="{DynamicResource DisabledBackgroundBrush}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<ControlTemplate x:Key="ComboBoxTextBox"
                 TargetType="{x:Type TextBox}">
    <Border x:Name="PART_ContentHost"
            Focusable="False"
            Background="{TemplateBinding Background}" />
</ControlTemplate>

<Style TargetType="{x:Type ComboBox}">
    <Setter Property="SnapsToDevicePixels"
            Value="true" />
    <Setter Property="HorizontalContentAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Center" />
    <Setter Property="FontSize"
            Value="13" />
    <Setter Property="FontWeight"
            Value="Bold" />
    <Setter Property="Padding"
            Value="6,2,25,2" />
    <Setter Property="Margin"
            Value="3" />
    <Setter Property="ToolTipService.ShowOnDisabled"
            Value="True" />
    <Setter Property="Template"
            Value="{DynamicResource ComboBoxTemplate}" />
    <Setter Property="Validation.ErrorTemplate"
            Value="{StaticResource SablonaChybovehoHlaseni}" />
</Style>

<ControlTemplate x:Key="ComboBoxTemplate"
                 TargetType="{x:Type ComboBox}">
    <ControlTemplate.Resources>
        <Storyboard x:Key="FocusedOn">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="FocusVisualElement"
                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.1000000"
                                      Value="1" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="FocusedOff">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
                                           Storyboard.TargetName="FocusVisualElement"
                                           Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000"
                                      Value="0" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </ControlTemplate.Resources>
    <Grid>
        <ToggleButton Grid.Column="2"
                      Template="{DynamicResource ComboBoxToggleButton}"
                      x:Name="ToggleButton"
                      Focusable="false"
                      IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                      ClickMode="Press" />
        <ContentPresenter HorizontalAlignment="Stretch"
                          Margin="3,3,23,3"
                          x:Name="ContentSite"
                          VerticalAlignment="Top"
                          Content="{TemplateBinding SelectionBoxItem}"
                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                          IsHitTestVisible="True">
            <ContentPresenter.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"
                               TextWrapping="Wrap" />
                </DataTemplate>
            </ContentPresenter.ContentTemplate>
        </ContentPresenter>
        <!--Textbox for ComboBox-->
        <!--Set transparent background of TextBox-->
        <TextBox Visibility="Hidden"
                 Template="{DynamicResource ComboBoxTextBox}"
                 HorizontalAlignment="Stretch"
                 Margin="3,3,23,3"
                 x:Name="PART_EditableTextBox"
                 Style="{x:Null}"
                 VerticalAlignment="Top"
                 Focusable="True"
                 Background="Transparent"
                 TextWrapping="Wrap"
                 IsReadOnly="{TemplateBinding IsReadOnly}" />
        <Rectangle x:Name="DisabledVisualElement"
                   Fill="{DynamicResource DisabledBackgroundBrush}"
                   Stroke="{DynamicResource DisabledBorderBrush}"
                   RadiusX="3"
                   RadiusY="3"
                   IsHitTestVisible="false"
                   Opacity="0" />
        <Rectangle x:Name="FocusVisualElement"
                   Margin="-1"
                   RadiusX="3"
                   RadiusY="3"
                   Stroke="{DynamicResource FocusBrush}"
                   StrokeThickness="1"
                   IsHitTestVisible="false"
                   Opacity="0" />
        <Popup IsOpen="{TemplateBinding IsDropDownOpen}"
               Placement="Bottom"
               x:Name="Popup"
               Focusable="False"
               AllowsTransparency="True"
               PopupAnimation="Slide"
               Margin="0,1,0,0">
            <Grid MaxHeight="{TemplateBinding MaxDropDownHeight}"
                  MinWidth="{TemplateBinding ActualWidth}"
                  x:Name="DropDown"
                  SnapsToDevicePixels="True">
                <Border x:Name="DropDownBorder"
                        Margin="0,-1,0,0"
                        BorderBrush="{DynamicResource ControlBorderBrush}"
                        BorderThickness="1"
                        CornerRadius="0,0,3,3"
                        Background="{DynamicResource WhiteColorBrush}">
                    <!--ControlBackgroundBrush-->
                    <ScrollViewer Margin="4,6,4,6"
                                  SnapsToDevicePixels="True"
                                  HorizontalScrollBarVisibility="Auto"
                                  VerticalScrollBarVisibility="Auto"
                                  CanContentScroll="True">
                        <StackPanel IsItemsHost="True"
                                    KeyboardNavigation.DirectionalNavigation="Contained" />

                    </ScrollViewer>
                </Border>
            </Grid>
        </Popup>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsFocused"
                 Value="True">
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource FocusedOff}"
                                 x:Name="FocusedOff_BeginStoryboard" />
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource FocusedOn}" />
            </Trigger.EnterActions>
            <Setter Property="CornerRadius"
                    TargetName="DropDownBorder"
                    Value="3" />
        </Trigger>
        <Trigger Property="HasItems"
                 Value="false">
            <Setter Property="MinHeight"
                    Value="95"
                    TargetName="DropDownBorder" />
        </Trigger>
        <Trigger Property="IsEnabled"
                 Value="false">
            <Setter Property="Foreground"
                    Value="{DynamicResource DisabledForegroundBrush}" />
            <Setter Property="Opacity"
                    TargetName="DisabledVisualElement"
                    Value="1" />
        </Trigger>
        <Trigger Property="IsGrouping"
                 Value="true">
            <Setter Property="ScrollViewer.CanContentScroll"
                    Value="false" />
        </Trigger>
        <Trigger Property="AllowsTransparency"
                 SourceName="Popup"
                 Value="true">
            <Setter Property="CornerRadius"
                    Value="4"
                    TargetName="DropDownBorder" />
            <Setter Property="Margin"
                    Value="0,2,0,0"
                    TargetName="DropDownBorder" />
        </Trigger>
        <Trigger Property="IsEditable"
                 Value="true">
            <Setter Property="IsTabStop"
                    Value="false" />
            <Setter Property="Visibility"
                    Value="Visible"
                    TargetName="PART_EditableTextBox" />
            <Setter Property="Visibility"
                    Value="Hidden"
                    TargetName="ContentSite" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
1个回答

4

ComboBox有两种用法。第一种是当IsEditable为false时。在这种情况下,用户只能选择预定义的项目。第二种情况是当IsEditable为true时,用户既可以输入文本,也可以选择预定义的项。

使用默认的Aero样式时,单击“文本”区域(即当IsEditable为true时)不会弹出下拉菜单。单击将聚焦/选择文本。但其他样式则会打开下拉菜单。

为了实现这一点,透明的ToggleButton被放置在其他控件之上,可切换下拉菜单的可见性。代码示例如下:

<Grid Grid.IsSharedSizeScope="true">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"
                          SharedSizeGroup="ComboBoxButton"/>
    </Grid.ColumnDefinitions>
    <TextBox x:Name="PART_EditableTextBox"
             Grid.Column="1"
             Style="{StaticResource ComboBoxEditableTextBox}"
             IsReadOnly="{Binding Path=IsReadOnly,RelativeSource={RelativeSource TemplatedParent}}"
             Margin="{TemplateBinding Padding}"
             HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
             VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
    <ToggleButton Background="{x:Null}"
                  Grid.ColumnSpan="3"
                  Style="{StaticResource ComboBoxTransparentButtonStyle}"
                  IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>

这是从Luna默认样式中提取的,您可以从这里获取(或直接从这里下载)。


1
谢谢,你让我朝着正确的方向前进了。我按照你的示例,在其他控件上添加了一个不可见的ToggleButton来解决它:<ToggleButton Grid.ColumnSpan="3" Opacity="0" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" /> - Honza Pačuta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接