Sonic Soul
Sonic Soul

Reputation: 24939

Binding properties of multiple tree views to the same ViewModel

I am working on a MVVM implementation, where i'll spawn multiple views (side by side) each containing a tree control.

each of the views will have a similar tree, with a copy of [almost] all the same items.

I would like to synchronize the IsExpanded property on all the view/TreeView's..

meaning, if i collapse one node, i would like all of them to collapse (and some goes for column widths etc).

One way to do this, would be to bind all views to the same viewmodel, and have a DependencyProperty on that ViewModel, and set up the binding as Two Way on each view. However, i need each view to be bound to a separate viewmodel so that it can display unique values. I just need to synchronize a few properties of the tree, such as IsExpanded and Width.

What would be the best approach here?

Upvotes: 1

Views: 399

Answers (4)

louie
louie

Reputation: 83

If you display the treeview's using xaml, you can bind every treeview to the first treeview spawned.

For example you can use some binding like this:

<TreeView Name="FirstTreeView" />
<TreeView Name="SecondTree" 
          IsExpended = {Binding Path=IsExpanded, ElementName=FirstTreeView, Mode=TwoWay}/>

Upvotes: 0

Kirk Broadhurst
Kirk Broadhurst

Reputation: 28728

There's no reason you can't have different collections within a single ViewModel, if that is the best design option. Especially if your multiple Trees / Collections are filtered from some 'complete set'; it might actually make more sense.

Just add multiple collections to your ViewModel, and bind to them.

public class MyViewModel : INotifyPropertyChanged
{
    public ObservableCollection<MyItem> FirstTreeCollection 
    { 
        get
        {
            // whatever you need to do here
        }
    }

    public ObservableCollection<MyItem> SecondTreeCollection 
    { 
        get { /* etc */ }
        set { /* etc */ }
    }
    // etc

    public bool Collapsed
    {
        get;
        set;
    }
}

and your Views should bind accordingly

// in your first view that contains a tree
<UserControl x:Class="View1" ...>
    <TreeView Name="FirstTree" 
              ItemsSource={Binding FirstTreeCollection}
              Collapsed={Binding Collapsed} ... >

// & in your second view that contains a tree
<UserControl x:Class="View2" ...>
    <TreeView Name="SecondTree" 
              ItemsSource={Binding SecondTreeCollection}
              Collapsed={Binding Collapsed} ... >

To clarify, I'm suggesting that you use a single ViewModel for all of these Tree-containing Views.

Upvotes: 1

Y.Yanavichus
Y.Yanavichus

Reputation: 2417

You can use Prism and EventAggregator service from it to exchange data between view models.

Upvotes: 1

Phil Sandler
Phil Sandler

Reputation: 28036

The ViewModel won't need a DependencyPropery--it will just need to expose a property that implements INotifyPropertyChanged.

The two ViewModels will need to have some way of sharing state, and exposing a property that represents that state. How you share the state depends heavily on how your ViewModels are instantiated (and probably other factors). For example, if your two VMs are being instantiated by some parent object, the parent may create one instance and pass it to both VMs in their constructors.

Upvotes: 0

Related Questions