我正在研究将wpf与mvvm设计一起使用的程序。 我有一个控件集合,每个项目都可以是Button \ RadioButton \ TextBox ...
ObservableCollection<Control> controls_lst = new ...
我想通过视图的xaml代码遍历此列表,并创建和显示每个控件。 但是问题是我需要在写之前检查类型
有一种方法可以遍历此列表,并通过检查 xaml 中的类型来创建和显示控件?我
我正在研究将wpf与mvvm设计一起使用的程序。 我有一个控件集合,每个项目都可以是Button \ RadioButton \ TextBox ...
ObservableCollection<Control> controls_lst = new ...
我想通过视图的xaml代码遍历此列表,并创建和显示每个控件。 但是问题是我需要在写之前检查类型
有一种方法可以遍历此列表,并通过检查 xaml 中的类型来创建和显示控件?我
您永远不要定义控件或任何其他UI元素的集合。如果在视图模型中定义了此集合,则这也会违反 MVVM 模式。控件集合消除了动态创建控件的所有灵活性。
推荐的方法是定义项目模型,并在相应的DataTemplpate
和ItemsControl
的帮助下使它们动态呈现:
数据模型定义
// Common base type
interface ISelectorItem
{
public string Text { get; set; }
}
// Model to represent a ToggleButton
class BooleanItem : ISelectorItem
{
}
ViewModel.cs
class ViewModel
{
public ObservableCollection<ISelectorItem> DataModels { get; set; }
public ViewModel()
{
this.DataModels = new ObservableCollection<ISelectorItem>() { new BooleanItem() { Text = "Click Me"}};
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type BooleanItem}">
<ToggleButton Content="{Binding Text}" />
</DataTemplate>
</Window.Resources>
<ListView ItemsSource="{Binding DataModels}" />
</Window>
您可以将DataTrigger
与自定义类型转换器结合使用(也适用于解决方案1):
TypeConverter
(IValueConverter
)的实现
public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
=> value.GetType();
查看实现
<ListView ItemsSource="{Binding CollectionWithControls}">
<ListView.Resources>
<TypeConverter x:Key="TypeConverter" />
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=.,Converter={StaticResources TypeConverter}}
Value="{x:Type RadioButton}">
<Setter ... />
</DataTrigger>
</Style.Triggers>
</Style>
<ListView.ItemContainerStyle>
</ListView>
使用DataTemplate
:
<ListView ItemsSource="{Binding CollectionWithControls}">
<ListView.Resources>
<DataTemplate DataType="{x:Type RadioButton}">
<!-- Type specific layout -->
...
</DataTemplate>
</ListView.Resources>
</ListView>