web-dev-qa-db-ja.com

WPF:ユーザーコントロールを動的に読み込むにはどうすればよいですか?

WPFベースのウィンドウにWPFベースのユーザーコントロールを動的に(実行時にコードを使用して)ロードするにはどうすればよいですか?

15
Muhammad Adnan

複合ユーザーインターフェイスが目的であるため、 Prism を確認することを強くお勧めします。ただし、これにはアプリケーション全体のリファクタリングが必要になるため、質問にも直接回答します。

コンテナーに単一のユーザーコントロールが必要な場合は、XAMLにContentControlを配置してから、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);
}
25
Richard Szalay

複数のコントロールを追加するには、コンテナが必要です。

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);    
}
5
Sasikumar D.R.

または、バインディングを使用します。これは、ContentControlとバインディング(PrismやCaliburn Microなどのツールキットが行うこと)を使用して、さまざまなWPFコントロールを単一のWPFウィンドウに表示する方法を示す非常に大雑把な例です。

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