Sharing state between ViewModels - wpf

I have two ViewModels that present the same Model to different Views. One presents the model as an item in a ListBox, the other presents it as a tab in a TabControl. The TabControl is to display tabs for the items that are selected in the ListBox, so that the tabs come and go as the selection changes.
I can easily synchronise the two controls by adding an IsSelected property to the Model and binding the ViewModels to it (a bit like this), but this will clutter the Model with presentation details that don't really belong there.
It seems like I need something between the Model and ViewModels to hold this extra state. Are there any patterns or examples of a good way to do this?

Use a ViewModel.
You've got a View that contains the two controls. Have a view model that will contain a list of ViewModels for the ListBox control to bind to. Also within this view model bind the listbox selection to a second list of viewmodels that the TabControl then also binds to.
That way your listbox drives what the tab control shows without this information entering the model which should stay oblivious to the existence of the view.

TabControl is ItemsControl, so you shouldn't be shy to bind its ItemsSource to ListBox.SelectedITems.
Obviously ViewModel for List should have a property that would produce ViewModel for Tabs:
public TabViewModel ItemTabModel { get { ... } }
And because TabControl is a bit funny, you'd need to add ItemContainerStyle to populate Content for TabControlItem, because the normal ItemTemplate for TableControl only affects headers for tabs.

Related

wpf checkbox binding with user controls

I am working on wpf mvvm pattern. I have different user controls. Based on the checkbox selection, I want them to be loaded in the main screen (that is also a user control). I have one HomeViewModel class which I have been using to bind the user controls of my project. Can you help me with a suitable way?
You should have different ViewModels for each kinds of UserControl.
Create different DataTemplates for each ViewModel Types
Put a ContentControl with binding a property of HomeViewModel -
Value of property will be an instance of ViewModel ( UserControl's) and is set by toggling CheckBoxes.

Binding to ViewModels that are displayed using a ContentPresenter and DataTemplates?

I am currently using an ItemsControl at the top of my application that contains a few buttons, bound to a list of ViewModelBases. These VMs are the pages of my app. When clicked, they set the current page to the appropriate page. A content presenter shows the current view model, and a DataTemplate converts it into the correct view.
How can I use Data Binding in these views? Since the view is being created by the ViewModel, doesn't that mean I can't create a new instance of that view model in the view? How can it find the correct instance to bind to? Or, is it automatically bound?
WPF ItemsControls automatically set the DataContext of each Item they render on screen to their corrsponding Item in the underlying collection. This means that, if you have an IEnumerable set as the ItemsSource of an ItemsControl (or any other ItemsControl-derived class, such as ListBox), it will render every item on screen (using any available DataTemplates) and automatically assign the DataContext property of the resulting visual elements to each of the ViewModelBase Items.

DataTemplate for View made up of different Views

In a Windows 8 style app I have a View (or page) which is made up of several other Sub-Views.
Each of these has an associated ViewModel and they are defined and bounded via the MVVM Light ViewModelLocator
I then have a View2 which is made up of other Sub-Views which, again, are defined and bounded via the MVVM Light ViewModelLocator
What I want to do is to place instances of the View and View2 controls into a List on a MasterViewModel and then bind this list to a GridView on a MasterView file.
Each of the instances of View and View2 should render as they do if you were to create a single instance without placing it into a list.
What I have tried to do is create a List of Pages (as all views are instances of this type) and bind the GridView to this, but when I run the app the GridView appears empty.
I have seen an examples that use a DataTemplateSelector (http://www.wiredprairie.us/blog/index.php/archives/1705) and apply a DataTemplate to each of the items in the MasterView list.
I understand what this does, but what I don’t understand is how to create a DataTemplate for a View that is made up of other Views.
I’m sure I am overlooking something and / or just making this harder than it needs to be!
Thank you for any help :)
Normally in this case, you would be binding a list to a set of ViewModels, not views, and the data template selector (or ValueConverter depending on your flavour) would select and instantiate a view suited to the view model.
So if ViewA uses ViewModelA : ISubViewViewModel, and ViewB uses ViewModelB : ISubViewModel then your main ViewModel would contain a List<ISubViewModel> which has a set of ViewModelA & ViewModelB within it. The main view's ListBox is bound to the List<ISubViewModel> and the data template selector / ValueConverter resolves ViewA for ViewModelA's and ViewB for ViewModelB's.
Hope that makes sense, it's about as hard to describe the solution as it probably was to describe the problem. :)

WPF TabControl add extra tabs to a bound control

I have a Tab Control with a ItemsSource Binding.
...
I want to add a predefined tab to the front called All that has an aggregate of all the other tabs, and I would also like to add a button at the end called Add so I can add a new tab.
Is there an easy way of doing this ?
Thanks,
Raul
The easiest way is to go with MVVM (the example in the url acutally contains TabControl bound to a ViewModel). Your ViewModel that you bind your TabPages against could expose an observablecollection of items where the first item is always a ViewModel instance that holds you aggregate data. All follwing items are the ViewModel instances for the rest of the tabpages. Your ViewModel would also expose a ICommand AddTabPage wich adds a new item to the obeservablecollection. The TabPage will pick up this change automatically. You'd have a button whose Command property is bound to this command.

autoupdate a list in wpf

I want to display a bunch of Objects i have created in a ListBox. My objects implement the INotifyPropertyChanged Interface.
I tried to use an ObservableCollection, which i have bound to a listbox Control (listbox1.DataContext = MyCollection)
But this does not exactly what i want to do, because the Listbox is not refreshed when one of the properties of one of my objects in MyCollection changes.
I have found this blogposting: http://sweux.com/blogs/psampaio/index.php/2009/04/13/creating-a-custom-observable-collection-in-wpf
is this realy the easyiest/only way to keep track of several objects?
I'm not sure, but have you tried using a datatemplate for your listbox items? like, a textbox that explicitly sets it's text to the appropriate binding.

Resources