簡體   English   中英

在 WPF/MVVM 中動態添加用戶控件

[英]Adding dynamically UserControls in WPF/MVVM

是否可以動態添加和綁定用戶控件? 也許我會展示示例代碼來說明我的意思。

主窗口:

 <UniformGrid
    Rows="11"
    Columns="11"
    DataContext="{StaticResource vm}">

    <local:DynamicUserControl
        ButClickControl="{Binding Path=UserControlObjects[0].ButClickCommand}"
        SomeDataInUserControl="{Binding Path=UserControlObjects[0].SomeData, Mode=OneWay}" />

    <local:DynamicUserControl
        ButClickControl="{Binding Path=UserControlObjects[1].ButClickCommand}"
        SomeDataInUserControl="{Binding Path=UserControlObjects[1].SomeData, Mode=OneWay}" />

    <local:DynamicUserControl
        ButClickControl="{Binding Path=UserControlObjects[2].ButClickCommand}"
        SomeDataInUserControl="{Binding Path=UserControlObjects[2].SomeData, Mode=OneWay}" />

    .....


</UniformGrid>

在 ViewModel 中有一個UserControlObjects數組。 但是在這個數組中,我將有超過 100 個元素,因此將所有元素一一寫入並不是最佳選擇。 有什么方法可以添加DynamicUserControls不在 XAML 中,而是在代碼循環中的某個地方添加,同時保持 MVVM 模式和綁定?

使用 ItemsControl 和 UniformGrid 作為 ItemsPanel 和 ItemTemplate 中的 DynamicUserControl:

<ItemsControl DataContext="{StaticResource vm}"
              ItemsSource="{Binding UserControlObjects}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="11" Columns="11"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:DynamicUserControl
                ButClickControl="{Binding ButClickCommand}"
                SomeDataInUserControl="{Binding SomeData}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

在我看來,您會希望將任何控件置於您的視野之外 model。 但是,您可以將支持控件的單個視圖模型保留在主視圖 model 內的列表中。 例如,創建將為“動態”控件提供數據的視圖 model。

   class SubViewModel
   {
      public string Name { get; private set; } = string.Empty;

      public SubViewModel(string aName)
      {
         Name = aName;
      }
   }

在主視圖 model 中,您可以做任何您想做的事情來動態創建實例。 在這種情況下,我只是在 for 循環中創建 then 。

   class MainWindowViewModel
   {
      public ObservableCollection<SubViewModel> SubViewModels
      {
         get
         {
            return mSubViewModels;
         }
      } private ObservableCollection<SubViewModel> mSubViewModels = new ObservableCollection<SubViewModel>();

      public MainWindowViewModel()
      {
         for(int i = 0; i < 30; i++)
         {
            SubViewModels.Add(new SubViewModel($"Control: {i}"));
         }
      }
   }

然后在視圖中,您可以將 ItemsControl 與基於 UniformGrid 的 ItemsPanelTemplate 結合使用,然后使用任何您想要的數據模板,無論是在那里顯式定義它,還是制作一個用戶控件(如您的本地:DynamicUserControl)來清理。 在此示例中,它明確定義的數據模板。

<Window x:Class="ListOfViewsSample.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:local="clr-namespace:ListOfViewsSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
   <Window.DataContext>
      <local:MainWindowViewModel/>
   </Window.DataContext>
   <Grid>
      <ItemsControl ItemsSource="{Binding SubViewModels}">
         <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
               <UniformGrid/>
            </ItemsPanelTemplate>
         </ItemsControl.ItemsPanel>
         <ItemsControl.ItemTemplate>
            <DataTemplate>
               <Grid Background="LightGray" Margin="10">
                  <Label Content="{Binding Name}" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
               </Grid>
            </DataTemplate>
         </ItemsControl.ItemTemplate>
      </ItemsControl>
   </Grid>
</Window>

結果如下:

在此處輸入圖像描述

如果不希望多個動態視圖相同,您可以查看數據模板選擇器以根據指定的視圖 model 顯示不同的內容,但根據您的問題,我認為您正在尋找相同控件的列表/數據。 希望這可以幫助!

通常的做法是:

  1. 為您要創建的動態項目創建一個 ItemsControl
  2. 將 ItemsPanel 覆蓋為您需要的任何內容(在您的情況下為 UniformGrid)
  3. 將其綁定到視圖模型列表,每個控件有一個視圖 model
  4. 將 DataTemplates 定義為 map 每個視圖 model 類型到其對應的視圖類型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM