0

I'm in the process of trying to implement "Commanding" in my Xamarin Forms app, in order to follow MVVM architecture pattern.

For Buttons, it works just fine because you can just define Command in the XAML. But for a Picker, for example, you have to do the following (NOTE: xct:EventToCommandBehavior used the new Xamarin Community Toolkit):

<Picker x:Name="myBackgroundColorChoicePicker" SelectedItem="{Binding BGColorChoice, Mode=TwoWay}"
    x:FieldModifier="public"
    TextColor="{DynamicResource TextForegroundColor}"
    WidthRequest="300" HorizontalOptions="CenterAndExpand">

    <Picker.Items>
        <x:String>User Selected</x:String>
        <x:String>Totally White</x:String>
        <x:String>Totally Black</x:String>
    </Picker.Items>

    <Picker.Behaviors>
        <xct:EventToCommandBehavior
            EventName="SelectedIndexChanged"
            Command="{Binding ProcessBGColorChoiceCommand}"/>
    </Picker.Behaviors>
</Picker>

So, I expect that when the user changes the selected item in the Picker, that the Command ProcessBGColorChoiceCommand will be called from the ViewModel.

But, the Command in the ViewModel is NOT getting called. I set a breakpoint at the beginning of the Command code, and the breakpoint is NEVER reached.

Is there something that I'm missing? I can't get this to work.

The Binding Context is set at the top of the XAML like so:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:MedLemnMobile.ViewModels"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             x:Class="MedLemnMobile.Views.ColorPage"
             Title="Color"
             x:FieldModifier="public"
             x:Name="myColorPage"
             AutomationId="myColorPage"
             BackgroundColor="{DynamicResource PageBackgroundColor}"
             x:DataType="viewModels:ColorViewModel">

    <ContentPage.BindingContext>
        <viewModels:ColorViewModel/>
    </ContentPage.BindingContext>

And, the Command is defined in the ViewModel like so:

using MedLemnMobile.Classes;
using MedLemnMobile.Models;
using MedLemnMobile.Views;
using System;
using System.Globalization;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.CommunityToolkit;

namespace MedLemnMobile.ViewModels
{
    public class ColorViewModel : ViewModelBase
    {
        public ICommand GotoMenuCommand { get; }
        public ICommand ProcessBGColorChoiceCommand { get; }
        public ICommand ProcessFGColorChoiceCommand { get; }
        public ICommand ProcessBGRedSliderCommand { get; }
        public ICommand ProcessBGGreenSliderCommand { get; }
        public ICommand ProcessBGBlueSliderCommand { get; }
        public ICommand ProcessFGRedSliderCommand { get; }
        public ICommand ProcessFGGreenSliderCommand { get; }
        public ICommand ProcessFGBlueSliderCommand { get; }

        public ColorViewModel()
        {
            IsBGColorChoiceUserSelected = EquationLibrary.MyCurrentEqSet.BackgroundColorChoice == "User Selected";
            IsFGColorChoiceUserSelected = EquationLibrary.MyCurrentEqSet.ForegroundColorChoice == "User Selected";

            GotoMenuCommand = new Command<ColorPage>(GotoMenu);
            ProcessBGColorChoiceCommand = new Command<ColorPage>(ProcessBGColorChoice);
            ProcessFGColorChoiceCommand = new Command<ColorPage>(ProcessFGColorChoice);
            ProcessBGRedSliderCommand = new Command<ColorPage>(ProcessBGRedSlider);
            ProcessBGGreenSliderCommand = new Command<ColorPage>(ProcessBGGreenSlider);
            ProcessBGBlueSliderCommand = new Command<ColorPage>(ProcessBGBlueSlider);
            ProcessFGRedSliderCommand = new Command<ColorPage>(ProcessFGRedSlider);
            ProcessFGGreenSliderCommand = new Command<ColorPage>(ProcessFGGreenSlider);
            ProcessFGBlueSliderCommand = new Command<ColorPage>(ProcessFGBlueSlider);
        }
  • Any warnings showing in the output console? Could possibly be a binding context issue that would show there. Also, can we see the VM with the command info. – Andrew Feb 04 '21 at 16:42
  • I just tested it and it with your xaml+my code and it is working fine, you have probably missed something or did something wrong in your bindings. could you check your binding? share ViewModel and where you set the BindingContext? – Cfun Feb 04 '21 at 16:44
  • I have edited the issue to include the top of the XAML file where the Binding Context is located, and the top of the ViewModel file where the Command is declared. – T. A. Pfaff Feb 04 '21 at 17:12
  • The method ProcessBGColorChoice is defined in the ViewModel. – T. A. Pfaff Feb 04 '21 at 17:19
  • I'm currently using XF 5.0.0.1874 and XCT 1.0.2 – T. A. Pfaff Feb 04 '21 at 17:34
  • You missed the parameter, which didn't fit your command ```new Command()``` – Shaw Feb 04 '21 at 22:52

1 Answers1

1

The command ProcessBGColorChoiceCommand was instantiated with a parameter ColorPage.
But no command parameter binding in your xaml. To fix that, change the command definition

ProcessBGColorChoiceCommand = new Command(ProcessBGColorChoice);
//also check other commands

And get selected value from property BGColorChoice in ProcessBGColorChoice method.

Shaw
  • 907
  • 1
  • 8
  • 20
  • -> Thanks so much for spotting the missing parameter issue. My code now runs as expected. Why couldn't Visual Studio have notified me somehow about this solution? – T. A. Pfaff Feb 04 '21 at 23:38
  • That's [member overloading](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/member-overloading) to handle different parameters in c#. You just didn't define the appropriate one, not means an error for vs, just like type `if (false) {somethinghappens}`, which would never happen. – Shaw Feb 05 '21 at 00:28