【问题标题】:Xamarin Detecting Enter Key MVVMXamarin 检测输入键 MVVM
【发布时间】:2018-05-10 03:37:30
【问题描述】:

如何使用 MVVM 方法检测何时按下回车键(或任何其他键)。我是 xamarin 的新手,所以我希望我问的是正确的问题。我的想法是在密码条目中添加一个命令。那是正确的方法吗?我可以将 Completed Event 添加到后端代码,但如何将其链接到我的视图模型?

这是我的 XAML 代码

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:newApp"
             x:Class="newApp.MainPage">

    <ContentPage.Content>

        <StackLayout Padding="30" Spacing="10" VerticalOptions="Center">

            <Image Source="logo.png" />

            <Entry Text="{Binding Username}" Placeholder="Username"  />

            <Entry Text="{Binding Password}" IsPassword="True" Placeholder="Password" />

            <Label Text="{Binding DisplayMessage}"/>

            <Button Text="Log In" Command="{Binding LogInCommand}"  />

        </StackLayout>

    </ContentPage.Content>
</ContentPage>

这是后端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

    namespace newApp
    {
      public partial class MainPage : ContentPage
      {
          public MainPage()
          {
              InitializeComponent();
              BindingContext = new LoginViewModel();
          }
      }
    }

这是我的 ViewModel

namespace newApp
{
    class LoginViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        string username, password;
        Boolean bol;

        void OnPropertyChanged([CallerMemberName] string name = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public string Password
        {
            get { return password; }
            set
            {
                password = value;
                OnPropertyChanged();
            }
        }

        public string Username
        {
            get { return username; }
            set
            {
                username = value;
                OnPropertyChanged();

                OnPropertyChanged(nameof(DisplayMessage));
            }
        }

        public string DisplayMessage
        {
            get
            {
                if (username != ""){return $"This is your {Username}";}
                else return "";
            }
        }


        void Login()
        {
            if (username == "")
                bol = false;

        }
    }
}

【问题讨论】:

    标签: xaml xamarin xamarin.forms


    【解决方案1】:

    简短的回答是:你不能。 Completed 事件就是这样:一个事件。由于事件的工作方式,它们不适合 MVVM 模式。

    有几种方法可以解决这个问题。首先,您可以在代码隐藏中捕获事件,然后在 BindingContext 属性中的视图模型中触发代码。尽管您对 MVVM 模式有些偏离,但这是一种解决方法。

    另一种选择是创建您自己的控件继承并实现一个新属性,该属性确实采用Command。然后,您可以在内部将事件循环到 Command

    但可能最简单的解决方案是创建一个Behavior,将您的活动变成Command。要创建一个可重用的Behavior,将其上的任何事件转换为Command,请像这样实现它(完整的实现可以在下面的链接中找到):

    public class EventToCommandBehavior : BehaviorBase<View>
    {
      public static readonly BindableProperty EventNameProperty =
        BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
      public static readonly BindableProperty CommandProperty =
        BindableProperty.Create ("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
      public static readonly BindableProperty CommandParameterProperty =
        BindableProperty.Create ("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
      public static readonly BindableProperty InputConverterProperty =
        BindableProperty.Create ("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
    
      public string EventName { ... }
      public ICommand Command { ... }
      public object CommandParameter { ... }
      public IValueConverter Converter { ...  }
      ...
    }
    

    对于你的Entry,像这样附加它:

    <Entry Text="{Binding Username}">
      <Entry.Behaviors>
        <local:EventToCommandBehavior EventName="Completed" Command="{Binding CompletedCommand}" />
      </Entry.Behaviors>
    </Entry>
    

    在文档中了解更多信息:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/behaviors/reusable/event-to-command-behavior

    【讨论】:

    • 非常感谢,本质上,行为是要命令的事件的包装器?
    • 不一定,各种东西都可以用。但是其中一种用法是这个:)
    • @GeraldVersluis 很好的答案! “首先,您可以在代码隐藏中捕获事件,然后在 BindingContext 属性中的视图模型中触发代码。”我喜欢。请问如何触发视图模型中的代码?
    • 从上面提供的链接链接到完整的源代码:github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/…
    • +1 回答。您给出的第一个选项是我在很多地方看到的,但是如果您想尽可能严格地遵守 MVVM 原则,那么 Behavior 路线是“正确”的答案。我说“正确”是因为......这是一个加载的意见哈哈。
    猜你喜欢
    • 2014-04-18
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 2012-09-10
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    相关资源
    最近更新 更多