当鼠标悬停在它上面时,WPF从Combobox中删除项目(MVVM)

时间:2013-07-11 13:57:27

标签: c# wpf mvvm combobox catel

我有一个与Observeable Collection捆绑在一起的组合框。 Collection是自定义类的容器。

当我将鼠标光标悬停在下拉列表的项目上时,我需要通过按鼠标右键从组合框中删除一个任意项目。当项目突出显示时,我还需要通过按删除按钮来删除它。

我已经在后面的代码中有一个解决方案,但我需要使用MVVM-Pattern。

有人可以帮我解决这个问题吗?

提前Thx:)。

以下是我的代码:

我的ViewModel:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Catel.MVVM;
using System.Windows.Input;
using DeleteItemFromComboBox.Models;
using Catel.Data;

namespace DeleteItemFromComboBox.ViewModels
{
    public class MainWindowVM : ViewModelBase
    {

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="MainWindowVM"/> class.
        /// </summary>
        public MainWindowVM()
        {
            PreviewKeyDownCmd = new Command<KeyEventArgs>(PreviewKeyDownCmdExecute);
            PersonList = new ObservableCollection<Person>();
            PersonList.Add(new Person("AA"));
            PersonList.Add(new Person("BB"));
        }
        #endregion


        #region Properties
        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        public ObservableCollection<Person> PersonList
        {
            get { return GetValue<ObservableCollection<Person>>(PersonListProperty); }
            set { SetValue(PersonListProperty, value); }
        }

        /// <summary>
        /// Register the PersonList property so it is known in the class.
        /// </summary>
        public static readonly PropertyData PersonListProperty = 
            RegisterProperty("PersonList", typeof(ObservableCollection<Person>), null);
        #endregion


        #region Commands
        /// <summary>
        /// Gets the PreviewKeyDownCmd command.
        /// </summary>
        public Command<KeyEventArgs> PreviewKeyDownCmd { get; private set; }

        /// <summary>
        /// Method to invoke when the PreviewKeyDownCmd command is executed.
        /// </summary>
        private void PreviewKeyDownCmdExecute(KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                //********************What Should i do here?***************************
            }
        }
        #endregion
    }
}

XAML文件:

<Window x:Class="DeleteItemFromComboBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModels="clr-namespace:DeleteItemFromComboBox.ViewModels"
    Title="MainWindow" Height="350" Width="525"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:catel="http://catel.codeplex.com">

<Window.Resources>
    <ViewModels:MainWindowVM x:Key="ViewModel"/>
</Window.Resources>

<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
    <ComboBox Height="44" 
              HorizontalAlignment="Left" 
              Margin="12,12,0,0" 
              Name="comboBox1" 
              VerticalAlignment="Top" 
              Width="479"
              ItemsSource="{Binding PersonList, Mode=TwoWay}" >

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="PreviewKeyDown">
                <catel:EventToCommand Command="{Binding PreviewKeyDownCmd}" DisableAssociatedObjectOnCannotExecute="False" />
            </i:EventTrigger>
        </i:Interaction.Triggers>

    </ComboBox>
</Grid>

人类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Catel.MVVM;
using Catel.Data;
using System.Runtime.Serialization;

namespace DeleteItemFromComboBox.Models
{

#if !SILVERLIGHT
    [Serializable]
#endif
    public class Person : ModelBase
    {

        #region Constructors

        public Person() { }

        public Person(string name)
        {
            this.Name = name;
        }

#if !SILVERLIGHT
        protected Person(SerializationInfo info, StreamingContext context)
            : base(info, context) { }
#endif
        #endregion

        /// <summary>
        /// Gets or sets the property value.
        /// </summary>
        [Model]
        public string Name
        {
            get { return GetValue<string>(NameProperty); }
            private set { SetValue(NameProperty, value); }
        }

        /// <summary>
        /// Register the Name property so it is known in the class.
        /// </summary>
        public static readonly PropertyData NameProperty = 
            RegisterProperty("Name", typeof(string));

        public override string ToString()
        {
            return Name;
        }
    }
}

非MVVM项目中的Codebehind解决方案:

private void comboBox1_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Delete)
        {
            foreach (People item in comboBox1.Items)
            {
                ComboBoxItem cbi = this.comboBox1.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;

                if (cbi.IsHighlighted == true)
                {
                    peoples.Remove(item);
                    return;
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

最简单的方法是创建属性SelectedPerson。只要用户右键单击某个项目,它就会自动设置SelectedPerson。然后,您还可以创建一个工具栏,该工具栏使用与弹出窗口相同的命令来删除列表中的选定项目。

使用SelectedPerson方法时,可以使用以下代码:

MyCollection.Remove(SelectedPerson);
SelectedPerson = null;

确保在OnCanExecute中检查SelectedPerson!= null。

答案 1 :(得分:0)

我使用其中一种方法来解决问题:

  1. 将MouseButtonEventArgs e.Source转换为Combobox,然后应用上面提到的解决方案来完成任务。只需使用您选择的类型删除IPlan。

    private void Plan_PreviewMouseRightButtonDownCmd_Execute(MouseButtonEventArgs e)
    {
        ComboBox comboBox =  e.Source as ComboBox;
        if(comboBox!=null)
        {
            foreach (IPlan item in comboBox.Items)
            {
                ComboBoxItem cbi = comboBox.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
    
                if (cbi.IsHighlighted == true)
                    SelectedPlans.Remove(item);
    
                if (item == SelectedPlan)
                    SelectedPlan = null;
            }
        }
    }
    
  2. 使用此组合框的自定义实现,并将itemindex绑定到后面的代码中的属性。然后,您可以通过MyCollection.RemoveAt();

  3. 删除该项目

    http://www.codeproject.com/Articles/14255/ComboBox-firing-events-when-hovering-on-the-dropdo