Observable控件集合

我正在研究将wpf与mvvm设计一起使用的程序。 我有一个控件集合,每个项目都可以是Button \ RadioButton \ TextBox ...

ObservableCollection<Control> controls_lst = new ...

我想通过视图的xaml代码遍历此列表,并创建和显示每个控件。 但是问题是我需要在写之前检查类型

有一种方法可以遍历此列表,并通过检查 xaml 中的类型来创建和显示控件?我

chen123321bin 回答:Observable控件集合

  1. 您永远不要定义控件或任何其他UI元素的集合。如果在视图模型中定义了此集合,则这也会违反 MVVM 模式。控件集合消除了动态创建控件的所有灵活性。

    推荐的方法是定义项目模型,并在相应的DataTemplpateItemsControl的帮助下使它们动态呈现:

    数据模型定义

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

  1. 您可以将DataTrigger与自定义类型转换器结合使用(也适用于解决方案1):

    TypeConverterIValueConverter)的实现

    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>
    

  1. 使用DataTemplate

    <ListView ItemsSource="{Binding CollectionWithControls}">
      <ListView.Resources>
        <DataTemplate DataType="{x:Type RadioButton}">
    
          <!-- Type specific layout -->
          ...
        </DataTemplate>
      </ListView.Resources>
    </ListView>
    
本文链接:https://www.f2er.com/2677167.html

大家都在问