WPF ComboBox 多列

6

我想知道是否有一个可以包含多列的WPF组合框控件?

如果没有,我需要使用什么XAML来实现这个功能?

我只是想要一个基本的两列组合框,如果可能的话,

谢谢。


在WPF中,任何控件都可以通过模板进行修改... - Felice Pollano
https://dev59.com/zn3aa4cB1Zd3GeqPYRdR#22269373 - Heena
4个回答

18

请参考以下链接,了解通过编辑ComboBox和ComboBoxItem的默认模板/样式实现的多列组合框

1)链接1

2)链接2

Xaml代码: 请查看ComboBoxItem样式中的被注释的触发器IsHighlighted

 <Grid>
    <ComboBox Height="30" Margin="5" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Margin="2" Text="{Binding Name}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
        <ComboBox.ItemContainerStyle>
            <Style TargetType="{x:Type ComboBoxItem}">                
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Grid x:Name="gd" TextElement.Foreground="Black">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
                                <TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
                                <TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="ComboBoxItem.IsSelected" Value="True">
                                    <Setter TargetName="gd"  Property="Background" Value="Gray"></Setter>
                                    <Setter TargetName="gd"  Property="TextElement.Foreground" Value="White"></Setter>
                                </Trigger>
                                <Trigger Property="ComboBoxItem.IsMouseOver" Value="True">
                                    <Setter TargetName="gd"  Property="Background" Value="Blue"></Setter>
                                    <Setter TargetName="gd"  Property="TextElement.Foreground" Value="White"></Setter>
                                </Trigger>

                                <!--IsHighlighted and IsMouseOver is showing same effect but IsHighlighted is used for showing logical focus( for understanding check using tab key)-->

                                <!--<Trigger Property="ComboBoxItem.IsHighlighted" Value="True">
                                    <Setter TargetName="gd"  Property="Background" Value="Yellow"></Setter>
                                    <Setter TargetName="gd"  Property="TextElement.Foreground" Value="Black"></Setter>
                                </Trigger>-->
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>
</Grid>

c# 代码

public partial class MainWindow : Window

{

    private ObservableCollection<City> cities = new ObservableCollection<City>();

    public MainWindow()
    {
        InitializeComponent();
        cities.Add(new City() { Name = "Mumbai", State = "Maharashtra", Population = 3000000 });
        cities.Add(new City() { Name = "Pune", State = "Maharashtra", Population = 7000000 });
        cities.Add(new City() { Name = "Nashik", State = "Maharashtra", Population = 65000 });
        cities.Add(new City() { Name = "Aurangabad", State = "Maharashtra", Population = 5000000 });
        DataContext = cities;
    }
}

class City
{
    public string State { get; set; }
    public string Name { get; set; }
    public int Population { get; set; }
}

输出 在这里输入图片描述


2
就此而言,这个答案看起来非常像这个指南 - Jon Peterson

4

我发现,Heena,你的Xaml没有提供选定的下拉项高亮显示,因此我修改了你的代码如下:

Xaml

<ComboBox Name="cbCities" Height="30" Margin="5" HorizontalContentAlignment="Left" HorizontalAlignment="Stretch" ItemsSource="{Binding}" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="2" Text="{Binding Name}"/>
                <TextBlock Margin="2" Text="{Binding State}"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                        <Border Name="templateBorder" Padding="2" SnapsToDevicePixels="true">
                            <ContentPresenter>
                                <ContentPresenter.Content>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                            <ColumnDefinition/>
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
                                        <TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
                                        <TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
                                    </Grid>
                                </ContentPresenter.Content>
                            </ContentPresenter>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsHighlighted" Value="True">
                                <Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
                                <Setter TargetName="templateBorder" Property="Background" Value="{x:Static SystemColors.HighlightBrush}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>  

C#

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    cities.Add(new City() { Name = "Boston", State = "MA", Population = 3000000 });
    cities.Add(new City() { Name = "Los Angeles", State = "CA", Population = 7000000 });
    cities.Add(new City() { Name = "Frederick", State = "MD", Population = 65000 });
    cities.Add(new City() { Name = "Houston", State = "TX", Population = 5000000 });
    cbCities.DataContext = cities;
}

class City
{
    public string State { get; set; }
    public string Name { get; set; }
    public int Population { get; set; }
}  

输出

这里输入图片描述


2
我知道我来晚了,但以下是简化的步骤。在 DataTemplate 标签后面,您可以根据您想要的布局外观放置任何内容。
  <ComboBox.ItemTemplate>
                        <DataTemplate >
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Foreground="{StaticResource ForegroundMainBrush}"
                                           Margin="5 0"
                                           FontFamily="{StaticResource LatoBold}"
                                           VerticalAlignment="Center">
                                    <Run  Text="Code :" />
                                    <Run Text="{Binding ActivityCode,Mode=OneWay}" />
                                </TextBlock>
                                <TextBlock Foreground="{StaticResource ForegroundDarkBrush}"
                                           Margin="5 0"
                                           Text="|"
                                           FontFamily="{StaticResource LatoBold}"
                                           VerticalAlignment="Center" />
                                <TextBlock Foreground="{StaticResource ForegroundMainBrush}"
                                           Margin="5 0"
                                           FontFamily="{StaticResource LatoBold}"
                                           VerticalAlignment="Center">
                                    <Run  Text="Rate :" />
                                    <Run Text="{Binding Rate,Mode=OneWay}" />
                                </TextBlock>
                            </StackPanel>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>

结果

示例结果

或者在您的DataModel中使用只读属性,如下所示的代码,并将您的组合框DisplayMemberPath设置为DisplayMemberPath="CodeRate"

 public string ActivityCode { get; set; }
 public string Rate { get; set; }
 public string CodeRate => string.Format("Code: {0} | Rate: 
 {1}",ActivityCode,Rate);

0

我只是在我的程序中使用了StackPanels。也许每个项目有点冗余,但它确实给了我想要的解决方案,而不需要深入研究太多东西。

        <ComboBox Name="cboTask">
            <StackPanel Orientation="Horizontal">
                <ComboBoxItem Name="someTask" Content="Doing Some Task" /><Button Name="cmdDetails" Content="..." />
            </StackPanel>
        </ComboBox>

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