[英]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! 改天,改个问题!
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”等,因此我想“服务” =服务清单,“合同” =合同清单,“节” =所有其他值)
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. 要回答第二点,您可以将
DataTemplates
与DataType
属性一起使用,以将样式应用于特定的数据类型。 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.