Wpf 自定义listbox控件事件处理

Wpf 自定义listbox控件事件处理,wpf,event-handling,listbox,Wpf,Event Handling,Listbox,我遵循MVVM模式。我已经创建了自定义listbox控件,将其命名为ExtendedListbox 在xmal中,我定义了listbox和DefineItemSource属性 在我的viewmodel中,我将学生定义为可观察集合 公共可观测集合学生 运行时,我正在学生集合中添加/删除学生对象 在我的ExtendedListBox控件类中,我想知道从listbox的数据源中添加/删除哪个对象 在列表框的数据源中添加或删除任何项目时是否会触发任何事件?如果您想要MVVM样式,我建议使用System

我遵循MVVM模式。我已经创建了自定义listbox控件,将其命名为ExtendedListbox

在xmal中,我定义了listbox和DefineItemSource属性

在我的viewmodel中,我将学生定义为可观察集合

公共可观测集合
学生

运行时,我正在学生集合中添加/删除学生对象

在我的ExtendedListBox控件类中,我想知道从listbox的数据源中添加/删除哪个对象


在列表框的数据源中添加或删除任何项目时是否会触发任何事件?

如果您想要
MVVM
样式,我建议使用
System.Windows.Interactivity
并使用“行为”

示例用法

行为类

public class ListBoxBehavior : Behavior<ListBox>
{
    public static readonly DependencyProperty AddedItemsProperty =
        DependencyProperty.Register("AddedItems", typeof (List<object>), typeof (ListBoxBehavior), new PropertyMetadata(new List<object>()));

    public List<object> AddedItems
    {
        get { return (List<object>) GetValue(AddedItemsProperty); }
        set { SetValue(AddedItemsProperty, value); }
    }

    public static readonly DependencyProperty RemovedItemsProperty =
        DependencyProperty.Register("RemovedItems", typeof(List<object>), typeof(ListBoxBehavior), new PropertyMetadata(new List<object>));

    public List<object> RemovedItems
    {
        get { return (List<object>) GetValue(RemovedItemsProperty); }
        set { SetValue(RemovedItemsProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        var observableCollection = AssociatedObject.ItemsSource as ObservableCollection<object>;
        if (observableCollection != null)
        {
            observableCollection.CollectionChanged += ItemsSourceOnCollectionChanged;
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        var observableCollection = AssociatedObject.ItemsSource as ObservableCollection<object>;
        if (observableCollection != null)
        {
            observableCollection.CollectionChanged -= ItemsSourceOnCollectionChanged;
        }
    }

    private void ItemsSourceOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
    {
        AddedItems.Clear();
        RemovedItems.Clear();
        switch (notifyCollectionChangedEventArgs.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach (var newItem in notifyCollectionChangedEventArgs.NewItems)
                {
                    AddedItems.Add(newItem);
                }
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var newItem in notifyCollectionChangedEventArgs.NewItems)
                {
                    RemovedItems.Add(newItem);
                }
                break;
        }
    }
}
公共类ListBoxBehavior:Behavior
{
公共静态只读DependencyProperty AddedItemsProperty=
Register(“AddedItems”、typeof(List)、typeof(ListBoxBehavior)、newpropertyMetadata(new List());
公开名单增编
{
获取{return(List)GetValue(AddedItemsProperty);}
set{SetValue(AddedItemsProperty,value);}
}
公共静态只读从属属性RemovedItemsProperty=
DependencyProperty.Register(“RemovedItems”、typeof(List)、typeof(ListBoxBehavior)、new PropertyMetadata(new List));
公共列表删除的项目
{
获取{return(List)GetValue(RemovedItemsProperty);}
set{SetValue(RemovedItemsProperty,value);}
}
受保护的覆盖无效附加()
{
base.onatached();
var observableCollection=AssociatedObject.ItemsSource作为observableCollection;
如果(observableCollection!=null)
{
observableCollection.CollectionChanged+=ItemsSourceCollectionChanged;
}
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
var observableCollection=AssociatedObject.ItemsSource作为observableCollection;
如果(observableCollection!=null)
{
observableCollection.CollectionChanged-=ItemsSourceCollectionChanged;
}
}
私有无效项SourceCollectionChanged(对象发送方,NotifyCollectionChangedEventArgs NotifyCollectionChangedEventArgs)
{
AddedItems.Clear();
RemovedItems.Clear();
开关(notifyCollectionChangedEventArgs.Action)
{
案例NotifyCollectionChangedAction。添加:
foreach(notifyCollectionChangedEventArgs.NewItems中的var newItem)
{
添加项。添加(新项);
}
打破
案例NotifyCollectionChangedAction。删除:
foreach(notifyCollectionChangedEventArgs.NewItems中的var newItem)
{
RemovedItems.Add(新建项);
}
打破
}
}
}
XAML

    <ListBox>
        <i:Interaction.Behaviors>
            <ListBoxBehavior AddedItems="{Binding AddedItems}"/>
            <ListBoxBehavior AddedItems="{Binding RemovedItems}"/>
        </i:Interaction.Behaviors>
    </ListBox>


所发生的情况是,订阅的事件被封装在行为类中,您现在可以创建与类关联的依赖项属性的绑定,该类是
列表框

谢谢,我将尝试这个解决方案,我想实现的是,ExtendedListBox将并排绘制多个学生对象(即矩形对象)。所以,如果我们添加新的student对象,ExtendedListBox将通过计算最后一个矩形位置来查找新添加的矩形位置,并相应地绘制一个矩形。当我们从ObservaleCollection中删除student对象时,ExtendedListBox将相应地重新排列其他矩形的位置。在viewModel中,我不想设置矩形的位置,扩展类应该负责矩形的位置查找和重新排列。给定的示例应该可以工作,并为您需要的业务逻辑编写一点代码。:)我还有一个查询,在ExtendedListBox构造函数中,我定义了这个;this.MouseLeftButtonDown+=扩展列表框\u MouseLeftButtonDown;this.MouseLeftButtonUp+=扩展列表框\u MouseLeftButtonUp;当我点击这个项目时,我并没有得到MouseLeftButtonDown事件,而是在释放鼠标时得到MouseLeftButtonUp事件。我将使用OnSelectionChanged()事件代替MouseLeftButtonDown(),还有其他方法捕获MouseLeftButtonDown事件吗?当您释放鼠标时,拖放所需的事件。当你不释放鼠标按钮时,不要忘记将其标记为已回答(选中标记)。