c#winforms:如何使用bindingsource捕获DGV中的checkbox.checked事件?

c#winforms:如何使用bindingsource捕获DGV中的checkbox.checked事件?,c#,checkbox,datagridview,inotifypropertychanged,bindingsource,C#,Checkbox,Datagridview,Inotifypropertychanged,Bindingsource,下面是一个玩具程序来说明我在实际应用中遇到的问题。它是一个DataGridView,具有类对象列表的BindingSource 问题是:当我单击一个复选框时,复选框会立即发生可见的更改,但是在我单击其他单元格之前,不会调用invitation\u property\u changed()方法。我需要获得与复选框等价的内容。一旦事件发生,我就会选中它,这样我就可以更新UI中的另一个控件。(如果我更改了一个OTHERS单元格,用户自然会按Enter键触发PropertyChanged事件,因此这对用

下面是一个玩具程序来说明我在实际应用中遇到的问题。它是一个
DataGridView
,具有类对象列表的
BindingSource

问题是:当我单击一个
复选框时,
复选框
会立即发生可见的更改,但是在我单击其他单元格之前,不会调用
invitation\u property\u changed()
方法。我需要获得与
复选框等价的内容。一旦事件发生,我就会选中它,这样我就可以更新UI中的另一个控件。(如果我更改了一个
OTHERS
单元格,用户自然会按Enter键触发
PropertyChanged
事件,因此这对用户来说是自然的。)

这是一个截图,fwiw:

这是我的玩具代码:

namespace dgv_binding_test {
    public partial class Form1 : Form {

        BindingSource bindingsource_invitations = new BindingSource();

        class an_invitation : INotifyPropertyChanged {

            static int lastID = 0;

            int _id;
            string _name;
            bool _rsvp;
            int _others;

            public int id() {
                return _id;
            }

            public string NAME {
                get { return _name; }
                set {
                    _name = value;
                    NotifyPropertyChanged("NAME");
                }
            }

            public bool RSVP {
                get { return _rsvp; }
                set {
                    _rsvp = value;
                    NotifyPropertyChanged("RSVP");
                }
            }

            public int OTHERS {
                get { return _others; }
                set {
                    _others = value;
                    NotifyPropertyChanged("OTHERS");
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

            public an_invitation(string a_name, bool a_rsvp, int others) {
                _id = lastID++;
                _name = a_name;
                _rsvp = a_rsvp;
                _others = others;
            }

            private void NotifyPropertyChanged(String propertyName = "") {
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        List<an_invitation> invitations = new List<an_invitation>();

        public Form1() {
            InitializeComponent();

            an_invitation ai = new an_invitation("harry", true, 3);
            ai.PropertyChanged += new PropertyChangedEventHandler(invitation_property_changed);
            invitations.Add(ai);

            ai = new an_invitation("heidi", false, 0);
            ai.PropertyChanged += new PropertyChangedEventHandler(invitation_property_changed);
            invitations.Add(ai);

            ai = new an_invitation("henry", false, 0);
            ai.PropertyChanged += new PropertyChangedEventHandler(invitation_property_changed);
            invitations.Add(ai);

            ai = new an_invitation("hazel", true, 0);
            ai.PropertyChanged += new PropertyChangedEventHandler(invitation_property_changed);
            invitations.Add(ai);

            BindingList<an_invitation> bindingList = new BindingList<an_invitation>(invitations);
            bindingsource_invitations = new BindingSource(bindingList, null);

            dataGridView1.DataSource = bindingsource_invitations;
            dataGridView1.AutoGenerateColumns = true;
        }

        private void invitation_property_changed(object sender, PropertyChangedEventArgs e) {
            Debug.Write("change for id: " + ((an_invitation)sender).id() + "  property: " + e.PropertyName + " change: " + ((an_invitation)sender).NAME + " to: ");

            if (e.PropertyName == "NAME") {
                Debug.WriteLine(((an_invitation)sender).NAME);
            } else if (e.PropertyName == "RSVP") {
                Debug.WriteLine(((an_invitation)sender).RSVP.ToString());
            } else if (e.PropertyName == "OTHERS") {
                Debug.WriteLine(((an_invitation)sender).OTHERS.ToString());
            }
        }
    }
}
名称空间dgv_绑定_测试{
公共部分类Form1:Form{
BindingSource BindingSource_邀请=新建BindingSource();
课堂邀请:INotifyPropertyChanged{
静态int lastID=0;
内部id;
字符串\u名称;
布尔(bool)rsvp,;
国际其他组织;
公共int id(){
返回_id;
}
公共字符串名{
获取{return\u name;}
设置{
_名称=值;
NotifyPropertyChanged(“名称”);
}
}
公共图书馆{
获取{return\u rsvp;}
设置{
_rsvp=值;
通知财产变更(“RSVP”);
}
}
公共int其他{
获取{return\u others;}
设置{
_其他=价值;
通知财产变更(“其他”);
}
}
公共事件属性更改事件处理程序属性更改;
公开邀请(字符串a_名称、bool a_rsvp、int其他){
_id=lastID++;
_名称=一个名称;
_rsvp=a_rsvp;
_其他人=其他人;
}
私有void NotifyPropertyChanged(字符串propertyName=“”){
if(PropertyChanged!=null){
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
列表邀请=新列表();
公共表格1(){
初始化组件();
邀请ai=新的邀请(“harry”,真,3);
ai.PropertyChanged+=新的PropertyChangedEventHandler(邀请\属性\更改);
添加(ai);
ai=新的邀请(“heidi”,false,0);
ai.PropertyChanged+=新的PropertyChangedEventHandler(邀请\属性\更改);
添加(ai);
ai=新的邀请(“亨利”,假,0);
ai.PropertyChanged+=新的PropertyChangedEventHandler(邀请\属性\更改);
添加(ai);
ai=新的邀请(“榛子”,真,0);
ai.PropertyChanged+=新的PropertyChangedEventHandler(邀请\属性\更改);
添加(ai);
BindingList BindingList=新的BindingList(邀请);
bindingsource\u邀请=新的bindingsource(bindingList,null);
dataGridView1.DataSource=bindingsource\u邀请;
dataGridView1.AutoGenerateColumns=true;
}
私有无效邀请\u属性\u已更改(对象发送方,PropertyChangedEventArgs e){
Debug.Write(“更改id:”+((邀请)发件人).id()+“属性:”+e.PropertyName+“更改:”+((邀请)发件人).NAME+“更改为:”;
如果(例如,PropertyName==“名称”){
Debug.WriteLine(((邀请)发送方).NAME);
}否则如果(如PropertyName==“RSVP”){
Debug.WriteLine(((一个邀请)发送方.RSVP.ToString());
}else if(如PropertyName==“其他”){
Debug.WriteLine(((一个邀请)发送方).OTHERS.ToString());
}
}
}
}

感谢您的考虑。

对于这种情况,我发现最简单的解决方案是处理
DataGridView.CellContentClick
DataGridView.CellContentDoubleClick
事件。您可以保留所有当前代码。您只需要为这两个事件添加一个句柄,当它是一个
复选框时,将结束单元格编辑。结束编辑将触发与当前离开单元格相同的值更改

this.dataGridView1.CellContentClick += DataGridView1_CellContentClick;
this.dataGridView1.CellContentDoubleClick += DataGridView1_CellContentClick;

private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (this.dataGridView1[e.ColumnIndex, e.RowIndex] is DataGridViewCheckBoxCell)
    {
        this.dataGridView1.EndEdit();
    }
}
由于验证,过早结束单元格的编辑可能会有问题,例如,如果它是
文本框
单元格。但由于它只是
真的
假的
,在这种情况下,这一点是没有意义的