简体   繁体   中英

Better way to add control during runtime

I'm searching the best way to add WPF controls during runtime. I'll explain.

  • When the application starts I'd like to search for some data and based on these data creating some UI controls.

Simple example

  • Start application
  • Search the configuration (in a DB)
  • Create or not some control based on the configuration.

In a non-MVVM way I simple create a loop to create or note these controls. But I had no idea how to do it on MVVM pattern.

My initial idea was create all the possible controls and show or not based on the configuration. Is it the best way?

Thanks :)

I'm searching the best way to add WPF controls during runtime.

If you are not using code-behind, I think data templating is exactly what you need.

I'd like the app to check in DB which boolean tags are listed and create a toggle button for each one.

You can do this with an ItemsControl and DataTemplate s. Create a data class for each type of control you want to display, eg a ToggleButton that would have a bool property for the toggled state and a title. Always make sure to implement INotifyPropertyChanged to reflect changes to data in the user interface.

public class MyToggleDataType : INotifyPropertyChanged
{
   private bool _isToggled;
   private string _title;

   public bool IsToggled
   {
      get => _isToggled;
      set
      {
         if (_isToggled == value)
            return;

         _isToggled = value;
         OnPropertyChanged();
      }
   }

   public string Title
   {
      get { ... }
      set { ...}
   }

   public event PropertyChangedEventHandler PropertyChanged;

   protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
}

Expose a collection of all the data items that you want to display as control in your main view model. An ObservableCollection automatically notifies changes like adding or removing items. I use a collection of object , but you might as well use a base class of your data items here.

public ObservableCollection<object> MyDataItems { get; }

You need to make sure to either initialize this collection before it is used in the user interface or implement INotifyPropertyChanged to signal its change if you assign it later.

In your XAML, create an ItemsControl and add a DataTemplate for each item data type that you specify in the DataType property. The DataTemplate contains the controls that should be displayed, as well as all bindings to the corresponding data item. Bind the ItemsSource of the ItemsControl to your MyDataItems collection.

<ItemsControl ItemsSource="{Binding MyDataItems}">
   <ItemsControl.Resources>
      <DataTemplate DataType="{x:Type local:MyDataType}">
         <ToggleButton IsChecked="{Binding IsToggled}"
                       Content="{Binding Title}"/>
      </DataTemplate>
   </ItemsControl.Resources>
</ItemsControl>

Now you just have to fetch the data from your database, wrap them in the corresponding data item or use those data types instead and add them to the MyDataItems collection. Each time an item is added, the collection will notify a change and the ItemsControl will search for the associated data template and display the controls.

By the way if you want to do this with single controls, you can use a ContentControl , which works the same way: Expose a view model property, bind it to the Content property and create a data template to display it. For advanced scenarios where you need create complex views and navigation, you might want to use an MVVM framework like Caliburn.Micro, Stylet or Prism, but I think that is not your scope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM