NTinkicht
NTinkicht

Reputation: 1002

Put different kinds of user-controls in a wpf grid

I'm starting with WPF, and I want to create a grid which shows shapes according to the context. So for example in one cell, I can have either a circle, or a rectangle !

I created my custom circle "Circle.Xaml" and my custom rectangle "Rectangle.Xaml". I created also their View-Models "CircleVM.Cs" and "RectangleVM.Cs".

Now, I added a listBox to my application to let the user to put either the circle, or the rectangle in my grid cell.

My problem is:

  1. How can I bind all that with my cell ? In order to put the right control when I'll add simply his corresponding View-Model in the collection binded to my grid !!
  2. How can I set the DataContext of a view when the view-Model constructor has arguments which are not defined at the initialisation (Values of arguments are according to the context too) !!

Upvotes: 0

Views: 113

Answers (1)

Sheridan
Sheridan

Reputation: 69959

When you declare a DataTemplate in a Resources section, you have a choice... you can provide it with a name and then use that name to reference it, or you leave it without a name. If a DataTemplate has no name (or x:Key value) then it will automatically be applied to all objects of the type specified in it unless they have another DataTemplate explicity set with a named DataTemplate.

Therefore, you can add the following into your application Resources section (in App.xaml) and it will apply to all of the view models in your application:

<DataTemplate DataType="{x:Type ViewModels:CircleVM}">
    <Views:Circle />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:RectangleVM}">
    <Views:Rectangle />
</DataTemplate>

Please note that you will need to add the required XML Namespaces... something like this:

xmlns:ViewModels="clr-namespace:YourApplicationName.FolderNameIfApplicable"
xmlns:Views="clr-namespace:YourApplicationName.FolderNameIfApplicable"

Now, whenever you add an instance of your CircleVM class into the UI, the related Circle.xaml file will be shown:

<ContentControl Content="{Binding YourViewModelProperty}" />

To switch between the two view models, create a property as above... again, you have two choices:

public object YourViewModelProperty // with valid getter/setter removed here

Or better, create a BaseViewModel class that implements the INotifyPropertyChangedinterface and extend all of your view models from it:

public BaseViewModel YourViewModelProperty // with valid getter/setter removed here

The final step to take when the user changes their selection is to set the value of this property:

if (userHasChosenCircle) YourViewModelProperty = new CircleVM();
else YourViewModelProperty = new RectangleVM();

Upvotes: 1

Related Questions