【问题标题】:C# WPF ComboBox complex custom pop-up data displayC# WPF ComboBox 复杂自定义弹出数据显示
【发布时间】:2018-04-13 19:41:07
【问题描述】:

所以,有一个具有自定义组合框样式的程序,让它看起来更扁平。它显示用户名,最近收到了将某些东西添加到弹出框本身的请求,但在选择该项目时没有在“选择”框中显示信息。像这样(红框里的东西就是我要补充的):

这个特定的组合框填充了一个作为自定义数据结构的项目源,所以我有数据,我只需要看看我该怎么做。

这是我的自定义样式:

    <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>

【问题讨论】:

    标签: c# wpf combobox


    【解决方案1】:

    在选择框中以不同方式显示项目的一种快速但有点脏的方法是通过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

    【讨论】:

    • 我实际上尝试过这个,但该信息仍然显示在选择区域中。我正在寻找将自定义内容添加到组合框的弹出部分。我更新了我的照片,使其更加清晰。
    • @DavidBentley 啊,好的。有一种方法可以编写触发器,将用户数据隐藏在选择框中显示的项目中。我已经完成了,但我将不得不再次谷歌它。例如,如果没有作为 ComboBoxItem 的父项,则它不在弹出窗口中。我想。嗯,我想知道你是否可以设置 ComboBoxItem 的样式来设置项目模板...
    • 谢谢!!这看起来会奏效。我完全忘记了SelectionBoxItem 不是ComboBoxItem 的孩子。
    猜你喜欢
    • 2021-07-31
    • 2016-03-12
    • 2013-08-23
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多