Search code examples
c#xamarinmvvmdata-binding

Command not firing on current item


I have a CarouselView. The ItemsSource is binded to an ObservableCollection of type AlarmEvent. AlarmEvent is a base class for different types of alarm events (Generic, Fr, Vfr, Anpr). The ItemTemplate changes depending on the type of CurrentItem. This works.

Xaml:

<CarouselView x:Name="cvAlarmEvents"
              ItemsSource="{Binding AlarmEvents}"
              CurrentItem="{Binding SelectedAlarmEvent}"
              CurrentItemChangedCommand="{Binding CmdSelectedAlarmEventChanged}"
              ItemTemplate="{StaticResource AlarmEventDataTemplateSelector}"
              Grid.Row="2"
              Margin="0, 2, 0, 0"
              BackgroundColor="#141d3d"                      
              IsVisible="true"/>

Template Selector:

public class AlarmEventDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate Generic { get; set; }
    public DataTemplate Fr { get; set; }
    public DataTemplate Tfr { get; set; }
    public DataTemplate Anpr { get; set; }

    public AlarmEventDataTemplateSelector()
    {
        Generic = new DataTemplate(typeof(GenericView));
        Fr = new DataTemplate(typeof(FrView));
        Tfr = new DataTemplate(typeof(TfrView));
        Anpr = new DataTemplate(typeof(AnprView));
    }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        var alarmEvent = item as AlarmEvent;

        switch (alarmEvent.Type)
        {
            case Enums.AlarmEventType.None:
                return null;
            case Enums.AlarmEventType.Generic:
                return Generic;
            case Enums.AlarmEventType.FaceRecognition:
                return Fr;
            case Enums.AlarmEventType.TemperatureFaceRecognition:
                return Tfr;
            case Enums.AlarmEventType.ANPR:
                return Anpr;
            default:
                return null;
        }
    }
}

GenericView, FrView etc inherit from ContentView. The actual command bindings are inside the DataTemplate (ContentView) which is returned from AlarmEventDataTemplateSelector:

<ImageButton Source="CamWhite1"
                                         BackgroundColor="Transparent"
                                         Scale="1"
                                         BorderColor="White"
                                         BorderWidth="3"
                                         Padding="10"
                                         Margin="10, 5"
                                         Command="{Binding CmdAddPic}" />

I have plenty of data bindings on the model which all work, aside from the Command bindings. I've tested the buttons with OnClick events and they fire as they should, which makes me think that the Command data binding is not working.

Here is how the command code looks inside AlarmEvent

public class AlarmEvent : BaseModel
    {
        public Command CmdAddPic { get; set; }

        public AlarmEvent()
        {
            CmdAddPic = new Command(AddPic);
        }

        public void AddPic()
        {
            // I dont fire and this makes me sad ;(
        }
    }

I cannot find a single thread online about this problem. I can find countless of threads where they are trying to bind a command from a selected item to their viewmodel. THIS IS NOT WHAT I WANT. I simply want the command binding to work on my data model (AlarmEvent), and I am stumped as to why it doesn't work. Perhaps I am missing something obvious?


Solution

  • I am a silly bum for not realising this sooner, the fix was:

    Instead of auto property like so -

    public Command CmdSubmitUserMedia{ get; set; }
    

    I needed to use a full property like so -

    private Command cmdSubmitUserMedia;
            [Ignore]
            public Command CmdSubmitUserMedia
            {
                get { return cmdSubmitUserMedia; }
                set { SetProperty(ref cmdSubmitUserMedia, value); }
            }