简体   繁体   中英

Proper handling of Controls on a WPF UserControl

I got a ComboBox with five entries and five UserControls.

When I choose the ComboBox Entry one, I want to assign the first UserControl to my grid. On the second ComboBox entry, the second UserControl, on the third entry... and so on.

Now each UserControl contains a bunch of Controls, such as TextControls, ComboBoxes and CheckBoxes.

Let's imagine the following pseudocode:

combobox_SelectedIndexChanged()
{
    if(comboBox.SelectedIndex == 1)
       grid.Content = new UserControlOne();
    else if(comboBox.SelectedIndex == 2)
       grid.Content = new UserControlTwo();
    else if(comboBox.SelectedIndex == 3)
       grid.Content = new UserControlThree();
    [...]
}

On a Button Click, I want to get the Values of the assigned control, but I don't know how to access the UserControl.

buttonSave_click()
{
    //TODO: Get Values of a UserControl and assign it to the Model-Class    
}

How do I access the Controls of the UserControl and get their values?

Personally, I would do something like this using the MVVM design pattern

The ComboBox would be bound to a collection of ViewModel or Model objects

So you'd have

<ComboBox ItemsSource="{Binding SomeCollection}" 
          SelectedItem="{Binding SelectedViewModel}"
          DisplayMemberPath="DisplayName" />

where SomeCollection is a collection of object on your ViewModel , and SelectedViewModel is an object property to hold the selected item

SomeCollection = new ObservableCollection<object>();
SomeCollection.Add(new ViewModelA());
SomeCollection.Add(new ViewModelB());
SomeCollection.Add(new ViewModelC());
SomeCollection.Add(new ViewModelD());
SomeCollection.Add(new ViewModelE());

SelectedViewModel = SomeCollection[0];

Now your SaveCommand can access whatever is selected by using SelectedViewModel and casting it into the appropriate type based on typeof(SelectedViewModel )

Personally I would use a generic interface like IViewModel instead of an object , and have it contain some generic properties (such as DisplayName ) and methods. Depending on your functionality, you could even have it contain it's own save logic, so you could execute this in the save command:

SelectedViewModel.Save();

As for displaying the correct View/UserControl, I would use a ContentControl , with it's Content bound to your SelectedViewModel , and use implicit data templates to tell WPF how to draw each object

<ContentControl Content="{Binding SelectedViewModel}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type local:ViewModelA}">
            <local:UserControlA />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModelB}">
            <local:UserControlB />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModelC}">
            <local:UserControlC />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModelD}">
            <local:UserControlD />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ViewModelE}">
            <local:UserControlE />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

Add dependency properties to the UserControl 's class and bind them to the properties of the controls inside the UserControl which you wish to expose to the world. This allows your UserControl to present a suitable interface to the outside world, while doing whatever it needs to do in the safety of its internal environment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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