简体   繁体   中英

Use selectedItem of treeview from another ViewModel

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

在此处输入图像描述

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.

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM