【问题标题】:How do I load user controls dynamically?如何动态加载用户控件?
【发布时间】:2010-12-18 23:58:34
【问题描述】:

如何在窗口中动态加载用户控件(在运行时使用代码)?

【问题讨论】:

    标签: wpf user-controls code-behind


    【解决方案1】:

    我强烈建议您查看Prism,因为它的用途是复合用户界面。但是,由于这需要您重构整个应用程序,所以我也会直接回答您的问题。

    如果您想在容器中使用单个用户控件,请将 ContentControl 放入您的 XAML 中,然后设置 Content 属性。如果您使用的是视图模型,则可以将 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);
    }
    

    【讨论】:

      【解决方案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】:

        或者使用绑定。这是一个非常粗略的示例,展示了如何使用 ContentControl 和绑定在单个 WPF 窗口中显示不同的 WPF 控件(这是 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.
        }
        

        【讨论】:

          猜你喜欢
          • 2023-03-09
          • 2011-05-17
          • 1970-01-01
          • 2014-09-08
          • 2011-08-01
          • 1970-01-01
          相关资源
          最近更新 更多