Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind multiple views to multiple viewmodels

I have a WPF window displaying different self-defined Views. So far I was able to use everything I learned about MVVM :)

Now I got to a new "problem": I have 10 entities of the same view in a bigger view. These ten view-entities contain a set of controls (textbox, combobox etc.) but are all consistent.

So how do I bind these Views to a ViewModel?

I thought about having 10 instances of the ViewModel in the "higher-level" ViewModel and give the views fix-defined the instances of the VM as datacontext.

My question is now --> Is there a easier (or more convienient) way to bind many (identical) views to their viewmodels?

Code-Example:

View Model:

private PanelViewModel _panelViewModel1 = new PanelViewModel();
public PanelViewModel PanelVM1
{
   get { return _panelViewModel1; }
}  

View-Example:

<myControls:vwPanel HorizontalAlignment="Left" x:Name="vwPanel1" 
                    VerticalAlignment="Top" DataContext="{Binding Path=PanelVM1}"/>

What bothers me is that I would need this logic ten times for ten views?

UPDATE: To answer some questions: I want to show one view 10 times (in my example) I defined my own view by inheriting from UserControl. So my vwPanel inherits from UserControl. The 10 vwPanels are just placed inside a StackPanel inside a Grid.

It's not about displaying data, as you pointed out, there would be a listview or a datagrid a better place to start. It's a special case where I need this much input-controls :/

UPDATE2: What I hoped for was more like defining a List of ViewModels and Bind my 10 Views to one of this List. But this will not work will it? At least I wouldn't know how to refernce one "special" entitiy in the list out of XAML...

like image 374
basti Avatar asked Jun 15 '12 13:06

basti


People also ask

Can one view have multiple ViewModels?

ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property.

Can a view have multiple ViewModels in WPF?

Err no - it's just convention that you have one instance, but there actually aren't any rules that you can't have multiple VM's in the XAML - the key thing to understand is that every item has it's own DataContext (that's inherited), so if you need to use a different DataContext then you just bind to the appropriate VM ...

Can a fragment have two ViewModels?

You can with the help of Inheritance, create a base class and put all the common functionality there, then create two more classes which inherit the base class. this way you can achieve what you want.

Can ViewModels communicate with each other?

We know that global command is triggered by binder sending events into event queue, hence, ViewModels attached with binders are able to communicate with each other by global command.


2 Answers

Typically I use implicit DataTemplates for mapping Views to ViewModels. They can go in <Application.Resources>, <Window.Resources> or even in under specific elements only such as <TabControl.Resources>

<DataTemplate DataType="{x:Type local:PanelViewModel}">
    <myControls:vwPanel />
</DataTemplate>

This means that anytime WPF encounters an object in the VisualTree of type PanelViewModel, it will draw it using vwPanel

Objects typically get placed in the VisualTree through an ItemsSource property

<ItemsControl ItemsSource="{Binding CollectionOfAllPanels}" />

or by using a ContentControl

<ContentControl Content="{Binding PanelVM1}" />
like image 166
Rachel Avatar answered Nov 02 '22 18:11

Rachel


If I understand your question correctly, you have a collection of something that you what to represent visually. That is, you have several viewmodels that you want to define a single view for, but show X number of times. Your example shows you using a panel as your view for the "PanelViewModel"...what is the parent item's control for the vwPanel? Assuming you're using something like a ListBox, you can define a custom DataTemplate that contains your vwPanel and assign that DataTemplate to your ListBox.ItemTemplate.

For example:

<Window.Resources>
    <DataTemplate x:Key="myVMTemplate" TargetType="{x:Type myViewModels:PanelViewModel}">
        <myControls:vwPanel HorizontalAlignment="Left" VerticalAlignment="Top"/>
    </DataTemplate>
</Window.Resources>

<ListBox ItemsSource="{Binding Path=MyCollectionOfPanelVMs}" 
         ItemTemplate="{StaticResource myVMTemplate}" />

I haven't verified that this works.

like image 20
Thelonias Avatar answered Nov 02 '22 19:11

Thelonias