在BindingList的ItemChanging事件中获取已删除的项目 [英] Get Deleted Item in ItemChanging event of BindingList

查看:98
本文介绍了在BindingList的ItemChanging事件中获取已删除的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用绑定列表以及ItemChanged事件。



有什么方法可以知道ItemChanged事件中属性的先前值。目前,我正在添加一个名为 OldValue的单独属性来实现此目的。



是否可以通过任何方式了解项目更改事件中已删除项目的信息。我找不到任何方法可以知道已从列表中删除了哪个项目。

解决方案

如果我正确理解,您我想获得有关从绑定列表中删除的项目的信息。



我认为最简单的方法是创建自己的绑定列表,该绑定列表是从绑定列表中派生的。 / p>

在内部,您将覆盖RemoveItem方法,因此在从绑定列表中删除项目之前,您将能够触发包含将要删除的项目的事件。

 公共类myBindingList< myInt> :BindingList< myInt> 
{
受保护的重写void RemoveItem(int itemIndex)
{
// itemIndex =要删除的项目的索引
//从绑定列表中获取项目在itemIndex位置
myInt DeletedItem = this.Items [itemIndex];

if(BeforeRemove!= null)
{
//引发事件的项目将被删除
BeforeRemove(deletedItem);
}

//从列表
base中删除项目。RemoveItem(itemIndex);
}

公共代表void myIntDelegate(myInt DeletedItem);
个公共事件myIntDelegate BeforeRemove;
}

为了示例,我创建了实现INotifyPropertyChanged的myInt类型-接口只是为了在绑定列表中添加/删除元素后,使dataGridView刷新。

 公共类myInt:INotifyPropertyChanged 
{
public myInt(int myIntVal)
{
myIntProp = myIntVal;
}
private int iMyInt;
public int myIntProp {
get
{
return iMyInt;
}
set
{
iMyInt =值;
if(PropertyChanged!= null)
{
PropertyChanged(this,new PropertyChangedEventArgs( myIntProp));;
}
}
}

公共事件PropertyChangedEventHandler PropertyChanged;
}

我正在使用ints初始化绑定列表(准确地说是myInts),然后我将列表绑定到dataGridView(出于演示目的)并订阅我的BeforeRemove事件。

  bindingList = new myBindingList< myInt> (); 
bindingList.Add(new myInt(8));
bindingList.Add(new myInt(9));
bindingList.Add(new myInt(11));
bindingList.Add(new myInt(12));

dataGridView1.DataSource = bindingList;
bindingList.BeforeRemove + = bindingList_BeforeRemove;

如果引发了BeforeRemove事件,我有被删除的项目

  void bindingList_BeforeRemove(Form1.myInt DeletedItem)
{
MessageBox.Show(您刚刚删除了值为 + DeletedItem.myIntProp的项目。 ToString());
}

下面是完整的示例代码(在窗体上放置3个按钮和dataGridView)-按钮1初始化绑定列表,按钮2将项目添加到列表,按钮3从出价列表中删除项目







 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows.Forms;

命名空间绑定列表
{
公共局部类Form1:表单
{
myBindingList< myInt> bindingList;

公共Form1()
{
InitializeComponent();
}

private void button1_Click(对象发送者,EventArgs e)
{
bindingList = new myBindingList< myInt>();
bindingList.Add(new myInt(8));
bindingList.Add(new myInt(9));
bindingList.Add(new myInt(11));
bindingList.Add(new myInt(12));

dataGridView1.DataSource = bindingList;
bindingList.BeforeRemove + = bindingList_BeforeRemove;
}

void bindingList_BeforeRemove(Form1.myInt DeletedItem)
{
MessageBox.Show(您刚刚删除了值为 + DeletedItem.myIntProp.ToString ());
}


private void button2_Click(对象发送者,EventArgs e)
{
bindingList.Add(new myInt(13));
}

private void button3_Click(对象发送者,EventArgs e)
{
bindingList.RemoveAt(dataGridView1.SelectedRows [0] .Index);
}

public class myInt:INotifyPropertyChanged
{
public myInt(int myIntVal)
{
myIntProp = myIntVal;
}
private int iMyInt;
public int myIntProp {
get
{
return iMyInt;
}
set
{
iMyInt =值;
if(PropertyChanged!= null)
{
PropertyChanged(this,new PropertyChangedEventArgs( myIntProp));;
}
}
}

公共事件PropertyChangedEventHandler PropertyChanged;
}

公共类myBindingList< myInt> :BindingList< myInt>
{
受保护的重写void RemoveItem(int itemIndex)
{
myInt DeletedItem = this.Items [itemIndex];

if(BeforeRemove!= null)
{
BeforeRemove(deletedItem);
}

base.RemoveItem(itemIndex);
}

公共代表void myIntDelegate(myInt DeletedItem);
个公共事件myIntDelegate BeforeRemove;
}
}
}






需要评论的人



问题的另一部分是=>有什么办法可以知道列表中更改的项目的旧值?在ListChangedEvent中不共享任何内容



要查看项目的旧值,您可以覆盖SetItem方法

 受保护的覆盖无效SetItem(int index,myInt item)
{
//这里还是旧的索引
的值myInt oldMyInt = this.Items [index];
//新值
myInt newMyInt = item;

if(myIntOldNew!= null)
{
//引发事件
myIntOldNew(oldMyInt,newMyInt);
}

//在索引位置更新项目
base.SetItem(index,item);
}

当指定索引处的对象发生更改时会触发,

  bindingList [dataGridView1.SelectedRows [0] .Index] = new myInt(new Random()。Next()); 

棘手的部分是,如果您尝试直接修改项目的属性

  bindingList [dataGridView1.SelectedRows [0] .Index] .myIntProp = new Random()。Next(); 

SetItem 不会触发,它必须是整个对象的替换。



所以我们需要另一个代表&处理此事件的事件

 公共委托void myIntDelegateChanged(myInt oldItem,myInt newItem); 
个公共事件myIntDelegateChanged myIntOldNew;

然后我们可以订阅此

  bindingList.myIntOldNew + = bindingList_myIntOldNew; 

并处理

  void bindingList_myIntOldNew(Form1.myInt oldItem,Form1.myInt newItem)
{
MessageBox.Show(您刚刚更改了值为 + oldItem.myIntProp.ToString()的项目+到 + newItem.myIntProp.ToString());
}




更新的代码(需要4个按钮,4个-th修改所选项目)

使用系统

 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows.Forms;

命名空间绑定列表
{
公共局部类Form1:表单
{
myBindingList< myInt> bindingList;

公共Form1()
{
InitializeComponent();
}

private void button1_Click(对象发送者,EventArgs e)
{
bindingList = new myBindingList< myInt>();
bindingList.Add(new myInt(8));
bindingList.Add(new myInt(9));
bindingList.Add(new myInt(11));
bindingList.Add(new myInt(12));

dataGridView1.DataSource = bindingList;
bindingList.BeforeRemove + = bindingList_BeforeRemove;
bindingList.myIntOldNew + = bindingList_myIntOldNew;
}

void bindingList_myIntOldNew(Form1.myInt oldItem,Form1.myInt newItem)
{
MessageBox.Show(您刚刚更改了值为 + oldItem.myIntProp.ToString()+到 + newItem.myIntProp.ToString());
}



void bindingList_BeforeRemove(Form1.myInt DeletedItem)
{
MessageBox.Show(您刚刚删除了带有值 + DeletedItem.myIntProp.ToString());
}


private void button2_Click(对象发送者,EventArgs e)
{
bindingList.Add(new myInt(13));
}

private void button3_Click(对象发送者,EventArgs e)
{
bindingList.RemoveAt(dataGridView1.SelectedRows [0] .Index);
}

public class myInt:INotifyPropertyChanged
{
public myInt(int myIntVal)
{
myIntProp = myIntVal;
}
private int iMyInt;
public int myIntProp {
get
{
return iMyInt;
}
set
{
iMyInt =值;
if(PropertyChanged!= null)
{
PropertyChanged(this,new PropertyChangedEventArgs( myIntProp));;
}
}
}
公共事件PropertyChangedEventHandler PropertyChanged;
}

公共类myBindingList< myInt> :BindingList< myInt>
{
受保护的覆盖无效SetItem(int索引,myInt项目)
{
myInt oldMyInt = this.Items [index];
myInt newMyInt =项目;

if(myIntOldNew!= null)
{
myIntOldNew(oldMyInt,newMyInt);
}

base.SetItem(index,item);
}

受保护的重写void RemoveItem(int itemIndex)
{
myInt DeletedItem = this.Items [itemIndex];

if(BeforeRemove!= null)
{
BeforeRemove(deletedItem);
}

base.RemoveItem(itemIndex);
}

公共代表void myIntDelegateChanged(myInt oldItem,myInt newItem);
个公共事件myIntDelegateChanged myIntOldNew;

公共代表void myIntDelegate(myInt DeletedItem);
个公共事件myIntDelegate BeforeRemove;


}

私有无效按钮4_Click(对象发送者,EventArgs e)
{
bindingList [dataGridView1.SelectedRows [0] .Index ] = new myInt(new Random()。Next());
}
}
}


I am using Binding List in my application along with ItemChanged event.

Is there any way I could know the previous values of properties in ItemChanged event. Currently I am adding a separate property named 'OldValue' to achieve this.

Is there any way to know about the deleted item in item changed event. I am not able to find any way to know which item has been deleted from the list.

解决方案

If I understand correctly, you want to get info about item which was deleted from binding list.

I think the easiest way to do this will be creating your own binding list which derives from binding list.

Inside you'll have RemoveItem method overriden, so BEFORE removing item from binding list, you'll be able to fire event containing item which is going to be removed.

public class myBindingList<myInt> : BindingList<myInt>
{
        protected override void RemoveItem(int itemIndex)
        {
            //itemIndex = index of item which is going to be removed
            //get item from binding list at itemIndex position
            myInt deletedItem = this.Items[itemIndex];

            if (BeforeRemove != null)
            {
                //raise event containing item which is going to be removed
                BeforeRemove(deletedItem);
            }

            //remove item from list
            base.RemoveItem(itemIndex);
        }

        public delegate void myIntDelegate(myInt deletedItem);
        public event myIntDelegate BeforeRemove;
    }

For the sake of example I created type myInt implementing INotifyPropertyChanged - interface is just to make dataGridView refresh after adding/deleting elements from binding list.

public class myInt : INotifyPropertyChanged
    {
        public myInt(int myIntVal)
        {
            myIntProp = myIntVal;
        }
        private int iMyInt;
        public int myIntProp {
            get
            {
                return iMyInt;
            }
            set
            {
                iMyInt = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("myIntProp"));
                }
            } 
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

I'm initializing binding list with ints (myInts to be precise), then I'm binding list to dataGridView (for presentation purpose) and subscribing to my BeforeRemove event.

bindingList = new myBindingList<myInt>();
        bindingList.Add(new myInt(8));
        bindingList.Add(new myInt(9));
        bindingList.Add(new myInt(11));
        bindingList.Add(new myInt(12));

        dataGridView1.DataSource = bindingList;
        bindingList.BeforeRemove += bindingList_BeforeRemove;

If BeforeRemove event was raised I have item which was deleted

 void bindingList_BeforeRemove(Form1.myInt deletedItem)
    {
        MessageBox.Show("You've just deleted item with value " + deletedItem.myIntProp.ToString());
    }

Below is whole example code (drop 3 buttons and dataGridView on form) - button 1 initializes binding list, button 2 adds item to list, button 3 removes item from biding list

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace bindinglist
{
public partial class Form1 : Form
{
    myBindingList<myInt> bindingList;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bindingList = new myBindingList<myInt>();
        bindingList.Add(new myInt(8));
        bindingList.Add(new myInt(9));
        bindingList.Add(new myInt(11));
        bindingList.Add(new myInt(12));

        dataGridView1.DataSource = bindingList;
        bindingList.BeforeRemove += bindingList_BeforeRemove;
    }

    void bindingList_BeforeRemove(Form1.myInt deletedItem)
    {
        MessageBox.Show("You've just deleted item with value " + deletedItem.myIntProp.ToString());
    }


    private void button2_Click(object sender, EventArgs e)
    {
        bindingList.Add(new myInt(13));
    }

    private void button3_Click(object sender, EventArgs e)
    {
        bindingList.RemoveAt(dataGridView1.SelectedRows[0].Index);
    }

    public class myInt : INotifyPropertyChanged
    {
        public myInt(int myIntVal)
        {
            myIntProp = myIntVal;
        }
        private int iMyInt;
        public int myIntProp {
            get
            {
                return iMyInt;
            }
            set
            {
                iMyInt = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("myIntProp"));
                }
            } 
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class myBindingList<myInt> : BindingList<myInt>
    {
        protected override void RemoveItem(int itemIndex)
        {
            myInt deletedItem = this.Items[itemIndex];

            if (BeforeRemove != null)
            {
                BeforeRemove(deletedItem);
            }

            base.RemoveItem(itemIndex);
        }

        public delegate void myIntDelegate(myInt deletedItem);
        public event myIntDelegate BeforeRemove;
    }
}
}


ASNWER TO COMMENT

"The other part of the question is => Is there any way to know the old value of the item which is changed in the list? In ListChangedEvent does not share anything"

To see old value of item you can override SetItem method

protected override void SetItem(int index, myInt item)
        {
            //here we still have old value at index
            myInt oldMyInt = this.Items[index];
            //new value
            myInt newMyInt = item;

            if (myIntOldNew != null)
            {
                //raise event
                myIntOldNew(oldMyInt, newMyInt);
            }

            //update item at index position
            base.SetItem(index, item);
        }

It fires when object at specified index is changed, like this

bindingList[dataGridView1.SelectedRows[0].Index] = new myInt(new Random().Next());

The tricky part is, if you try to modify item's property directly

bindingList[dataGridView1.SelectedRows[0].Index].myIntProp = new Random().Next();

SetItem won't fire, it has to be a whole object replaced.

So we will need another delegate & event to handle this

public delegate void myIntDelegateChanged(myInt oldItem, myInt newItem);
public event myIntDelegateChanged myIntOldNew;

Then we can subscribe to this

bindingList.myIntOldNew += bindingList_myIntOldNew;

and handle it

void bindingList_myIntOldNew(Form1.myInt oldItem, Form1.myInt newItem)
{
    MessageBox.Show("You've just CHANGED item with value " + oldItem.myIntProp.ToString() + " to " + newItem.myIntProp.ToString());
}

Updated code (4 buttons required, 4-th modifies selected item)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace bindinglist
{
public partial class Form1 : Form
{
    myBindingList<myInt> bindingList;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bindingList = new myBindingList<myInt>();
        bindingList.Add(new myInt(8));
        bindingList.Add(new myInt(9));
        bindingList.Add(new myInt(11));
        bindingList.Add(new myInt(12));

        dataGridView1.DataSource = bindingList;
        bindingList.BeforeRemove += bindingList_BeforeRemove;
        bindingList.myIntOldNew += bindingList_myIntOldNew;
    }

    void bindingList_myIntOldNew(Form1.myInt oldItem, Form1.myInt newItem)
    {
        MessageBox.Show("You've just CHANGED item with value " + oldItem.myIntProp.ToString() + " to " + newItem.myIntProp.ToString());
    }



    void bindingList_BeforeRemove(Form1.myInt deletedItem)
    {
        MessageBox.Show("You've just deleted item with value " + deletedItem.myIntProp.ToString());
    }


    private void button2_Click(object sender, EventArgs e)
    {
        bindingList.Add(new myInt(13));
    }

    private void button3_Click(object sender, EventArgs e)
    {
        bindingList.RemoveAt(dataGridView1.SelectedRows[0].Index);
    }

    public class myInt : INotifyPropertyChanged
    {
        public myInt(int myIntVal)
        {
            myIntProp = myIntVal;
        }
        private int iMyInt;
        public int myIntProp {
            get
            {
                return iMyInt;
            }
            set
            {
                iMyInt = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("myIntProp"));
                }
            } 
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class myBindingList<myInt> : BindingList<myInt>
    {
        protected override void SetItem(int index, myInt item)
        {
            myInt oldMyInt = this.Items[index];
            myInt newMyInt = item;

            if (myIntOldNew != null)
            {
                myIntOldNew(oldMyInt, newMyInt);
            }

            base.SetItem(index, item);
        }

        protected override void RemoveItem(int itemIndex)
        {
            myInt deletedItem = this.Items[itemIndex];

            if (BeforeRemove != null)
            {
                BeforeRemove(deletedItem);
            }

            base.RemoveItem(itemIndex);
        }

        public delegate void myIntDelegateChanged(myInt oldItem, myInt newItem);
        public event myIntDelegateChanged myIntOldNew;

        public delegate void myIntDelegate(myInt deletedItem);
        public event myIntDelegate BeforeRemove;


    }

    private void button4_Click(object sender, EventArgs e)
    {
        bindingList[dataGridView1.SelectedRows[0].Index] = new myInt(new Random().Next());
    }
}
}

这篇关于在BindingList的ItemChanging事件中获取已删除的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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