【问题标题】:How to pass data from ViewModel to View code behind in Xamarin.Forms following MVVM?如何在 MVVM 之后将数据从 ViewModel 传递到 Xamarin.Forms 后面的 View 代码?
【发布时间】:2020-10-03 12:17:08
【问题描述】:

所以问题很简单,我认为:

我有一个 View 及其关联的 ViewModel。 我有一个在 ViewModel 中生成的值,并希望按照 MVVM 模式将其传递给 View 的 Code Behind。我知道这完全有可能,因为这基本上是使用 INotifyPropertyChanged 和数据绑定时发生的情况,但我想将值传递到 Code Behind 中的变量中,而不是 XAML 组件中。

例如,考虑这样的事情:

视图模型

public string VM_String { get; set; }

查看代码背后

ViewModel MyViewModel = new ViewModel;

public string View_String { get; set; }

我只是想将 VM_String 中的值传递给 View_String,同时遵循 MVVM 原则,例如:

View_String = MyViewModel.VM_String;

不是我想要的。我希望这些值彼此分离。

如何去做这件事?可能与代表/事件有关?

谢谢

【问题讨论】:

  • 后面代码中的这个值是什么??一个控制??这是什么??
  • 这只是我在构造函数中声明的变量。如果我想将值附加到控件,我会使用数据绑定,这不是我想要在这里做的。
  • 其他方式是使用 Xamarin.Essentials: Preferences stackoverflow.com/a/63553826/4654957

标签: c# xamarin mvvm xamarin.forms


【解决方案1】:

您需要在视图的代码隐藏中创建BindableProperty,并使用 xaml 将此属性绑定到视图模型中的属性。然后,您可以使用 BindableProperty 的 propertyChanged 事件在绑定值更改时应用您的逻辑。

如果您的视图是 ContentPage,it's not possible 在代码隐藏中声明一个 BindableProperty 并将其绑定到同一视图的 xaml 文件中。但是,使用 attached BindableProperty 就可以了。

在您的视图 (NewPage.xaml.cs) 的代码隐藏中:

    public static readonly BindableProperty VMStringProperty 
        = BindableProperty.CreateAttached("VMString",
            typeof(string),
            typeof(NewPage),
            default(string),
            propertyChanged: VMStringChanged);

    public static string GetVMString(BindableObject target)
    {
        return (string)target.GetValue(VMStringProperty);
    }

    private static void VMStringChanged(BindableObject target, object oldValue, object newValue)
    {
        var yourView = target as NewPage;
        var vmString = newValue as string; // or GetVMString(target)
        yourView.ApplyLogic(newValue); // ApplyLogic is an instance method in your NewPage class
    }

在您视图的 xaml 文件中 (NewPage.xaml):

<ContentPage
    xmlns:local="clr-namespace:YourNamespace"
    local:NewPage.VMString="{Binding VM_String}"
...

以这种方式使用附加的可绑定属性并不常见。相反,根据您的情况,您可以考虑创建一个custom control,其中包含(非附加的)VmString 可绑定属性。然后,您可以将此控件像普通控件一样添加到您的 NewPage,并将其 VmString 属性绑定到您页面的 ViewModel 中的属性。

【讨论】:

  • 这听起来和我想要的完全一样。要求一个简单字符串的例子会不会太过分了,也许?我正在检查您的链接,但 MSDN 文档对我来说似乎总是有点过于庞大。谢谢。
  • @Zidd 您的视图类型是什么?
  • 我猜这是一个常规的 XAML 页面。类似“public partial class NewPage : ContentPage { }”
  • 谢谢!还有一个问题,我将如何将它也绑定到代码后面而不是在 XAML 文件中进行绑定?
  • @Zidd 你可以这样做:"this.SetBinding(VMStringProperty, "VM_String");"在你的 NewPage 类的某个地方。如果此答案帮助您解决了问题,请将其标记为已接受。
【解决方案2】:

背后的代码可以与视图模型交互的唯一方法是将视图模型绑定到视图。

所以ViewModel MyViewModel = new ViewModel; 这设置了视图以了解视图模型。

VariableInCodeBehind = MyViewModel.VariableInViewModel;

这是您在后面的代码中使用视图模型中的变量分配变量的方式。

【讨论】:

  • 嗯,是的,但这正是我在这里试图避免的。我试图找到一种迂回的方式来实现这一点,以便将 View 与 ViewModel 分离。毕竟,这不是 MVVM 的重点吗?还是我弄错了?
  • 是的,MVVM 是一种设计模式,它说明了如何构建应用程序。这种设计模式不会阻止您将代码放在代码后面。将会有一些用例让您将代码放入后面的代码中。要点是,当使用 MVVM 时,您将所有逻辑都放在一个单独的 cs 文件中,这样您就可以轻松地进行单元测试。对后面的代码进行单元测试要困难得多。最佳做法是将核心逻辑(命令等)放入您的视图模型中,但其他不需要单元测试的东西可以放入视图模型中。
  • 有趣,没有从单元测试的角度考虑过。我认为这更多是关于使用不同的 ViewModel 重用 View,这就是我想避免直接引用当前 ViewModel 的原因。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 2013-11-30
  • 2016-01-16
  • 1970-01-01
相关资源
最近更新 更多