WPF - ViewModel'e bağlı ListView'ü yenile

Oct 19 2020

Dakikada bir uygulama yazıyorum ve bir Görünüm Modelinden öğeleri görüntüleyen ListView ile ilgili bir sorunla karşılaştım; bahsedilen görünüm modelinde "Selected" bir özellik var ve bu sadece bir bool ve bunu ListView'ın "IsSelected" özelliğine bağlarım.

Seçili her öğe üzerinde yinelenen ve onu yanlış olarak ayarlayan "Seçimi Temizle" düğmesi var; bu çalışır ve komut güncellenir ve hiçbir şey olmadığı için düğmeler artık etkin değildir Selected == true.

Resimlerde

Öğe seçildi; düğmeler mevcuttur.

"Seçimi Temizle" düğmesine basıldı

Bu noktada, öğeyi seçmek için artık denetimi tıklayamıyorum; Seçimi kaldırmak için tıklamayı kontrol etmem gerekiyor, bu da her şeyi devre dışı bırakıyor ve hiçbir şey seçilmedi.

İşte kontrol için XAML - neyi yanlış yapıyor olabileceğimden emin değilim, ancak şu ana kadar bir cevap bulamıyorum.

<ListView ItemsSource="{Binding AssignableItems, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" SelectionMode="Extended">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem" BasedOn="{StaticResource lviStyleBase}">
            <Setter Property="IsSelected" Value="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Created" DisplayMemberBinding="{Binding ContactCreated}" Width="Auto" />
            <GridViewColumn Header="Contact Name" DisplayMemberBinding="{Binding ContactName}" Width="Auto" />
            <GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="Auto" />
        </GridView>
    </ListView.View>
</ListView>

İşte ViewModel:

namespace CSI.ViewModels
{
    public class AssignViewModel
        : ModelBase
    {
        #region Properties
        private bool viewingFilters;

        public bool Filtering
        {
            get { return viewingFilters; }
            set { if ( SetValue(ref viewingFilters, value) ) Notify(); }
        }

        private bool assigning;

        public bool Assigning
        {
            get { return assigning; }
            set { if ( SetValue(ref assigning, value) ) Notify(); }
        }

        private string viewTitle = "Assign";
        public string ViewTitle
        {
            get => $"{viewTitle}{(Filtered ? " (filtered)" : "")}";
        }

        private AssignFilterValuesModel filters;

        public AssignFilterValuesModel Filters
        {
            get { return filters; }
            set { SetValue(ref filters, value); }
        }

        public bool Filtered
        {
            get
            {
                if ( filters == null ) return false;

                return assignables.Count() != AssignableItems.Count();
            }
        }

        private bool loading;

        public bool Loading
        {
            get { return loading; }
            set { SetValue(ref loading, value); }
        }

        private ObservableCollection<AssignableWorkItemModel> assignables;
        public ObservableCollection<AssignableWorkItemModel> AssignableItems
        {
            get
            {
                if ( assignables == null ) return null;
                if ( Filters == null ) return assignables;

                var retval = assignables.Where(x => 1 == 1);

                if ( Filters.Dealers.Any(x => x.Selected) )
                    retval = retval.Where(x => filters.Dealers.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.Dealer));

                if ( Filters.VehicleModels.Any(x => x.Selected) )
                    retval = retval.Where(x => filters.VehicleModels.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.VehicleModel));

                return new ObservableCollection<AssignableWorkItemModel>(retval);
            }
            set => SetValue(ref assignables, value);
        }
        private ObservableCollection<AssignableWorkItemModel> selected;
        public ObservableCollection<AssignableWorkItemModel> SelectedItems
        {
            get => selected;
            set => SetValue(ref selected, value);
        }
        #endregion
        #region Commands
        private RelayCommand displayFilterScreen;
        public void Execute_DisplayFilters(object _)
        {
            Filtering = true;
        }
        public bool CanExecute_DisplayFilters(object _) => !Filtering;
        public RelayCommand DisplayFilters
        {
            get => displayFilterScreen ?? (displayFilterScreen = new RelayCommand(Execute_DisplayFilters, CanExecute_DisplayFilters));
        }

        private RelayCommand applyFilters;
        public void Execute_ApplyFilters(object _)
        {
            Filtering = !Filtering;
            Notify(nameof(AssignableItems));
            Notify(nameof(Filtered));
            Notify(nameof(ViewTitle));
        }
        public bool CanExecute_ApplyFilters(object _) => Filtering;
        public RelayCommand ApplyFilters
        {
            get => applyFilters ?? (applyFilters = new RelayCommand(Execute_ApplyFilters, CanExecute_ApplyFilters));
        }

        private RelayCommand doAssign;
        public void Execute_Assign(object _)
        {
            UserSelectWindow us = new UserSelectWindow();
            us.Owner = Application.Current.MainWindow;

            ViewModelServer.UserSelectVM.Prompt = "Select the user you wish to assign these items to";
        }
        public bool CanExecute_Assign(object _) => !Filtering && (bool)AssignableItems?.Any(x => x.Selected);
        public RelayCommand Assign
        {
            get => doAssign ?? (doAssign = new RelayCommand(Execute_Assign, CanExecute_Assign));
        }

        private RelayCommand clrSelection;
        public void Execute_ClearSelection(object _)
        {
            AssignableItems?.Where(x => x.Selected).ToList().ForEach(x => x.Selected = false);
        }
        public bool CanExecute_ClearSelection(object _) => (bool)AssignableItems?.Any(x => x.Selected);
        public RelayCommand ClearSelection
        {
            get => clrSelection ?? (clrSelection = new RelayCommand(Execute_ClearSelection, CanExecute_ClearSelection));
        }
        #endregion
        #region Constructors
        
        #endregion
    }
}

Yanıtlar

huzi8t9 Oct 24 2020 at 15:17

Çözüm, SelectedIndex için bir bağlama eklemek ve ClearSelection'ı çağırırken değeri -1 olarak ayarlamaktı; buradan ipucu