dimanche 23 juillet 2017

List Box items with checkboxes, multiselect not working properly in WPF MVVM

So I have a ListBox with CheckBox-es that have the IsChecked property bound to the Item's property called IsSelected. That produces a weird behavior where if I click on the item itself it checks the checkbox (good) and sets the property on the item (good), but doesn't actually select the item in the list box, ie. the highlighting isn't there. I am guessing that the ListBox IsSelected property needs to be set as well for that right? Now, I am trying to get the multi-select behavior to work so I changed the SelectionMode to Extended. Now, I can select only Items, not the checkboxes. What happens is that if I use SHIFT + click by pointing at the area next to the item, not the item itself, then it select multiple items, but clicking on the items themselves doesn't do the trick of multi-selection not does it check the checkboxes. What is going on in here?

I would like to be able to select multiple items by holding shift etc, and have that trigger the property on the Elevation item so I know which ones are checked. Any help is appreciated.

Here's my XAML:

<ListBox x:Name="LevelsListBox"
                         ItemsSource="{Binding Elevations, UpdateSourceTrigger=PropertyChanged}"
                         SelectionMode="Extended"
                         BorderThickness="0">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}"/>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

My View Model:

public class AxoFromElevationViewModel : ViewModelBase
    {
        public AxoFromElevationModel Model { get; }
        public RelayCommand CheckAll { get; }
        public RelayCommand CheckNone { get; }

        public AxoFromElevationViewModel(AxoFromElevationModel model)
        {
            Model = model;
            Elevations = Model.CollectElevations();
            CheckAll = new RelayCommand(OnCheckAll);
            CheckNone = new RelayCommand(OnCheckNone);
        }


        private void OnCheckNone()
        {
            foreach (var e in Elevations)
            {
                e.IsSelected = false;
            }
        }


        private void OnCheckAll()
        {
            foreach (var e in Elevations)
            {
                e.IsSelected = true;
            }
        }

        /// <summary>
        /// All Elevation Wrappers.
        /// </summary>
        private ObservableCollection<ElevationWrapper> _elevations = new ObservableCollection<ElevationWrapper>();
        public ObservableCollection<ElevationWrapper> Elevations
        {
            get { return _elevations; }
            set { _elevations = value; RaisePropertyChanged(() => Elevations); }
        }
    }

Finally my Elevation Class:

public sealed class ElevationWrapper : INotifyPropertyChanged
    {
        public string Name { get; set; }
        public ElementId Id { get; set; }
        public object Self { get; set; }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; RaisePropertyChanged("IsSelected"); }
        }

        public ElevationWrapper(View v)
        {
            Name = v.Name;
            Id = v.Id;
            Self = v;
            IsSelected = false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propname)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
        }
    }




Aucun commentaire:

Enregistrer un commentaire