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

Posted

技术标签:

【中文标题】在哪种情况下首选 ICommand 和 Local:Mvx【英文标题】:In which context ICommand and Local:Mvx are prefered 【发布时间】:2019-06-07 22:39:42 【问题描述】:

我正在使用 Xamarin 和 MvvmCross 开发一个 android 应用程序。从这个问题底部发布的布局中可以看出,我有一个TextView 和一个Button。 我想实现以下几点:

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

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

    通过定制的 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】:

如果我理解你的问题,你想知道两者之间的区别:

<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 个文本框而不是 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_
    android:layout_>

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

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

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

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

</LinearLayout>

【讨论】:

以上是关于在哪种情况下首选 ICommand 和 Local:Mvx的主要内容,如果未能解决你的问题,请参考以下文章

递归与手动堆栈 - 在哪种情况下哪个是首选?

CachedNetworkImage 和 CachedNetworkImageProvider 有啥区别?应该分别用在哪种情况下?

在哪种情况下使用 JPA @JoinTable 注释?

英语问题:future 在哪种情况下可数

在哪种情况下应该在情节提要中使用 Popover segue?

在哪种情况下我们应该在 Erlang 中使用 The Hybrid Approach Socket?