Вы никогда не должны определять коллекции элементов управления или любой другой элемент пользовательского интерфейса. Если эта коллекция определена в модели представления, это также приведет к нарушению шаблона 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>