简体   繁体   English

Combobox:每个DataTrigger的DataTemplate

[英]Combobox : DataTemplate for each DataTrigger

I have two problems, one small and one big, and I need help; 我有两个问题,一是小,一是大,我需要帮助。

First, this is my code : 首先,这是我的代码:

                <ComboBox Name="cmb1" Width="165" Height="25" Margin="25,5,10,10" 
                      ItemsSource="{Binding ChoicesList}"
                      SelectedItem="{Binding SelectedChoiceList}">
            </ComboBox>
            <ComboBox Name="cmb2" Width="165" Height="25" Margin="10,5,25,10">
                <ComboBox.Style>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Sections}"></Setter>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding SelectedChoiceList}" Value="Contract">
                                <Setter Property="ItemsSource" Value="{Binding Contract}"></Setter>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding SelectedChoiceList}" Value="Service">
                                <Setter Property="ItemsSource" Value="{Binding Services}"></Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ComboBox.Style>
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="0" 
                                           Text="{Binding Name}" 
                                           Margin="4,0"/>
                            <TextBlock Grid.Column="0" 
                                           Text="{Binding label}" 
                                           Margin="0"/>
                            <TextBlock Grid.Column="0" 
                                           Text="{Binding Start, StringFormat=d}"
                                           Margin="0"/>
                            <TextBlock Grid.Column="1" 
                                           Text="{Binding End,StringFormat=d}"
                                           Margin="0"/>
                        </Grid>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>

Another day, another problem! 改天,改个问题!

  1. In cmb2, I would like nothing to be loaded until I have made one of the three choices, is there a way? 在cmb2中,在做出三种选择之一之前,我什么都不想加载,有没有办法? (for the moment I load "section" list if nothing is chosen, and the binding changes according to the choices. I made this choice because the value of "section" can change, it can be "A" or "B" or "C" and more, so I would like "service" = service list, "contract" = contract list and "section"= all other values) (目前,如果未选择任何内容,我将加载“ section”列表,并且绑定会根据选择进行更改。之所以做出此选择,是因为“ section”的值可以更改,可以是“ A”,“ B”或“ C”等,因此我想“服务” =服务清单,“合同” =合同清单,“节” =所有其他值)

  2. More importantly, I would like to rework this code because currently the DataTemplate is the same for all three binds, which was not awkward (If I choose "section", textblock displays "name" selected, cause section have no label, for example) but I would like, for contracts, to display "name" + "from" + "Starting date" + "To" + "Ending date". 更重要的是,我想重新编写这段代码,因为当前所有三个绑定的DataTemplate都是相同的,这并不尴尬(例如,如果我选择“ section”,则文本块将显示“ name”,例如,因为section中没有标签)但对于合同,我希望显示“名称” +“从” +“开始日期” +“到” +“结束日期”。

If I add textblock "text = from" and "text = to", it will apply to all my choices, and I would have, for example, if I choose "section", a result like "nameOfSection + from + to", and I don't want that. 如果我添加文本块“ text = from”和“ text = to”,它将适用于我所有的选择,例如,如果我选择“ section”,则结果将为“ nameOfSection + from + to”,我不想要那样

So I would like the textblock "from" and "to" to appear only for the choice "contract", I don't know if it's possible? 因此,我希望文本块“ from”和“ to”仅出现在“ contract”选项中,我不知道是否可能?

Hoping to have been clear, and thanking you for your time for the help you will give me; 希望已经清楚了,并感谢您拨冗为我提供的帮助;

Welcome to SO! 欢迎来到SO!

To answer your first point by removing the line that is setting the ItemSource you should be able to have nothing loaded 要通过删除设置ItemSource的行来回答您的第一点,您应该什么都不装

<Setter Property="ItemsSource" Value="{Binding Sections}"></Setter> can be removed and replaced with another DataTrigger . 可以删除<Setter Property="ItemsSource" Value="{Binding Sections}"></Setter>并用另一个DataTrigger替换。

To answer your second point you can use DataTemplates with the DataType property to apply a style to a specific data type. 要回答第二点,您可以将DataTemplatesDataType属性一起使用,以将样式应用于特定的数据类型。 This means you can setup each of your, Service, Section and Contract to look differently / template their own properties. 这意味着您可以设置您的“服务”,“部分”和“合同”以使其外观不同/模板化其自己的属性。

<DataTemplate DataType="{x:Type classes:Contract}">
    <Label Content="Contract"/>
</DataTemplate>
<DataTemplate DataType="{x:Type classes:Service}">
    <Label Content="Service"/>
</DataTemplate>
<DataTemplate DataType="{x:Type classes:Section}">
    <Label Content="Section"/>
</DataTemplate>

This bit of code demonstrates that. 这段代码演示了这一点。

Here is also a sample application I have made that should do what you've asked. 这也是我制作的一个示例应用程序,应该可以满足您的要求。

View 视图

<Window x:Class="SOHelp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:classes="clr-namespace:SOHelp.Classes"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <DataTemplate DataType="{x:Type classes:Contract}">
            <Label Content="Contract"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type classes:Service}">
            <Label Content="Service"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type classes:Section}">
            <Label Content="Section"/>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ComboBox Grid.Row="0" Width="165" Height="25" 
                  ItemsSource="{Binding ChoicesList}"
                  DisplayMemberPath="Name"
                  SelectedItem="{Binding SelectedChoiceList}"/>
        <ComboBox Grid.Row="1" Width="165" Height="25" 
                  ItemsSource="{Binding SelectedChoiceList.Items}"/>
    </Grid>
</Window>

Code behind / could be ViewModel 后面的代码可能是ViewModel

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<Option> _choicesList;
    private Option _selectedChoiceList;
    public Option SelectedChoiceList
    {
        get { return _selectedChoiceList; }
        set { _selectedChoiceList = value; NotifyPropertyChanged(); }
    }
    public ObservableCollection<Option> ChoicesList
    {
        get { return _choicesList; }
        set { _choicesList = value; NotifyPropertyChanged(); }
    }
    public MainWindow()
    {
        InitializeComponent();

        ChoicesList = new ObservableCollection<Option>
        {
            new Option("Contract", new ObservableCollection<object>
            {
                new Contract(), new Contract(), new Contract()
            }),
            new Option("Service", new ObservableCollection<object>
            {
                new Service(), new Service(), new Service()
            }),
            new Option("Section", new ObservableCollection<object>
            {
                new Section(), new Section(), new Section()
            }),
        };

        DataContext = this;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Classes I created 我创建的课程

public class Option
{
    public string Name { get; set; }
    public ObservableCollection<object> Items { get; set; }
    public Option(string name, ObservableCollection<object> items)
    {
        Name = name;
        Items = items;
    }
}

public class Service
{
}

public class Section
{
}

public class Contract
{
}

Hope some of this helps. 希望有些帮助。 Let me know if you have any questions. 如果您有任何疑问,请告诉我。

第一个组合框 第二个组合框的示例 第二个组合框的第二个示例 启动时未加载任何内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM