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

时间:2016-06-15 12:27:13

标签: c# checkbox datagridview inotifypropertychanged bindingsource

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

问题是:当我点击CheckBox时,CheckBox会立即明显更改,但invitation_property_changed()方法不会被调用,直到我点击其他某个单元格为止。我需要在事件发生时立即获得等效的Checkbox.Checked事件,以便我可以在UI中更新另一个控件。 (如果我更改了OTHERS单元格,那么用户点击 Enter 会触发PropertyChanged事件是很自然的 - 所以这个对用户来说很自然。 )

这是一个截图,fwiw:

example filled DataGridView

这是我的玩具代码:

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());
            }
        }
    }
}

感谢您的考虑。

1 个答案:

答案 0 :(得分:1)

我在此类情况下发现的最简单的解决方案是处理DataGridView.CellContentClickDataGridView.CellContentDoubleClick事件。您可以保留所有当前的代码。您需要添加的所有内容都是这两个事件的单个句柄,当它是CheckBox单元格时,它会结束单元格编辑。结束编辑将触发值更改与离开单元格当前的值相同。

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();
    }
}

过早结束单元格的编辑可能会有问题 - 例如,如果它是TextBox单元格 - 由于验证。但由于它只是TrueFalse,因此在这种情况下,这一点没有实际意义。