在WPF MVVM中使用按钮删除列表框中的项目 [英] Delete an item in a listbox with a button, in wpf MVVM

查看:91
本文介绍了在WPF MVVM中使用按钮删除列表框中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有问题.看起来很简单,但并不是那么容易.我有两个列表框,其中包含对象.一个充满了可用的对象,另一个充满了,我可以通过拖放来填充它.如果您填充此空白列表框,则这些项也将添加到的列表中,这是另一个对象的属性.但是现在我的问题是,如何通过单击按钮可以轻松地删除此列表框中的对象.

I have a problem. It seems a simple thing but it isn't that easy. I have two listboxes, with objects in it. One is full with available objects and the other is empty, and I can fill this up with drag and drop. If you fill this empty listbox, the items are also added to a list of, this is a property of another object. But now my question is how I can easily delete an object in this listbox by clicking on a button.

我尝试了一些操作,但无法运行. 这是我的xaml:

I tried something but it wouldn't run. Here is my 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");
        }
    }               
}

有人可以帮我吗?

推荐答案

您需要了解两件事:

  • 首先,不要忘记将ListBox绑定到ObservableCollection而不是经典的IList.否则,如果您的命令实际上被触发并从列表中删除了一项,则用户界面将完全不变
  • 第二,您的命令在这里永远不会被创建.让我解释.您正在将删除"按钮绑定到命令命令".它有吸气剂.但是,如果您调用get,它将返回什么?没什么,命令为空...
  • First, Don't forget to bind your ListBox to an ObservableCollection rather than to a classic IList. Otherwise, if your command is actually fired and removes an item from the list, the UI wouldn't change at all
  • Second, your command here is never created. Let me explain. You are binding the Delete button to your command Commands. It has a getter. However, if you call get, what will it return? Nothing, the command is null...

这是我建议您工作的方式:创建一个通用命令类(按照教程,我将其称为RelayCommand,但名称无关紧要):

Here is the way I'd advise you to work: Create a generic command class (I called it RelayCommand, following a tutorial... but the name doesn't matter):

/// <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中,创建一个属性命令,并定义实际的getter(您不必使用setter,您可以将其忘记):

Then, in your ViewModel, create a property command, and define the actual getter (you don't have to use the setter, you can just forget it):

private RelayCommand _deleteCommand;

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

这意味着当您调用命令时,它将调用函数DeleteItem

This means that when you call your command, it will call the function 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");
                    }
                }
    }

然后就可以了:)

这篇关于在WPF MVVM中使用按钮删除列表框中的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆