1
votes

I have a collection view with the command binded, but for some reason when I select an item the action is never called in the viewmodel, heres my ViewModel code:

public class PlatillosViewModel : INotifyPropertyChanged
{
    private INavigation Navigation;
    public event PropertyChangedEventHandler PropertyChanged;
    public List<PlatilloModel> Platillos { get; set; }
    public List<GrupoModel> Grupos { get; set; }
    public ICommand SelectedGroupCommand => new Command(SelectedGroup);

    public PlatillosViewModel(INavigation navigation)
    {
        Navigation = navigation;
        PlatillosRepository repository = new PlatillosRepository();
        Platillos = repository.GetAll().ToList();
        GrupoRepository grupoRepository = new GrupoRepository();
        Grupos = grupoRepository.GetAll().ToList();
    }

    public ICommand SelectedPlatilloCommand => new Command<PlatilloModel>(async platillo =>
    {
        await Navigation.PushAsync(new PlatilloView());
    });

    void SelectedGroup()
    {
        PlatillosRepository platillosRepository = new PlatillosRepository();
        //Platillos = platillosRepository.GetFilteredByGroup(grupoSeleccionado);
    }

    protected virtual void OnPropertyChanged(string property = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

And here is my Page:

<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ComanderoMovil.Views.PlatillosView"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
xmlns:behaviorsPack="clr-namespace:Xamarin.Forms.BehaviorsPack;assembly=Xamarin.Forms.BehaviorsPack">
<ContentPage.Content>
    <StackLayout>
        <SearchBar> </SearchBar>
        <StackLayout Orientation="Horizontal">
            <CollectionView ItemsSource="{Binding Grupos}"
                            HeightRequest="50"
                            ItemsLayout="HorizontalList"
                            SelectionMode="Single"
                            SelectedItem="{Binding SelectedGroupCommand, Mode=TwoWay}">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <ContentView>
                            <Label Margin="2"
                                    BackgroundColor="Black"
                                    Text="{Binding nombre}"
                                    TextColor="White"
                                   VerticalTextAlignment="Center"
                                   HorizontalTextAlignment="Center"
                                   FontSize="Small"></Label>
                        </ContentView>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
        <ListView Grid.Column="2"
                  HasUnevenRows="True"
                  SeparatorVisibility="None"
                  ItemsSource="{Binding Platillos}">
            <ListView.Behaviors>
                <behaviorsPack:SelectedItemBehavior Command="{Binding SelectedPlatilloCommand}"/>
            </ListView.Behaviors>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ContentView Padding="2, 5, 5, 0">
                            <Frame OutlineColor="Black"
                                   Padding="10"
                                   HasShadow="False">
                                <StackLayout Orientation="Horizontal">
                                    <Label Margin="10"
                                           Text="{Binding clave_platillo}"
                                           FontSize="Large"
                                           HorizontalOptions="Start"></Label>
                                    <Label Margin="10"
                                           HorizontalTextAlignment="End"
                                           Text="{Binding nombre}"></Label>
                                </StackLayout>
                            </Frame>
                        </ContentView>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>

I have tried adding the command to the items inside the collection view, replacing labels for buttons, but still doesn't work, I've also tried to use SelectionChangedCommand in the collection view, and still the same issue, the only way I can make it work is handling the item selection in the View, but I want to stay true to MVVM.

Here is my GrupoModel:

public class GrupoModel
{
    public string clave_grupo { get; set; }
    public int id_clasificacion { get; set; }
    public int id_grupo { get; set; }
    public string nombre { get; set; }
    public bool pedirClave { get; set; }
    public bool status { get; set; }
    public int tipo { get; set; }
}

and here is an image of what im trying to do:

enter image description here

2
The command Should go in the class of GrupoModel instead of the PlatillosViewModel William-H-M
What do you mean?, I have the PlatillosView Page, and the PlatillosViewModel, there is not GrupoView or GrupoViewModel, I want to manage the collection view like a top menu, sort of, I'll update my question with images, also I tried putting the command in the model class of grupo, still didn't workArturo Calvo

2 Answers

2
votes

If you read the document:

When the SelectionMode property is set to Single, a single item in the CollectionView can be selected. When an item is selected, the SelectedItem property will be set to the value of the selected item. When this property changes, the SelectionChangedCommand is executed (with the value of the SelectionChangedCommandParameter being passed to the ICommand), and the SelectionChanged event fires.

When you want to bind a Commond, you should bind to the SelectionChangedCommand instead of SelectedItem. Change your code like below and it will work:

   <CollectionView 
         HeightRequest="50"
         ItemsLayout="HorizontalList"
         SelectionMode="Single"
         SelectionChangedCommand="{Binding SelectedGroupCommand, Mode=TwoWay}"

    >
0
votes

The command should go in the class of GrupoModel instead of the PlatillosViewModel

public List<GrupoModel> Grupos { get; set; }

Should be "linked" to class GrupoModel that have properties and a commandwhich will listen, something like:

Class GrupoModel
{
    public int Id { get; set; }
    public string Foo { get; set; }

    public ICommand SelectedGroupCommand => new Command(Completar);
    private async void Completar()
    {
       await ViewModels.PlatillosViewModel.GetInstancia().SelectedGroup(this);
    }
}

This way each element of Grupos will have a command to listen.

BTW: Shouldn't Grupos be an ObservableCollection?