Удалить элемент в списке с помощью кнопки, в wpf MVVM - PullRequest
2 голосов
/ 29 марта 2011

У меня проблема. Это кажется простой вещью, но это не так просто. У меня есть два списка, с объектами в нем. Один заполнен доступными объектами, а другой пуст, и я могу заполнить его перетаскиванием. Если вы заполните этот пустой список, элементы также будут добавлены в список, это свойство другого объекта. Но теперь мой вопрос заключается в том, как я могу легко удалить объект в этом списке, нажав на кнопку.

Я попробовал что-то, но это не сработало. Вот мой xaml:

<ListBox ItemsSource="{Binding AvailableQuestions}"          
         DisplayMemberPath="Description" 
         dd:DragDrop.IsDragSource="True" 
         dd:DragDrop.IsDropTarget="True" Margin="0,34,0,339" Background="#CDC5CBC5"
         dd:DragDrop.DropHandler="{Binding}"/>

        <ListBox SelectedItem="{Binding Path=SelectedQuestionDropList, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" ItemsSource="{Binding SelectedQuestions}"
                 DisplayMemberPath="Description"
                 dd:DragDrop.IsDragSource="True" 
                 dd:DragDrop.IsDropTarget="True" Margin="0,201,0,204" Background="#CDC5CBC5"
                 dd:DragDrop.DropHandler="{Binding}"  />

 <Button Content="Delete" Height="23" 
         HorizontalAlignment="Left" 
         Margin="513,322,0,0"  
         Name="button1" 
         VerticalAlignment="Top" Width="75" Command="{Binding Commands}"    
         CommandParameter="Delete" />

вот моя модель:

// other stuff and properties..
public ICommand Commands { get; set; }

public bool CanExecute(object parameter)
{
    return true;
}
public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested += value; }
}
public void Execute(Object parameter)
{
    foreach (ExaminationQuestion exaq in this.Examination.ExaminationQuestions)
    {
        if (exaq.Question.Guid == SelectedQuestionDropList.Guid)
        {
            this.Examination.ExaminationQuestions.Remove(exaq);
            SelectedQuestions.Remove(SelectedQuestionDropList);
            OnPropertyChanged("SelectedQuestions");
        }
    }               
}

Может кто-нибудь помочь мне?

1 Ответ

6 голосов
/ 29 марта 2011

Вам нужно знать две вещи:

  • Во-первых, не забудьте связать свой ListBox с ObservableCollection, а не с классическим IList.В противном случае, если ваша команда действительно запущена и удаляет элемент из списка, пользовательский интерфейс вообще не изменится
  • Во-вторых, ваша команда здесь никогда не создается.Позволь мне объяснить.Вы связываете кнопку Удалить с вашей командой Commands.У него есть добытчик.Однако, если вы позвоните get, что он вернет?Ничего, команда пуста ...

Вот способ, которым я бы посоветовал вам работать: создайте общий класс команд (я назвал его RelayCommand, следуя учебному пособию ... но названиене имеет значения):

/// <summary>
    /// Class representing a command sent by a button in the UI, defines what to launch when the command is called
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Fields

        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;

        #endregion // Fields

        #region Constructors

        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }
        #endregion // Constructors

        #region ICommand Members

        //[DebuggerStepThrough]
        /// <summary>
        /// Defines if the current command can be executed or not
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute(parameter);
        }

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

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        #endregion // ICommand Members
    }

Затем в вашей ViewModel создайте команду свойства и определите фактический получатель (вам не нужно использовать установщик, вы можете просто забыть его):

private RelayCommand _deleteCommand;

public ICommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                {
                    _deleteCommand = new RelayCommand(param => DeleteItem());
                }
                return _deleteCommand;
            }
        }

Это означает, что при вызове вашей команды она вызовет функцию DeleteItem

Осталось только сделать:

   private void DeleteItem() {
//First step: copy the actual list to a temporary one
ObservableCollection<ExaminationQuestion> tempCollection = new ObservableCollection<ExaminationQuestion>(this.Examination.ExaminationQuestions);
//Then, iterate on the temporary one:
        foreach (ExaminationQuestion exaq in tempCollection)
                {
                    if (exaq.Question.Guid == SelectedQuestionDropList.Guid)
                    {
//And remove from the real list!
                        this.Examination.ExaminationQuestions.Remove(exaq);
                        SelectedQuestions.Remove(SelectedQuestionDropList);
                        OnPropertyChanged("SelectedQuestions");
                    }
                }
    }

И вотты идешь :) 1023 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...