使用自定义项目模板在ComboBox中显示所选项目 [英] Show selected item in ComboBox with custom item template

查看:65
本文介绍了使用自定义项目模板在ComboBox中显示所选项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了此页面上的代码来设置组合框的样式:如何在鼠标悬停时设置组合框背景的样式?

我更改了默认项目模板,但现在它们不会出现在所选值区域中.在下面的图像中,您可以看到问题以及我想要实现的目标.

这是我在App.xaml中的XAML:

<LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFF3F3F3"/>
    <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFF3F3F3"/>
    <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundHoverBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFE4E4E4"/>
    <GradientStop Offset="0.3" Color="#FFBBBBBB"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundDisabledBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FF636363"/>
    <GradientStop Offset="0.3" Color="#FF4E4D4D"/>
</LinearGradientBrush>

<SolidColorBrush x:Key="GlyphBrush" Color="#FFF" />

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>

        <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="{StaticResource ButtonBackgroundBrush}" BorderBrush="#FF898989" BorderThickness="1" />
        <Border x:Name="Border2" Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="White" BorderBrush="#FF898989" BorderThickness="0,0,1,0" />

        <Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource GlyphBrush}" 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="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
            <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
            <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
            <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
            <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundDisabledBrush}" />
            <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

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

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="MinWidth" Value="120"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
                    <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" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
                    <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
                        <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border x:Name="DropDownBorder" Background="White" BorderThickness="1" BorderBrush="#FF898989" />
                            <ScrollViewer Margin="4,6,4,6" 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="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="True">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,2,2"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,-1,0,0"/>
                    </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>

<Style x:Name="CustomComboboxItem" TargetType="ComboBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid Grid.Column="1">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                        </Grid.RowDefinitions>
                        <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                        <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                    </Grid>
                </Grid>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="LightGray"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MainWindow.xaml:

<ComboBox Height="40" HorizontalAlignment="Left" Margin="102,64,0,0" Name="comboBox1" VerticalAlignment="Top" Width="459" />

隐藏代码:

public MainWindow()
{
    InitializeComponent();

    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 1", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 2", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 3", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 4", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 5", NewItemComment = "hello :)" });
}

public class CustomComboboxItem
{
    public string NewItemName { get; set; }
    public string NewItemComment { get; set; }
}

有人可以告诉我我在做什么错吗?

解决方案

您可以为ComboBox定义ItemTemplate而不是为ComboBoxItem定义ControlTemplate来实现.如您所见,ComboBoxItem的ControlTemplate不会影响ItemTemplate时所选项目的外观.以下是CustomComboboxItem样式在ComboBox样式中合并的内容:

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
        ........
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid>
                        <Grid.Style>
                            <Style TargetType="Grid">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="LightGray"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Grid.Style>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                            <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                        </Grid>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        ........
    </Style>

I used the code from this page to style my combobox: How to style ComboBox Background on Mouse Hover?

I've changed my default item template, but now they won't appear in the selected value area. In the image below you can see the problem and what I want to achieve.

This is my XAML in App.xaml:

<LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFF3F3F3"/>
    <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFF3F3F3"/>
    <GradientStop Offset="0.3" Color="#FFCCCCCC"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundHoverBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FFE4E4E4"/>
    <GradientStop Offset="0.3" Color="#FFBBBBBB"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="ButtonBackgroundDisabledBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Offset="0" Color="#FF636363"/>
    <GradientStop Offset="0.3" Color="#FF4E4D4D"/>
</LinearGradientBrush>

<SolidColorBrush x:Key="GlyphBrush" Color="#FFF" />

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />

<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="ToggleButton">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="20" />
        </Grid.ColumnDefinitions>

        <Border x:Name="Border" Grid.ColumnSpan="2" CornerRadius="2" Background="{StaticResource ButtonBackgroundBrush}" BorderBrush="#FF898989" BorderThickness="1" />
        <Border x:Name="Border2" Grid.Column="0" CornerRadius="2,0,0,2" Margin="1" Background="White" BorderBrush="#FF898989" BorderThickness="0,0,1,0" />

        <Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource GlyphBrush}" 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="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
            <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
            <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundHoverBrush}" />
            <Setter TargetName="Border" Property="BorderBrush" Value="#FF59B7FF" />
            <Setter TargetName="Border2" Property="BorderBrush" Value="#FF59B7FF" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Border" Property="Background" Value="{StaticResource ButtonBackgroundDisabledBrush}" />
            <Setter TargetName="Arrow" Property="Fill" Value="{StaticResource DisabledForegroundBrush}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

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

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="MinWidth" Value="120"/>
    <Setter Property="MinHeight" Value="20"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
                <Grid>
                    <ToggleButton Name="ToggleButton" Template="{StaticResource ComboBoxToggleButton}" Grid.Column="2" Focusable="False" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" />
                    <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" Style="{x:Null}" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Focusable="True" Background="Transparent" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}" />
                    <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
                        <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
                            <Border x:Name="DropDownBorder" Background="White" BorderThickness="1" BorderBrush="#FF898989" />
                            <ScrollViewer Margin="4,6,4,6" 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="95"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsGrouping" Value="True">
                        <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                    </Trigger>
                    <Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
                        <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0,0,2,2"/>
                        <Setter TargetName="DropDownBorder" Property="Margin" Value="0,-1,0,0"/>
                    </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>

<Style x:Name="CustomComboboxItem" TargetType="ComboBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="30"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid Grid.Column="1">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                        </Grid.RowDefinitions>
                        <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                        <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                    </Grid>
                </Grid>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="LightGray"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MainWindow.xaml:

<ComboBox Height="40" HorizontalAlignment="Left" Margin="102,64,0,0" Name="comboBox1" VerticalAlignment="Top" Width="459" />

Code-behind:

public MainWindow()
{
    InitializeComponent();

    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 1", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 2", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 3", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 4", NewItemComment = "hello :)" });
    comboBox1.Items.Add(new CustomComboboxItem { NewItemName = "Item 5", NewItemComment = "hello :)" });
}

public class CustomComboboxItem
{
    public string NewItemName { get; set; }
    public string NewItemComment { get; set; }
}

Can someone tell me what I'm doing wrong?

解决方案

You can define ItemTemplate for ComboBox instead of ControlTemplate for ComboBoxItem to achieve that. As you can see, ControlTemplate for ComboBoxItem doesn't affect selected item appearance when ItemTemplate does. Following is content of your CustomComboboxItem Style merged within ComboBox Style :

<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
        ........
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid>
                        <Grid.Style>
                            <Style TargetType="Grid">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="LightGray"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Grid.Style>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="30"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                                <RowDefinition Height="16" MinHeight="16" MaxHeight="16" />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding NewItemName}" Grid.Row="0" FontWeight="Bold" />
                            <TextBlock Text="{Binding NewItemComment}" Grid.Row="1" FontStyle="Italic" Foreground="#FF555454" />
                        </Grid>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        ........
    </Style>

这篇关于使用自定义项目模板在ComboBox中显示所选项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆