将WPF元素本身绑定到视图模型对象

时间:2018-08-11 02:21:53

标签: c# wpf xaml mvvm data-binding

我使用 MVVM模式将数据提供给窗口中的用户控件。 我想在视图模型上实现一个方法对象,该对象将任何调用转发给相应的用户控件,该控件随数据一起提供。为此,我需要在视图模型对象中具有对控件的引用

我可以通过在用户控件上声明一个属性来做到这一点,该属性返回对控件本身的引用,然后绑定到视图模型对象,但这很丑陋:

<MyUserControl ReferenceToMyself="{Binding CorrespondingUserControl, Mode=OneWayToSource}"/>

然后在视图模型对象中:

public void MethodThatForwardsCalls() => CorrespondingUserControl.ThisIsCalled();

是否有更好的方法将控件本身绑定到视图模型对象

1 个答案:

答案 0 :(得分:2)

您是否考虑过在ViewModel和View之间使用类似事件的交互方式,以避免必须将View的引用保留在ViewModel中?

在ViewModel中,我将创建类型为Action的属性,并将其命名为ThisIsCalledEvent;

#region ThisIsCalledEvent
        private Action m_ThisIsCalledEvent;
        public Action ThisIsCalledEvent
        {
            get
            {
                return m_ThisIsCalledEvent;
            }
            set
            {
                if (m_ThisIsCalledEvent != value)
                {
                    m_ThisIsCalledEvent = value;
                    OnPropertyChanged(nameof(ThisIsCalledEvent));
                }
            }
        }

#endregion

然后在MyUserControl的{​​{1}}事件中添加事件回调;

DataContextChanged在CS构造函数中,或者 this.DataContextChanged += MyUserControl_DataContextChanged;在XAML构造函数中。

现在,在事件回调中,您可以为ViewModel的DataContextChanged="MyUserControl_DataContextChanged"属性设置Action

ThisIsCalledEvent

现在,回到ViewModel,只需将方法的主体更改为即可调用您

private void MyUserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    MyUserControlViewModel vm = DataContext as MyUserControlViewModel; //Get the ViewModel from the View's DataContext

    if(vm == null)
        return;

    vm.ThisIsCalledEvent = delegate () { ThisIsCalled(); }; //When the action is invoked, call the desired function
}

这样,您就永远不会在ViewModel中保留View的实例,并且每次从ViewModel实例化新视图时,它都会设置public void MethodThatForwardsCalls() { this.ThisIsCalledEvent?.Invoke(); //Invoke the Action, if it exists, that has been set by the View } 回调。

编辑 正如JürgenRöhr在评论中所建议的那样,在Action事件回调中,可以使用DataContextChanged绑定到新的DataContext。此外,如果您另外将委托注册到args.NewValue属性中而不是对其进行设置,则可以使用Action从先前的DataContext中注销它。