Как заполнить ListBox из списка посредством DelegateCommand в WPF? - PullRequest
0 голосов
/ 27 апреля 2020

Я столкнулся с проблемой при попытке заполнить свой ListBox. У меня есть кнопка в моем файле xaml:

<Button Content="Show" Command="{Binding ShowSongsBy}" ... >

У меня также есть ListBox:

<ListBox x:Name="sorted" ItemsSource="{Binding SortedListVM}" ... >

В моей ViewModel у меня есть:

        private List<string> _sortedList;
        public List<string> SortedListVM
        {
            set
            {
                _sortedList = value;
                onPropertyChanged();
            }
            get { return _sortedList; }
        }

и

        public event PropertyChangedEventHandler PropertyChanged;

        public void onPropertyChanged([CallerMemberName]string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }

Когда я нажимаю кнопку, происходит следующее (также в ViewModel):

public ICommand ShowSongsBy
        {
            get
            {
                return new DelegateCommand((obj) =>
                {
                    SortedListVM = new List<string>();

                    List<string> testlist = new List<string>();
                    testlist.Add("1");
                    testlist.Add("2");

                    foreach (string i in testlist)
                    {
                        SortedListVM.Add(i);
                    }
                });
            }
        }

Что я ожидаю увидеть в ListBox: «1» и «2». Вместо этого я вижу только «1»

Я не могу понять, в чем проблема. Также, если я изменю код на этот:

public ICommand ShowSongsBy
{
...
                    foreach (string i in testlist)
                    {
                        SortedListVM.Add(i);
                    }

                    SortedListVM.Add("Test1");
...

, я вижу то, что ожидаю увидеть в ListBox: «1», «2» и «Test1».

Что мне делать делать, если я хочу, чтобы в списке были только "1" и "2"?

Мой класс DelegateCommand:

class DelegateCommand : ICommand
    {
        private Action<object> execute;
        private Func<object, bool> canExecute;

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return this.canExecute == null || this.canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            this.execute(parameter);
        }
    }    

Спасибо.

1 Ответ

1 голос
/ 27 апреля 2020

Используйте ObservableCollection вместо List.

private ObservableCollection<string> _sortedList;
public ObservableCollection<string> SortedListVM
{
    get => _sortedList;
    set
    {
        _sortedList = value;
        onPropertyChanged();
    }
}

... и делайте то, что вы хотите с ним делать. Так же, как вы работаете с List.

ListBox, будет динамически обновлять его макет, когда вы будете вносить какие-либо изменения в коллекцию.

...