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.
}