组合框:每个DataTrigger的DataTemplate

时间:2019-04-24 11:53:23

标签: c# wpf mvvm

我有两个问题,一是小,一是大,我需要帮助。

首先,这是我的代码:

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

前一天,另一个问题!

  1. 在cmb2中,我不希望加载任何东西,直到我做出了三种选择之一,有办法吗? (目前,如果未选择任何内容,我将加载“ section”列表,并且绑定会根据选择进行更改。之所以做出此选择,是因为“ section”的值可以更改,可以是“ A”,“ B”或“ C”等等,因此我想“ service” =服务清单,“ contract” =合同清单,“ section” =所有其他值)

  2. 更重要的是,我想对这段代码进行修改,因为当前所有三个绑定的DataTemplate都是相同的,这并不尴尬(如果我选择“ section”,则文本块将显示“ name”,这是因为section具有例如,没有标签),但对于合同,我希望显示“名称” +“自” +“开始日期” +“至” +“结束日期”。

如果我添加文本块“ text = from”和“ text = to”,它将适用于我的所有选择,例如,如果我选择“ section”,则结果将类似于“ nameOfSection + from +”到”,而我则不需要。

所以我希望文本块“ from”和“ to”仅针对选择“ contract”出现,我不知道是否可能?

希望一切都清楚,并感谢您拨冗为我提供的帮助;

1 个答案:

答案 0 :(得分:1)

欢迎您!

要通过删除设置ItemSource的行来回答您的第一点,您应该什么都不能加载

<Setter Property="ItemsSource" Value="{Binding Sections}"></Setter>可以被删除并替换为另一个DataTrigger

要回答第二点,您可以将DataTemplates属性与DataType一起使用,以将样式应用于特定的数据类型。这意味着您可以设置自己的“服务”,“部分”和“合同”以使其外观不同/模板化各自的属性。

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

/后面的代码可以是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));
    }
}

我创建的课程

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

希望其中一些帮助。如果您有任何问题,请告诉我。

First combobox Example of second combobox Second example of second combobox Nothing loaded on startup