In which context ICommand and Local:Mvx are prefered

主宰稳场 提交于 2019-12-11 04:25:53

问题


I'm developing an Android application using Xamarin and MvvmCross. As seen in the layout posted at the bottom of this question I have a TextView and a Button. I want to achieve the following things:

  1. Bind the OnClick listener of the button to the onClikCommand method as shown in the code below.

  2. When the onClikCommand is called I expect the value of the Text attribute of the TextView to change according to the evaluation of the if-statement.

  3. Broadcast the value of the evaluation via a cutomized EventHandler and EventArgs.

Concerning the binding part, I've read several tutorials and I found that some developers are using

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

and some are using

local:Mvx 

My question is, what is the difference between both kinds of bindings and in which context either of them is preferred?

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));
    }
}

Layout

<TextView
Command="{Binding isValidPlayValue}"

<Button
Command="{Binding onClikCommand}"

回答1:


If I understand your question right you want to know the difference between:

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

and:

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

Both code blocks achieve the same thing but the difference is that the first code block is for Android applications and the second block is for UWP applications. Since you are creating a Android application you should go for the first option. I would expect that your Android application would not run when using the second code block.

Extra:

For the implementation of the functionality you described in points 1, 2 and 3 I would like to give you a tip:

Don't pass the value of your TextBox as a parameter to isValidPlay. Instead bind the value of your TextBox to a property in your ViewModel. Question: what is it that the parameters string p1, string p2, string p3 represent? I assume that you actually want to have 3 TextBoxes instead of one.

An example of what your ViewModel could look like:

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));
        }
    }
}

And your Layout could look like:

<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>


来源:https://stackoverflow.com/questions/54173093/in-which-context-icommand-and-localmvx-are-prefered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!