问题
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:
Bind the OnClick listener of the button to the
onClikCommand
method as shown in the code below.When the
onClikCommand
is called I expect the value of the Text attribute of theTextView
to change according to the evaluation of the if-statement.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