繁体   English   中英

使用mvvm动态添加控件

[英]Add controls dynamically using mvvm

我想使用xaml创建propertygrid。 来自Extended WPF Toolkit的PropertyGrid没有自动更新,工具提示等,因此我决定创建自己的。

我的想法是创建一个ObservableCollection控件并将其动态添加到ListBox(或ListView)。

这是一个示例项目“ testy_wpf”:

要使用数据绑定,我创建一个OnPropertyChanged类

namespace testy_wpf
{
    public class NotifyPropertyChanged : INotifyPropertyChanged
    {
        public NotifyPropertyChanged ()
        {

        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(String Name)
        {
            if (PropertyChanged != null)
            {
                 PropertyChanged(this, new PropertyChangedEventArgs(Name));
            }
         }
     }
}

然后,我在Test类中继承了该类,并带有一些属性(仅用于测试)

namespace testy_wpf
{
    public class Test : NotifyPropertyChanged
    {
        public Test()
        { 
        }

        private int val { get; set; }
        public int Val 
        {
            get { return val; }
            set
            {
                val = value;
                OnPropertyChanged("Val");
            }
         }

        private String name { get; set; }
        public String Name
        {
             get { return name; }
             set
             {
                  name = value;
                  OnPropertyChanged("Name");
             }
         }

        private String errorMsg { get; set; }
        public String ErrorMsg 
        {
            get {return errorMsg; }
            set 
            {
                errorMsg = value;
                OnPropertyChanged("ErrorMsg");
            }
        }

        public Control Control { get; set; }
    }
}

然后我创建一个MainWindowViewModel类

public class MainWindowViewModel
    {
        public MainWindowViewModel()
        {
            T = new ObservableCollection<Test>() 
            {
                new Test(){ Name = "Object 1" , Val = 1, Control = new TextBox(){ Text = "Test"}, ErrorMsg = "Error 1"},
                new Test(){ Name = "Object 2" , Val = 2, Control = new ComboBox(), ErrorMsg = "Error 2"},
                new Test(){ Name = "Object 3" , Val = 2, Control = new CheckBox(), ErrorMsg = "Error 3"}
            };
        }

        public ObservableCollection<Test> T { get; set; }
    };

我添加到MainWindow视图中:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindowViewModel();
        }
    }

在主窗口XAML中,我想显示此控制。 目前,我用一些文本创建了一些文本框。

<Window.Resources>
    <DataTemplate x:Key="ControlTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}" Width="100"/>
            <TextBox Text="{Binding Path=Val,Mode=TwoWay,     UpdateSourceTrigger=PropertyChanged}" Width="50">
                <TextBox.ToolTip>
                    <StackPanel>
                        <TextBlock Text="{Binding ErrorMsg}" />
                    </StackPanel>
                </TextBox.ToolTip>
            </TextBox>               
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<ListBox Width="200"
             HorizontalAlignment="Left"
             Margin="10"
             ItemTemplate="{StaticResource ControlTemplate}"
             ItemsSource="{Binding Path=T}" />

我的想法是使用一些控制容器将“ T”(T是ViewModel的ObservableCollection的名称)控件属性与xaml中的一些控制容器绑定。

像这样

//Pseudo code
<control data="{Binding Control}" /> <!-- Where control is i.e. Textbox, ComboBox, CheckBox-->

结果,我应该显示与T数组长度一样多的控件(当前我创建了TextBoxes)。 稍后,我将枚举某个类的所有属性以显示propertygrid字段。

我的问题是,哪种XAML容器可以存储所有类型的控件? 以及如何将其与T数组中的某些控件绑定。

有类似的主题,但是人们只能创建一种控件,即Textbox。 而且我知道如何显示许多TextBoxes。

看一下DataTemplateSelector 您可以提供自己的模板选择器,该选择器会将特定的DataTemplate返回到ListBox(将自定义模板选择器设置为listbox的ItemTemplateSelector属性)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM