c# - 将 WPF 元素本身绑定(bind)到 View 模型对象

标签 c# wpf xaml mvvm data-binding

我使用 MVVM 模式 向窗口中的用户控件提供数据。
我想实现一个 View 模型上的方法 的对象转接任何来电对应用户控件 ,它提供数据。为此,我需要一个 引用控件在 View 模型对象中。

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

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

然后在 View 模型对象中:
public void MethodThatForwardsCalls() => CorrespondingUserControl.ThisIsCalled();

有没有更好的方法将控件本身绑定(bind)到 View 模型对象 ?

最佳答案

您是否考虑过在 ViewModel 和 View 之间使用类似事件的交互来避免在 ViewModel 中保留对 View 的引用?

在 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 , 添加事件回调到 DataContextChanged事件;
this.DataContextChanged += MyUserControl_DataContextChanged;在 CS 构造函数中,或DataContextChanged="MyUserControl_DataContextChanged"在 XAML 构造函数中。

现在,在事件回调中,您可以设置 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,调用您只需将方法的主体更改为;
public void MethodThatForwardsCalls()
{
    this.ThisIsCalledEvent?.Invoke(); //Invoke the Action, if it exists, that has been set by the View
}

这样,您永远不会在 ViewModel 中保留 View 的实例,并且每次从 ViewModel 实例化新 View 时,它都会设置 Action打回来。

编辑
正如 Jürgen Röhr 在评论中所建议的,在 DataContextChanged 中事件回调,可以使用args.NewValue绑定(bind)到新的 DataContext。此外,如果您将代理注册到 Action除了设置属性之外,您还可以使用 args.OldValue从以前的 DataContext 中注销它。

关于c# - 将 WPF 元素本身绑定(bind)到 View 模型对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51795917/

相关文章:

c# - 如何将自定义属性添加到 .Net Core 中的角色声明?

c# - 选中复选框时更改 wpf 数据网格行背景颜色

c# - 获取WPF中单击的矩形的名称

c# - 如何在 XAML 页面之间传递值(参数)?

c# - 如何在 PdfSharp 中添加指向文件的链接?

c# - Xamarin.Forms无法从资源返回空读取文本文件

c# - 为什么 HttpClientHandler 没有正确获取和使用默认代理设置?

wpf - 处理 WM_GETMINMAXINFO 时如何考虑帧大小

wpf - 在 Xaml 中为 Material Design 创建自定义主题

c# - 路径上的Window.DataContext错误不能为null