В каком контексте предпочтительны ICommand и Local: Mvx - PullRequest
0 голосов
/ 13 января 2019

Я разрабатываю приложение для Android с использованием Xamarin и MvvmCross. Как видно из макета, размещенного внизу этого вопроса, у меня есть TextView и Button. Я хочу добиться следующих вещей:

  1. Свяжите прослушиватель кнопки OnClick с методом onClikCommand, как показано в коде ниже.

  2. Когда вызывается onClikCommand, я ожидаю, что значение атрибута Text TextView изменится в соответствии с оценкой оператора 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 голосов
/ 14 января 2019

Если я правильно понимаю ваш вопрос, вы хотите знать разницу между:

<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 текстовых поля вместо одного.

Пример того, как может выглядеть ваша 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>
...