0
votes

I am a newbie in MVVM/WPF and try to use MVVM design pattern. I don't know how to describe my issue but let assume I have 2 ViewModel like below picture

enter image description here

RedViewModel has a treeview. When user click to treeview, it get selectedItem and send to BlueViewModel. Base on selectedItem from RedViewModel, BlueViewModel show data of selectedItem in textbox.

I don't know how to access and use variables between 2 MVVM.

2
You can use EventHandler that trigger when you select an item From RedViewModel. - Ali Ahmad
can you give me more detail example :(( - Bruce
RedViewModel has a treeview. That is not MVVM, your are breaking MVVM. ViewModels should know nothing about Views - Nawed Nabi Zada
No, I am not mean like that, let image I am usimh Josh Smith's FamilyTreeviewModel, when I lick on each person, it's show another view which has person's detail information (Name, email, phone number, address...) - Bruce
A window is not a view model... - mm8

2 Answers

1
votes

Option 1: The red and blue views could share the same view model. They could then simply bind to the same properties.

Option 2: If you want to stick with separate view model classes, you could send a loosely coupled message from RedViewModel to BlueViewModel when an item is selected using an event aggregator or a messenger.

How do I notify a parent view of a child view event in an MVVM WPF application?

Option 3: Use a shared service in both view models.

0
votes

You can't bind to the SelectedItem of a standard WPF TreeView. However, you can create a bindable property using a Beahvior class

public class perTreeViewHelper : Behavior<TreeView>
{
    public object BoundSelectedItem
    {
        get => GetValue(BoundSelectedItemProperty);
        set => SetValue(BoundSelectedItemProperty, value);
    }

    public static readonly DependencyProperty BoundSelectedItemProperty =
        DependencyProperty.Register("BoundSelectedItem",
            typeof(object),
            typeof(perTreeViewHelper),
            new FrameworkPropertyMetadata(null,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnBoundSelectedItemChanged));

    private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue is perTreeViewItemViewModelBase item)
        {
            item.IsSelected = true;
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
        base.OnDetaching();
    }

    private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
    {
        BoundSelectedItem = args.NewValue;
    }
}

That way, you can bind to a property on one ViewModel that you can reference from the other. Obviously the two ViewModels need to be linked in some way - usually by having one as a property of the other.

More on my take on TreeViews in a WPF / MVVM context on my blog post.