Подсчитайте выбранные флажки в xamarin collectionview

#c# #xamarin #checkbox

Вопрос:

У меня есть представление коллекции с флажком. Я хочу подсчитать количество флажков, которые были выбраны, и показать это значение в метке (строка Sel). Я думаю, что в основном я это сделал, однако этикетка не обновляется. Я думаю, что это связано с тем, что не вызывается свойство, измененное в правильном месте, которое обновило бы метку. Я все еще ломаю голову над MVVM. Спасибо

Вид модели:

 public class MeetAWalkerViewModel : INotifyPropertyChanged
 {
       
       
     public ObservableCollection<PetProfile> source;
     public ObservableCollection<PetProfile> PetInfo { get; private set; }
     public ObservableCollection<PetProfile> EmptyPetInfo
     {
         get => source;
         private set
         {
             if (value != source)
             {
                 source = value;
                 OnPropertyChanged(nameof(EmptyPetInfo));
             }
         }
     }
     
        
     public string Sel { get; private set; }

     public MeetAWalkerViewModel()
     {
            
         var count = EmptyPetInfo.Count(t => t.Selected);
         Sel = "Amount of selected pets"   Convert.ToString(count);
     }

       
        
     #region INotifyPropertyChanged
     public event PropertyChangedEventHandler PropertyChanged;
     void OnPropertyChanged([CallerMemberName] string propertyName = null)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
     #endregion
 }
 

Xaml:

 <CollectionView  x:Name="petCollectionView"  ItemsSource="{Binding EmptyPetInfo}">
                 <CollectionView.ItemTemplate>
                     <DataTemplate>
                         <Grid Padding="10" RowDefinitions="80" ColumnDefinitions="120,60,60">
                             <Image Grid.Column="0"
                                Grid.Row="0"
                                x:Name="PetImage"
                                Source="{Binding imageUrl}"/>
                             <Label Grid.Column="1"
                                Grid.Row="0"
                                Text="{Binding PetName}"
                                FontAttributes="Bold"
                                x:Name="labelpetname" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                             <CheckBox  Grid.Row="0" Grid.Column="2" HorizontalOptions="End" IsChecked="{Binding Selected, Mode=TwoWay}" CheckedChanged="CheckBox_CheckedChanged" BindingContext="{Binding .}"/>
                         </Grid>
                     </DataTemplate>
                 </CollectionView.ItemTemplate>
             </CollectionView>
 

Ответ №1:

Я сделал образец на основе вашего кода, он работает правильно.

Вы можете обратиться к следующему коду:

MeetAWalkerViewModel.cs

  public class MeetAWalkerViewModel: INotifyPropertyChanged
{
    public ObservableCollection<PetProfile> source;
    //public ObservableCollection<PetProfile> PetInfo { get; private set; }
    public ObservableCollection<PetProfile> EmptyPetInfo
    {
        get => source;
        private set
        {
            if (value != source)
            {
                source = value;
                OnPropertyChanged(nameof(EmptyPetInfo));
            }
        }
    }

    int _count;
    public int Count
    {
        set
        {
            if (_count != value)
            {
                _count = value;
                OnPropertyChanged(nameof(Count));

                Sel = "Amount of selected pets is : "   Convert.ToString(_count);
            }
        }
        get
        {
            return _count;
        }
    }

    public void updateCount(int count) { 
    
    }

    String sel;
    public String Sel
    {
        set
        {
            if (sel != value)
            {
                sel = value;
                OnPropertyChanged(nameof(Sel));
            }
        }
        get
        {
            return sel;
        }
    }

    public MeetAWalkerViewModel()
    {
        EmptyPetInfo = new ObservableCollection<PetProfile>();
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet1", IsSelected= false,ImageUrl= "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet2", IsSelected = false, ImageUrl = "watermelon.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet3", IsSelected = false, ImageUrl = "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet4", IsSelected = false, ImageUrl = "watermelon.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet5", IsSelected = false, ImageUrl = "cherry.png" });
        EmptyPetInfo.Add(new PetProfile { PetName = "Pet6", IsSelected = false, ImageUrl = "watermelon.png" });

        foreach (PetProfile petProfile in EmptyPetInfo) {
            if (petProfile.IsSelected)
            {
                Count  ;
            }

        }
        Sel = "Amount of selected pets is : "   Convert.ToString(Count);
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}
 

Главная страница.xaml

 <StackLayout HorizontalOptions="Center"  Padding="10" >
    <Label   x:Name="countSelectedItemsLabel" Text="{Binding Sel}" FontSize="20" />

    <CollectionView  x:Name="petCollectionView"  ItemsSource="{Binding EmptyPetInfo}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10" RowDefinitions="80" ColumnDefinitions="120,60,60">
                    <Image Grid.Column="0"
                            Grid.Row="0"
                            x:Name="PetImage"
                            Source="{Binding ImageUrl}"/>
                    <Label Grid.Column="1"
                            Grid.Row="0"
                            Text="{Binding PetName}"
                            FontAttributes="Bold"
                            x:Name="labelpetname" VerticalTextAlignment="Center" HorizontalTextAlignment="Center"/>
                    <CheckBox  Grid.Row="0" Grid.Column="2" HorizontalOptions="End" IsChecked="{Binding IsSelected, Mode=TwoWay}" CheckedChanged="CheckBox_CheckedChanged" BindingContext="{Binding .}"/>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</StackLayout>
 

Главная страница.xaml.cs

 public partial class MainPage : ContentPage
    {

        MeetAWalkerViewModel viewModel;

        int selectedCount = 0;

        public MainPage()
        {
            InitializeComponent();

            viewModel = new MeetAWalkerViewModel();
            BindingContext = viewModel;
        }

        private void CheckBox_CheckedChanged(object sender, CheckedChangedEventArgs e)
        {
            PetProfile model = (PetProfile)((CheckBox)sender).BindingContext;

            if (model.IsSelected)
            {
                selectedCount  ;
            }
            else
            {
                selectedCount--;
            }

            viewModel.Count = selectedCount;

        }
    }
 

PetProfile.cs

 public class PetProfile
{
    public string PetName { get; set; }

    public string ImageUrl { get; set; }

    public bool IsSelected { get; set; }
}
 

В результате получается:

введите описание изображения здесь

Комментарии:

1. Спасибо, это многое проясняет для меня в mvvm и о том, как реагировать на измененные события. Очень признателен

Ответ №2:

Вам нужно изменить строку следующим образом

 String sel ;
        public String Sel 
        {
            set
            {
                if (sel != value)
                {
                    sel = value;
                    OnPropertyChanged(nameof(Sel ));
                }
            }
            get
            {
                return sel ;
            }
        }