如何创建自定义组合框按钮?

时间:2014-04-03 10:29:38

标签: wpf xaml

下面是我的组合框代码,它有另外两个组合框,现在我想要使用combobox2切换按钮改变它的方向,即切换按钮应指向右边,也可以点击切换按钮组合框应该在右侧打开,这样它就不会隐藏我的组合框1项,怎么做?

<Window x:Class="ComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
        <Color x:Key="GrayColor_">#FF928B81</Color>
        <Color x:Key="LightGrayColor_">#FFC3C3C3</Color>
        <Color x:Key="LightLightGrayColor_">#FFF1F1F1</Color>
        <SolidColorBrush x:Key="GrayColor" Color="{StaticResource GrayColor_}"/>
        <SolidColorBrush x:Key="LightGrayColor" Color="{StaticResource LightGrayColor_}"/>
        <SolidColorBrush x:Key="LightLightGrayColor" Color="{StaticResource LightLightGrayColor_}"/>

        <Color x:Key="BlueColor_">#0073b0</Color>
        <Color x:Key="DarkBlueColor_">#FF004165</Color>
        <Color x:Key="LightBlueColor_">#FFa4ddfa</Color>
        <SolidColorBrush x:Key="BlueColor" Color="{StaticResource BlueColor_}" />
        <SolidColorBrush x:Key="DarkBlueColor" Color="{StaticResource DarkBlueColor_}" />
        <SolidColorBrush x:Key="LightBlueColor" Color="{StaticResource LightBlueColor_}" />

        <SolidColorBrush x:Key="Foreground" Color="Black"/>
        <SolidColorBrush x:Key="ForegroundWhite" Color="White"/>


        <Style x:Key="LightGrayBox" TargetType="{x:Type Border}">
            <Setter Property="Background" Value="White"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="BorderBrush" Value="{StaticResource LightGrayColor}" />
        </Style>


        <Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition Width="20"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="Border" Style="{DynamicResource LightGrayBox}" Grid.ColumnSpan="2" Background="{StaticResource BlueColor}" />
                            <Path x:Name="Arrow" Grid.Column="1" Opacity="0.6" Fill="{StaticResource LightBlueColor}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="ToggleButton.IsMouseOver" Value="true">
                                <Setter TargetName="Arrow" Property="Opacity" Value="1" />
                                <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource LightBlueColor}" />
                                <Setter TargetName="Border" Property="BorderBrush" Value="{DynamicResource BlueColor}"/>
                            </Trigger>
                            <Trigger Property="ToggleButton.IsChecked" Value="true">
                                <Setter TargetName="Arrow" Property="Opacity" Value="1" />
                                <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource LightBlueColor}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="ComboBoxToggleButtonActive" TargetType="{x:Type ToggleButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition Width="20"/>
                            </Grid.ColumnDefinitions>
                            <Border x:Name="Border" Grid.ColumnSpan="2" Background="{DynamicResource BlueColor}" />
                            <Path x:Name="Arrow" Grid.Column="1" Opacity="1" Fill="{StaticResource LightBlueColor}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsFocused" Value="true">
                                <Setter TargetName="Border" Property="Background" Value="{DynamicResource BlueColor}" />
                                <Setter TargetName="Border" Property="BorderBrush" Value="White"/>
                                <Setter Property="Foreground" Value="White" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

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

        <Style x:Key="StandardComboBox" TargetType="{x:Type ComboBox}">
            <Setter Property="Foreground" Value="{StaticResource Foreground}"/>
            <Setter Property="Height" Value="25"/>
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="IsEditable" Value="True" />
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
            <Setter Property="VerticalAlignment" Value="Top"/>
            <Setter Property="Width" Value="120"/>
            <Setter Property="IsSelected" Value="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}, Mode=OneWay}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ComboBox">
                        <Grid>
                            <ToggleButton Name="ToggleButton" Style="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="false" ClickMode="Press"
                                      IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
                            <Label Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                               ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
                            <!--<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
                                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />-->
                            <TextBox x:Name="PART_EditableTextBox" 
                                 CaretBrush="{DynamicResource ForegroundWhite}"
                                 Style="{x:Null}" 
                                 Template="{StaticResource ComboBoxTextBox}" 
                                 HorizontalAlignment="Left" 
                                 VerticalAlignment="Center" 
                                 Margin="3,3,23,3" 
                                 Focusable="True" 
                                 Background="Transparent" 
                                 Foreground="{StaticResource ForegroundWhite}" 
                                 Visibility="Hidden"
                                 IsReadOnly="{TemplateBinding IsReadOnly}"/>
                            <Popup VerticalOffset="-1" SnapsToDevicePixels="True" Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True"  Focusable="False" PopupAnimation="Fade">
                                <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="200">
                                    <Border x:Name="DropDownBorder" Style="{DynamicResource LightGrayBox}"/>
                                    <ScrollViewer SnapsToDevicePixels="True">
                                        <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                    </ScrollViewer>
                                </Grid>
                            </Popup>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="HasItems" Value="false">
                                <Setter TargetName="DropDownBorder" Property="MinHeight" Value="20"/>
                            </Trigger>
                            <Trigger Property="IsGrouping" Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                            </Trigger>
                            <Trigger Property="IsSelected"  Value="True">
                                <Setter TargetName="ToggleButton" Property="Style" Value="{StaticResource ComboBoxToggleButtonActive}" />
                                <Setter TargetName="ContentSite" Property="Foreground" Value="{DynamicResource ForegroundWhite}"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="False">
                                <Setter TargetName="PART_EditableTextBox" Property="Foreground" Value="{DynamicResource Foreground}"/>
                                <Setter TargetName="ContentSite" Property="Foreground" Value="{DynamicResource Foreground}"/>
                            </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>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Resources>
                <Style TargetType="ComboBoxItem">
                    <Setter Property="SnapsToDevicePixels" Value="true"/>
                    <Setter Property="OverridesDefaultStyle" Value="true"/>
                    <Setter Property="HorizontalContentAlignment" Value="Left" />
                    <Setter Property="VerticalContentAlignment" Value="Center" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ComboBoxItem">
                                <Border Name="Border" Padding="2" SnapsToDevicePixels="true" BorderThickness="1" Background="{StaticResource BlueColor}">
                                    <ContentPresenter />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsHighlighted" Value="true">
                                        <Setter TargetName="Border" Property="Background" Value="{DynamicResource BlueColor}"/>
                                        <Setter TargetName="Border" Property="Padding" Value="2,3,2,3" />
                                        <Setter Property="Foreground" Value="White" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>

                </Style>

            </Style.Resources>
        </Style>
    </Window.Resources>


    <Grid>
        <ComboBox Height="23" Margin="122,32,100,0" Style="{StaticResource StandardComboBox}"  Name="comboBox1" VerticalAlignment="Top" IsEditable="True" Text="Settings">
            <ComboBoxItem>
                <ComboBox Style="{StaticResource StandardComboBox}" Name="comboBox2" VerticalAlignment="Top" >

                   <StackPanel Orientation="Horizontal">
                        <Label Content="Logout Time:"></Label>
                        <Label></Label>
                    </StackPanel>
                    <ComboBoxItem Content="10 Min"></ComboBoxItem>
                    <ComboBoxItem Content="20 Min"></ComboBoxItem>
                    <ComboBoxItem Content="30 Min"></ComboBoxItem>
                    <ComboBoxItem Content="40 Min"></ComboBoxItem>
                    <ComboBoxItem Content="50 Min"></ComboBoxItem>
                </ComboBox>
            </ComboBoxItem>
            <ComboBoxItem Content="Logout"></ComboBoxItem>
        </ComboBox>
    </Grid>
</Window>

2 个答案:

答案 0 :(得分:0)

您需要为ComboBox控件定义一个新的ControlTemplate。您可以在MSDN上的Customizing the Appearance of an Existing Control by Using a ControlTemplate文章中找到如何定义新的ControlTemplate。一个好的起点是实现默认的ControlTemplate,然后根据需要自定义它。您可以在MSDN上的ComboBox Styles and Templates页面中找到ComboBox的默认ControlTemplate。

作为起点,从MSDN上链接页面的默认ControlTemplate中找到以下控件:

<ToggleButton x:Name="ToggleButton"
            Template="{StaticResource ComboBoxToggleButton}"
            Grid.Column="2"
            Focusable="false"
            ClickMode="Press"
            IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, 
            RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter x:Name="ContentSite"
                IsHitTestVisible="False"
                Content="{TemplateBinding SelectionBoxItem}"
                ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                Margin="3,3,23,3"
                VerticalAlignment="Stretch"
                HorizontalAlignment="Left">
</ContentPresenter>
<TextBox x:Name="PART_EditableTextBox"
       Style="{x:Null}"
       Template="{StaticResource ComboBoxTextBox}"
       HorizontalAlignment="Left"
       VerticalAlignment="Bottom"
       Margin="3,3,23,3"
       Focusable="True"
       Background="Transparent"
       Visibility="Hidden"
       IsReadOnly="{TemplateBinding IsReadOnly}" />

ToggleButton显然是Button控件中的ComboBoxContentSite ContentPresenter是所选项目显示在ButtonPART_EditableTextBox TextBox旁边的位置{1}}是控件设置为TextBox时使用的可编辑IsEditable="True"。如果您可以编写XAML,那么您可以简单地安排这些内部控件以满足您的要求。


更新&gt;&gt;&gt;

为了旋转控件,最简单的方法是使用RotateTransform ...试试这个:

<Path x:Name="Arrow" Grid.Column="1" HorizontalAlignment="Center" 
    VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" >
    <Path.Fill>
        <SolidColorBrush Color="{DynamicResource GlyphColor}"/>
    </Path.Fill>
    <Path.LayoutTransform>
        <RotateTransform Angle="90" />
    </Path.LayoutTransform>
</Path>

更新2(希望最后一次)&gt;&gt;&gt;

ComboBox弹出窗口是Popup控件,因此要了解如何向右打开它,您需要研究如何向右打开Popup。为此,我要查看MSDN上Popup Placement Behavior页面的弹出窗口定位部分。

现在,请记住,我们不是为您完成所有您的工作。我觉得我已为您提供了足够的信息,以便完成自定义ComboBox控制。祝你好运。

答案 1 :(得分:0)

可能会有帮助

          <ComboBox Height="23" Margin="122,32,100,0" Style="{StaticResource StandardComboBox}"  Name="comboBox1" VerticalAlignment="Top" IsEditable="True" Text="Settings">
    <ComboBoxItem>
        <ComboBox ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Hidden"   Name="comboBox2"  VerticalAlignment="Top">
            <ComboBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal"   IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ComboBox.ItemsPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Logout Time:"></Label>
                <Label></Label>
            </StackPanel>
            <ComboBoxItem Content="10 Min"></ComboBoxItem>
            <ComboBoxItem Content="20 Min"></ComboBoxItem>
            <ComboBoxItem Content="30 Min"></ComboBoxItem>
            <ComboBoxItem Content="40 Min"></ComboBoxItem>
            <ComboBoxItem Content="50 Min"></ComboBoxItem>

            </ComboBox>
        </ComboBoxItem>
        <ComboBoxItem Content="Logout">

        </ComboBoxItem>
    </ComboBox>


</Grid>