Sunday, 17 July 2016

Add controls dynamically using mvvm

I want to make propertygrid using xaml. PropertyGrid from Extended WPF Toolkit don't have autoupdate, tooltips etc so I decided to create my own.

My idea is to create a ObservableCollection of Controls and add them dynamically to ListBox(or ListView).

This is a example project "testy_wpf":

To use databinding I create a OnPropertyChanged class

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));
            }
         }
     }
}

Then I inherit this class in my Test class, with some properties(just for tests)

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

Then I create a MainWindowViewModel class

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

Which I add to MainWindow view:

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

In main window XAML I want to display this contorls. Currently I create some textboxes with some text.

<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}" />

My idea is to use some contorl containter to bind "T" (T is name of ObservableCollection from ViewModel)control property with some containter in xaml.

Something like this

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

As a result I should have as many controls displayed as length of T array(currently I create TextBoxes). Later I will just enumerate over all properties of someclass to display propertygrid fields.

My question is what kind of XAML containter can store all types of controls? And how bind it with some control in T array.

There were similar topics but people create just one type of control i.e. Textbox. And I know how to display many TextBoxes.



from Recent Questions - Stack Overflow http://ift.tt/29MIwWP
via https://ifttt.com/ IFTTT

No comments:

Post a Comment