C#WPF ComboBox复杂的自定义弹出数据显示

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#WPF ComboBox复杂的自定义弹出数据显示相关的知识,希望对你有一定的参考价值。

因此,拥有一个具有自定义组合框样式的程序,使其外观更平整。它显示用户名,并且最近收到了向弹出框本身添加内容的请求,但在选择该项时,选项框中没有显示信息。像这样的东西(红色框中的东西是我想要添加的东西):

enter image description here

这个特殊的组合框填充了一个自定义数据结构的项目源,所以我有数据,我只需要看看如何做到这一点。

这是我的自定义样式:

    <Style x:Key="ComboBoxFlatStyle" TargetType="{x:Type ComboBox}">
        <Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
        <Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
        <Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid>
                        <ToggleButton Name="ToggleButton" Grid.Column="2"
                                      ClickMode="Press"
                                      Focusable="False"
                                      IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                                      Template="{StaticResource ComboBoxToggleButtonTemplate}"/>

                        <ContentPresenter Name="ContentSite" Margin="5,3,23,3" IsHitTestVisible="False"
                                          HorizontalAlignment="Left" VerticalAlignment="Center"
                                          Content="{TemplateBinding ComboBox.SelectionBoxItem}"
                                          ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
                                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>

                        <TextBox Name="PART_EditableTextBox" Margin="3,3,23,3"                     
                                 IsReadOnly="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=IsReadOnly}"
                                 Visibility="Hidden"
                                 Background="Transparent"
                                 Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Foreground}"
                                 HorizontalAlignment="Left" VerticalAlignment="Center"
                                 Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Focusable}">

                            <TextBox.Template>
                                <ControlTemplate TargetType="{x:Type TextBox}">
                                    <Border Name="PART_ContentHost"
                                            Focusable="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Focusable}"/>
                                </ControlTemplate>
                            </TextBox.Template>
                        </TextBox>
                        <!-- Popup showing items -->
                        <Popup Name="Popup"
                               Placement="Bottom"
                               Focusable="False"
                               AllowsTransparency="True"
                               IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"
                               PopupAnimation="Slide">

                            <Grid Name="DropDown" SnapsToDevicePixels="True"
                                  MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
                                  MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}">

                                <Border Name="DropDownBorder" Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Background}"
                                        Margin="0,1,0,0"
                                        CornerRadius="0" BorderThickness="1,1,1,1"
                                        BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=BorderBrush}"/>

                                <ScrollViewer Margin="4" SnapsToDevicePixels="True">
                                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
                                </ScrollViewer>
                            </Grid>
                        </Popup>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="ItemsControl.HasItems" Value="False">
                            <Setter Property="FrameworkElement.MinHeight" TargetName="DropDownBorder" 
                                    Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=MaxDropDownHeight}"/>
                        </Trigger>
                        <Trigger Property="UIElement.IsEnabled" Value="False">
                            <Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
                        </Trigger>
                        <Trigger Property="ItemsControl.IsGrouping" Value="True">
                            <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
                        </Trigger>
                        <Trigger Property="ComboBox.IsEditable" Value="True">
                            <Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
                            <Setter Property="UIElement.Visibility" TargetName="PART_EditableTextBox" Value="Visible"/>
                            <Setter Property="UIElement.Visibility" TargetName="ContentSite" Value="Hidden"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
答案

在选择框中以不同方式显示项目的快速且有点脏的方法是通过ItemContainerStyle设置项目模板:选择框内容不是ComboBoxItem的内容,因此模板不应用于它。

<ComboBox
    VerticalAlignment="Top"
    ItemsSource="{Binding Items}"
    DisplayMemberPath="Name"
    HorizontalContentAlignment="Stretch"
    >
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <DockPanel LastChildFill="False">
                            <ContentControl Content="{Binding Name}" DockPanel.Dock="Left" />
                            <ContentControl Content="{Binding Value}" DockPanel.Dock="Right" />
                        </DockPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

但你不能用ComboBox.ItemTemplate;它将覆盖您通过样式应用的模板。更强大的solution is to write a template selector, as in this answer

以上是关于C#WPF ComboBox复杂的自定义弹出数据显示的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF - 组合框

Wpf的comboBox怎么绑定数据?

弹出窗口 WPF 表单自定义控件内容

c# WPF Telerik combobox 多选自定义显示值

具有在 XAML 中定义的选项的数据绑定 WPF ComboBox?

wpf 自定义控件combobox 依赖属性