WPF ComboBox 中带有列的不可选择标题

发布于 2024-10-14 11:04:56 字数 2094 浏览 1 评论 0 原文

我有一个自定义控件,其中包含一个组合框,我在其中创建了多个数据列。 这很好用,但我一直无法弄清楚如何将标题行置于下拉菜单的顶部,并为每列提供标题。另外,如果可能的话,它希望能够对其进行样式设置,以便行交替颜色。鉴于下面的 XAML,我有什么想法可以做到这一点吗?

<UserControl x:Class="ActualsAllocations.LegalEntityDropDown"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="28" d:DesignWidth="400">
    <UserControl.Resources>
        <ResourceDictionary>
            <Style x:Key="MainComboStyle" TargetType="{x:Type ComboBoxItem}">
                <Style.Triggers>
                </Style.Triggers>
            </Style >
        </ResourceDictionary>
    </UserControl.Resources>
    <DockPanel>
        <Label Name="lblTitle" Width="75" Content="Title" Margin="3,3"/>
        <ComboBox Name="cmbMain" HorizontalAlignment="Stretch" Margin="3,3" ItemsSource="{Binding}"  ItemContainerStyle="{StaticResource MainComboStyle}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                        <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ComboBox>
    </DockPanel>
</UserControl>

I have a custom control that contains a ComboBox in which I've created multiple data columns.
This works great, but I have been unable to figure out how to head a header row to the top of the drop down with titles for each of the columns. Also, if possible it would love to be able to style it so that the rows alternate colors. Given the XAML below, any ideas of how I can do this?

<UserControl x:Class="ActualsAllocations.LegalEntityDropDown"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="28" d:DesignWidth="400">
    <UserControl.Resources>
        <ResourceDictionary>
            <Style x:Key="MainComboStyle" TargetType="{x:Type ComboBoxItem}">
                <Style.Triggers>
                </Style.Triggers>
            </Style >
        </ResourceDictionary>
    </UserControl.Resources>
    <DockPanel>
        <Label Name="lblTitle" Width="75" Content="Title" Margin="3,3"/>
        <ComboBox Name="cmbMain" HorizontalAlignment="Stretch" Margin="3,3" ItemsSource="{Binding}"  ItemContainerStyle="{StaticResource MainComboStyle}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                        <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                        <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ComboBox>
    </DockPanel>
</UserControl>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秉烛思 2024-10-21 11:04:56

关于行的替代颜色,我会尝试使用 ItemTemplateSelector 您可以阅读有关 在这里

对于标题,我会尝试使用描述的CompositeCollection此处

如果您选择这个 ItemTemplateSelector ,您不需要为标头使用不同的模板,因为它已经是 ComboBoxItem 并且 Template 将被忽略。

ItemTemplateSelector 的代码:

public class CustomTemplateSelector : DataTemplateSelector
{        
    public DataTemplate EvenTemplate { get; set; }        

    public DataTemplate OddTemplate { get; set; }

    public CollectionViewSource Collection { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var list = Collection.Source as IList;
        if (list != null)
        {

            if (list.IndexOf(item) % 2 == 0)
            {
                return EvenTemplate;
            }
            else
            {
                return OddTemplate;
            }
        }
        return EvenTemplate;
    }
}

组合框的 Xaml:

<DockPanel>
        <DockPanel.Resources>
            <Style x:Key="MainComboStyle" TargetType="{x:Type ComboBoxItem}">
                <Style.Triggers></Style.Triggers>
            </Style >

            <CollectionViewSource x:Key="list" Source="{Binding}"/>

            <DataTemplate x:Key="EventTemplate">
                <StackPanel Orientation="Horizontal" Background="Red">
                    <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                    <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                </StackPanel>
            </DataTemplate>

            <DataTemplate x:Key="OddTemplate">
                <StackPanel Orientation="Horizontal" Background="Green">
                    <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                    <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                </StackPanel>
            </DataTemplate>


            <local:CustomTemplateSelector OddTemplate="{StaticResource OddTemplate}" 
                                          EvenTemplate="{StaticResource EventTemplate}" 
                                          Collection="{StaticResource list}"
                                         x:Key="customTemplateSelector" />


        </DockPanel.Resources>
        <Label Name="lblTitle" Width="75" Content="Title" Margin="3,3"/>
        <ComboBox Name="cmbMain" HorizontalAlignment="Stretch" Margin="3,3" 
                  ItemTemplateSelector="{StaticResource customTemplateSelector}" >                
            <ComboBox.ItemsSource>
                <CompositeCollection>
                    <ComboBoxItem IsEnabled="False" Foreground="Black"> VersionID | VersionName | EndDate | CreatedByUser | CreateDate</ComboBoxItem>
                    <CollectionContainer Collection="{Binding Source={StaticResource list}}"/>
                </CompositeCollection>
            </ComboBox.ItemsSource>
        </ComboBox>
    </DockPanel>

您可以考虑制作样式标头,这样会更好。您还可以将此数据模板的一部分放在单独的控件中,这样就可以避免重复代码。

About alternate colors for rows I would try using ItemTemplateSelector you can read about that here.

For header I would try using CompositeCollection described here.

If you go for this ItemTemplateSelector you don't need to different template for header as it will be already ComboBoxItem and Template will be ignored.

Code for ItemTemplateSelector:

public class CustomTemplateSelector : DataTemplateSelector
{        
    public DataTemplate EvenTemplate { get; set; }        

    public DataTemplate OddTemplate { get; set; }

    public CollectionViewSource Collection { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var list = Collection.Source as IList;
        if (list != null)
        {

            if (list.IndexOf(item) % 2 == 0)
            {
                return EvenTemplate;
            }
            else
            {
                return OddTemplate;
            }
        }
        return EvenTemplate;
    }
}

Xaml for combobox:

<DockPanel>
        <DockPanel.Resources>
            <Style x:Key="MainComboStyle" TargetType="{x:Type ComboBoxItem}">
                <Style.Triggers></Style.Triggers>
            </Style >

            <CollectionViewSource x:Key="list" Source="{Binding}"/>

            <DataTemplate x:Key="EventTemplate">
                <StackPanel Orientation="Horizontal" Background="Red">
                    <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                    <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                </StackPanel>
            </DataTemplate>

            <DataTemplate x:Key="OddTemplate">
                <StackPanel Orientation="Horizontal" Background="Green">
                    <TextBlock Text="{Binding Path=VersionID}" Width="25" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=VersionName}" Width="220" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=EndDate, StringFormat={}{0:M/yyyy}}" Width="50" Margin="3,0" />
                    <TextBlock Text="{Binding Path=CreatedByUserName}" Width="100" Margin="3,0"/>
                    <TextBlock Text="{Binding Path=CreateDate}" Width="120" Margin="3,0"/>
                </StackPanel>
            </DataTemplate>


            <local:CustomTemplateSelector OddTemplate="{StaticResource OddTemplate}" 
                                          EvenTemplate="{StaticResource EventTemplate}" 
                                          Collection="{StaticResource list}"
                                         x:Key="customTemplateSelector" />


        </DockPanel.Resources>
        <Label Name="lblTitle" Width="75" Content="Title" Margin="3,3"/>
        <ComboBox Name="cmbMain" HorizontalAlignment="Stretch" Margin="3,3" 
                  ItemTemplateSelector="{StaticResource customTemplateSelector}" >                
            <ComboBox.ItemsSource>
                <CompositeCollection>
                    <ComboBoxItem IsEnabled="False" Foreground="Black"> VersionID | VersionName | EndDate | CreatedByUser | CreateDate</ComboBoxItem>
                    <CollectionContainer Collection="{Binding Source={StaticResource list}}"/>
                </CompositeCollection>
            </ComboBox.ItemsSource>
        </ComboBox>
    </DockPanel>

You can consider making styling header so it will be nicer. Also you can put part of this dataTemplates in separate control so you can avoid repeating code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文