I've created a CustomElementTagger
class which allows me to set
and get
custom set tags on view elements. I need this because I want to have a single command
that gets executed but has different behavior on the corresponding tag on the element. In the ViewModel
I want to receive the tag and work with it accordingly but the Command
never executes. I've also tried it as an Object
but the object never comes back as I need it and when I try to cast the Object
to the ImageButton
I get an error that I cannot cast this Object
.
I've looked up youtube videos by JamesMontemagno but everything I look at that is using EventToCommandBehaviour
are ListViews
with EventName = "ItemSelected"
.
Also viewed a number of articles and neither of those helped me to understand how to make this work.
All I want is to get my ImageButton
sender.
Many Thanks in advance.
CustomElementTagger: Class
public class CustomElementTagger
{
public static readonly BindableProperty TagProperty = BindableProperty.Create("Tag", typeof(object), typeof(CustomElementTagger), null);
public static string GetTag(BindableObject bindable)
{
return (string)bindable.GetValue(TagProperty);
}
public static void SetTag(BindableObject bindable, string value)
{
bindable.SetValue(TagProperty, value);
}
}
XAML
<ImageButton WidthRequest="200"
HeightRequest="200"
HorizontalOptions="CenterAndExpand"
VerticalOptions="EndAndExpand"
BackgroundColor="Red"
tagger:CustomElementTagger.Tag="1">
<ImageButton.Behaviors>
<xct:EventToCommandBehavior EventName="Clicked"
Command="{Binding KeyboardTapCommand}" />
</ImageButton.Behaviors>
</ImageButton>
ViewModel
public class SpellViewModel: BaseViewModel
{
public ICommand NextPageCommand { get; private set; }
public ICommand PreviousPageCommand { get; private set; }
public ICommand KeyboardTapCommand { get; private set; }
public SpellViewModel()
{
Initialize();
}
void Initialize()
{
InitializeCommands();
}
void InitializeCommands()
{
NextPageCommand = Navigation.NextPage(nameof(CopyWhatIDoPage));
PreviousPageCommand = Navigation.PreviousPage();
KeyboardTapCommand = new Command<ImageButton>(ReadVirtualKeyboardTap);
}
void ReadVirtualKeyboardTap(ImageButton btn) //This never gets executed...
{
var tag = CustomElementTagger.GetTag(btn);
}
}
CodePudding user response:
I don't know how EventToCommandBehavior
works under the hood. But I argue your approach here, is against MVVM. Generally, the view models should be unaware of the details of the view. Here the ImageButton
is a UI element hence a view detail, which your view model should not care about. You can use CommandParameter
to achieve what you want. Usually, using command parameters, you can have a single general command that can act differently based on the parameter which in your case is the tag you are assigning.
View:
<ImageButton WidthRequest="200"
HeightRequest="200"
HorizontalOptions="CenterAndExpand"
VerticalOptions="EndAndExpand"
BackgroundColor="Red"
CommandParameter="1"
Command="{Binding KeyboardTapCommand}" />
View Model:
KeyboardTapCommand = new Command<string>(ReadVirtualKeyboardTap);
void ReadVirtualKeyboardTap(string tag)
{
}
This way, the tag (as a command parameter) will be directly sent to your ReadVirtualKeyboardTap
method. And you can decide what to do based on that.