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

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

Ответ 1

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

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

contentControlInstance.Content = new CustomUserControl();

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

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

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

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

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

Ответ 2

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

Предположим, что у вас есть контейнер 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);    
}

Ответ 3

Или используйте привязку. Здесь очень грубый пример, показывающий, как различные элементы управления WPF могут отображаться в одном окне WPF с использованием ContentControl и привязки (это то, что делает инструментарий, такой как 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.
}