WPF: как динамически загружать пользовательские элементы управления?

Как я могу загрузить пользовательский элемент управления на основе WPF в окне на основе WPF динамически (используя код во время выполнения)?

3 ответов


я настоятельно рекомендую взглянуть на Присм, поскольку составные пользовательские интерфейсы как для. Однако, поскольку это потребует от вас рефакторинга всего вашего приложения, я также отвечу на ваш вопрос напрямую.

Если требуется один пользовательский элемент управления в контейнере, поместите ContentControl в XAML и задайте свойство Content. При использовании модели представления можно привязать содержимое к свойству FrameworkElement в представлении модель:

contentControlInstance.Content = new CustomUserControl();

Если требуется несколько элементов управления в списке, используйте ItemsControl и назначьте ObservableCollection свойству ItemsSource. При использовании модели представления можно привязать ItemsSource к свойству ObservableCollection в модели представления.

тогда вы можете просто добавить / удалить представления из этой коллекции ObservableCollection:

private ObservableCollection<FrameworkElement> views = 
    new ObservableCollection<FrameworkElement>();

private void Initialize()
{
    itemsControl.ItemsSource = views;
}

private void AddView(FrameworkElement frameworkElement)
{
    views.Add(frameworkElement);
}

для добавления нескольких элементов управления вам понадобится контейнер.

Предположим, у вас есть контейнер StackPanel "myStack"

<Window ..>
    <StackPanel Name="MyStack" />
</Window>

вы можете создать элемент управления динамически и добавить его в контейнер. См. код ниже

void AddButtons()
{
    Button B1=new Button(),B2=new Button(), B3=new Button();
    B1.Content="Hello";
    B2.Content="First";       
    B3.content="Application";
   // Now you can set more properties like height, width, margin etc...
    MyStack.Children.Add(B1);
    MyStack.Children.Add(B2);
    MyStack.Children.Add(B2);    
}

или использовать привязки. Вот действительно грубый пример, показывающий, как различные элементы управления WPF могут быть показаны в одном окне WPF с помощью ContentControl и binding (что делает инструментарий, такой как Prism или Caliburn Micro).

в XAML:

<UserControl x:Class="ViewA">
  ...
<UserControl/>

<UserControl x:Class="ViewB">
  ...
<UserControl/>

код:

void ShowViewModelDialog (object viewModel)
{
  var host = new MyViewHost();
  FrameworkElement control = null;
  string viewModelName = viewModel.GetType().Name;
  switch (viewModelName )
  {
     case ("ViewModelA"):
       control  = new ViewA();
       break;
     case ("ViewModelB"):
       control  = new ViewB();
       break;
     default:
       control = new TextBlock {Text = String.Format ("No view for {0}", viewModelName);
       break;
  }

  if (control!=null) control.DataContext = viewModel;
  host.DataContext = control;
  host.Show(); // Host window will show either ViewA, ViewB, or TextBlock.
}