在这种情况下,首选ICommand和Local:Mvx

时间:2019-01-13 20:50:18

标签: android mvvmcross icommand mvxbind

我正在使用Xamarin和MvvmCross开发一个Android应用程序。从此问题底部的布局中可以看到,我有一个TextView和一个Button。 我要实现以下目标:

  1. 将按钮的OnClick侦听器绑定到onClikCommand方法,如下面的代码所示。

  2. 当调用onClikCommand时,我希望TextView的Text属性的值根据if语句的评估而变化。

  3. 通过定制的EventHandler和EventArgs广播评估值。

关于绑定部分,我阅读了一些教程,发现一些开发人员正在使用

ICommand interface and Command in the property of UI-Command, 

有些正在使用

local:Mvx 

我的问题是,两种绑定之间有什么区别?在哪种情况下,哪种绑定都是首选的?

code_VM:IMvxNotifyPropertyChanging

public event EventHandler<ValidPlayValueEventArgs> ValidPlayValueEventHandler;
public ICommand onClikCommand {get; private set;}
public isValidPlayValue {get; private set;}

public VM() {
onClikCommand = new Command<string, string, string>(isValidPlay);
}

public class ValidPlayValueEventArgs : EventArgs {
public isValidPlay {get; private set;}

public ValidPlayValueEventArgs(bool isValid) {
    isValidPlay = isValid;
    }
}


public void isValidPlay(string p1, string p2, string p3) {
if (p1 && p2 && P3) {
    isValidPlayValue = true;//<----I expect this to update/set value in the textview!! true??
    ValidPlayValueEventHandler(this, new ValidPlayValueEventArgs(true));
} else {
        isValidPlayValue = false;//<----I expect this to update/set value in the textview!! true??
        ValidPlayValueEventHandler(this, new ValidPlayValueEventArgs(false));
    }
}

布局

<TextView
Command="{Binding isValidPlayValue}"

<Button
Command="{Binding onClikCommand}"

1 个答案:

答案 0 :(得分:0)

如果我对您的问题理解正确,那么您想知道两者之间的区别:

<Button 
    local:MvxBind="Click ExecuteThisCommand" />

和:

<Button 
    Command="{Binding ExecuteThisCommand}" />

两个代码块都实现相同的功能,但是不同之处在于,第一个代码块用于Android应用程序,第二个代码块用于UWP应用程序。 由于您正在创建Android应用程序,因此应该选择第一个选项。我希望您的Android应用程序在使用第二个代码块时不会运行。

额外:

对于实现您在第1、2和3点中描述的功能,我想给您一个提示:

请勿将TextBox的值作为参数传递给isValidPlay。而是将TextBox的值绑定到ViewModel中的属性。问题:参数string p1, string p2, string p3代表什么?我假设您实际上想拥有3个TextBoxes,而不是1个。

ViewModel外观示例:

public class MyViewModel : MvxViewModel
{
    public class ValidPlayValueEventArgs : EventArgs
    {
        public bool IsValidPlay { get; private set; }

        public ValidPlayValueEventArgs(bool isValid)
        {
            IsValidPlay = isValid;
        }
    }

    private event EventHandler<ValidPlayValueEventArgs> ValidPlayValueEventHandler;

    // Property to which your TextBoxOne Value is bound
    private string _textBoxOne;
    public string TextBoxOne
    {
        get { return _textBoxOne; }
        set
        {
            _textBoxOne = value;
            // RaisePropertyChanged will notify the view that this property has changed
            RaisePropertyChanged();
        }
    }

    // Property to which your TextBoxTwo value is bound
    private string _textBoxTwo;
    public string TextBoxTwo
    {
        get { return _textBoxTwo; }
        set
        {
            _textBoxTwo = value;
            // RaisePropertyChanged will notify the view that this property has changed
            RaisePropertyChanged();
        }
    }

    // Property to which your TextBoxThree value is bound
    private string _textBoxThree;
    public string TextBoxThree
    {
        get { return _textBoxThree; }
        set
        {
            _textBoxThree = value;
            // RaisePropertyChanged will notify the view that this property has changed
            RaisePropertyChanged();
        }
    }

    /// <summary>
    /// Property to which your button Click is bound
    /// </summary>
    public IMvxCommand OnClickCommand
    {
        get
        {
            return new MvxCommand(() =>
            {
                IsValidPlay();
            });
        }
    }

    private void IsValidPlay()
    {
        // Instead of retrieving the textbox values by the parameters p1, p2 and p3 we can use them like this
        if(TextBoxOne != string.Empty 
           && TextBoxTwo != string.Empty 
           && TextBoxThree != string.Empty)
        {
            // Invoke eventhandler to broadcast
            ValidPlayValueEventHandler.Invoke(this, new ValidPlayValueEventArgs(true));
        }
        else
        {
            // Invoke eventhandler to broadcast
            ValidPlayValueEventHandler.Invoke(this, new ValidPlayValueEventArgs(false));
        }
    }
}

您的布局可能如下:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView  
        android:id="@+id/textBoxOne"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        local:MvxBind="Text TextBoxOne" />

    <TextView  
        android:id="@+id/textBoxTwo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        local:MvxBind="Text TextBoxTwo" />

    <TextView  
        android:id="@+id/textBoxThree"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        local:MvxBind="Text TextBoxThree" />

    <Button 
        android:id="@+id/myButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click my button"
        local:MvxBind="Click OnClickCommand" />

</LinearLayout>