【问题标题】:Accessing Xamarin.Forms inside ViewModel在 ViewModel 中访问 Xamarin.Forms
【发布时间】:2018-06-26 06:54:58
【问题描述】:

我对 Xamarin.forms 中的跨平台开发非常陌生。我的代码应该是高度可单元测试的,并且我创建了一个ViewModel 类来在我的ViewModel 之间进行通信。我想知道,如果我们要在视图模型中访问 Xamarin.forms(使用 Xamarin.Forms;),这是一种不好的做法还是违反了 MVVM 概念。如果是这样,我们如何在 ViewModel 中使用 Command 来绑定视图。

谢谢

【问题讨论】:

    标签: c# xamarin mvvm xamarin.forms


    【解决方案1】:

    从视图模型访问视图确实“违反”了 MVVM 原则。所以,你是对的!不过,绑定 Command 并不难,并且与您可能使用的任何其他绑定一样工作。

    在您的视图模型中,只需为 Command 定义一个属性:

    public class YourViewModel
    {
        public Command YourCommand { get; set; }
    }
    

    然后在构造函数中定义应该执行的逻辑:

    public YourViewModel()
    {
        YourCommand = new Command(() =>
        {
            Console.WriteLine("TADA!");
        });
    }
    

    当然,您可以将其定义为自己的单独方法或以其他方式声明。为简洁起见,我现在已经内联了。

    要从 XAML 绑定到它,只需执行以下操作:

    <Button Text="Make it so!" Command="{Binding YourCommand}" />
    

    并确保您已将页面上的BindingContext 属性设置为视图模型。如果您使用的是 MVVM 框架,您可能已经这样做了。

    在某些时候,您可能希望绑定到 ListView 或类似的单元格。在这种情况下,请记住范围会发生变化。然后,您将绑定到该单元格后面的视图模型,而不是页面。因此,您必须引用该页面才能访问该BindingContext。但是,当您到达那里时,请过那座桥,请记住它有一些特别之处。

    【讨论】:

    • 为了访问命令,我们需要将 Xamarin.Forms 导入我们的 ViewModel。我想知道这是违法的吗?因为我听说我们不应该将 Xamarin.Forms 导入我们的 ViewModel
    • 啊,这就是你的意思。如果真的让您感到困扰,您可以选择ICommand。但是引用 Xamarin.Forms 并没有那么糟糕。只要您不从视图模型中引用您的视图。
    • 如果我尝试像这样使用 ICommand,ConvertToGeoCodeCommand = new ICommand(ConvertToGeoCode); "无法创建抽象类或接口 'ICommand' 的实例"
    • ICommand是接口,不能直接创建接口。但是你可以将它定义为一个接口,所以它会是:public ICommand YourCommand { get; set; } 但是,如果你真的不想引用 Xamarin.Forms 你将需要某种工厂模式,因为否则当你这样做 YourCommand = new Command(...) 你还是需要参考。如果我是你,我现在会选择常规命令,当你开始掌握它并且你仍然想摆脱参考时,当你学会了基础知识时,看看如何去做。
    【解决方案2】:

    使用以下代码,因此您无需在 ViewModel 中导入 Xamarin.Forms:

    按钮行为

     public class ButtonBehavior : Behavior<Button>
        {
            protected override void OnAttachedTo(Button bindable)
            {
                base.OnAttachedTo(bindable);
                bindable.Clicked += Bindable_Clicked;
            }
    
            private void Bindable_Clicked(object sender, EventArgs e)
            {
                //Use you logic here
            }
    
            protected override void OnDetachingFrom(Button bindable)
            {
                base.OnDetachingFrom(bindable);
                bindable.Clicked -= Bindable_Clicked;
            }
        }
    

    查看

        <Button Text="Click Me" HeightRequest="50" WidthRequest="80">
            <Button.Behaviors>
                <behavior:ButtonBehavior/>
            </Button.Behaviors>
        </Button>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-26
      • 2011-10-13
      • 2020-09-24
      • 1970-01-01
      • 1970-01-01
      • 2019-06-24
      相关资源
      最近更新 更多