绑定的DataGridView不更新以显示信息+排序问题 [英] Bound DataGridView not updating to display information + sorting issues

查看:89
本文介绍了绑定的DataGridView不更新以显示信息+排序问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定的DataGridView1以及几个绑定的TextBoxes和DateTimePickers。



一切正常,除非我尝试同时完成这两件事:


  1. 按特定列(日期)对DataGridView1进行排序。

  2. 基于DateTimePicker更改同一列日期



这样的想法是,我像这样对DataGridView1进行排序(我在Form Load中设置了此值) :

  DataGridView1.Sort(DataGridView1.Columns(45),ListSortDirection.Ascending)

(第45列只是我的 MyDateColumn列)



然后,当我这样更改日期列:

  DirectCast(MyBindingSource.Current,DataRowView).Item( MyDateColumn)= MyDateTimePicker。 Value.AddDays(100)

DataGridView1应该自动并立即按日期排序。





好的,这就是问题所在。排序有效-但由于某种原因,我的DataGridView拒绝反映DirectCast设置的日期直到我选择另一行。当我选择另一行- then 时,它会更改以反映我刚刚发送的日期。


我尝试了所有可能想到的-终于找到了解决方案:

  Me.BindingContext(MyBindingSource).EndCurrentEdit()



很棒-但只有在我不使用的情况下:

  DataGridView1.Sort(DataGridView1.Columns(45),ListSortDirection.Ascending)

如果我对DataGridView进行排序,则绑定似乎只是...在我结束后停止工作。 。如果我注释掉ListSortDirection.Ascending行,那么它将很好用!



我尝试使用DataGridView1.Refresh()代替.EndCurrentEdit(),但是它是异常缓慢-我宁愿完全避免使用它。



有人有什么建议吗?

解决方案

由于可以对BindingSource数据源进行排序,因此请使用


I have a bound DataGridView1 and several bound TextBoxes and DateTimePickers.

Everything is working well, except when I try to accomplish these two things in conjunction:

  1. Sort the DataGridView1 by a specific column (date).
  2. Change that same column date based on a DateTimePicker.


The idea is that I am sorting my DataGridView1 like so (I set this in Form Load):

DataGridView1.Sort(DataGridView1.Columns(45), ListSortDirection.Ascending)

(Column 45 is just my "MyDateColumn" column)

And later on, when I change my date column like so:

DirectCast(MyBindingSource.Current, DataRowView).Item("MyDateColumn") = MyDateTimePicker.Value.AddDays(100)

The DataGridView1 should automatically and immediately sort by the date.


Okay, so here's where the issue is. The sorting works - but for some reason my DataGridView refuses to reflect the date set by the DirectCast until I select another row. When I select another row - then it changes to reflect the date I just sent.
I've tried everything I could think of - and I finally found a solution:

Me.BindingContext(MyBindingSource).EndCurrentEdit()


This works great - but only if I am not using:

DataGridView1.Sort(DataGridView1.Columns(45), ListSortDirection.Ascending)

If I'm sorting my DataGridView, my binding seems to just...stop working after I .EndCurrentEdit. If I comment out that ListSortDirection.Ascending line, then it works great!

I tried to use DataGridView1.Refresh() in lieu of .EndCurrentEdit(), but it is exceptionally slow - I would rather avoid using that altogether.

Does anyone have any advice?

解决方案

Since the BindingSource data source can be sorted, use the BindingSource.Sort property instead of sorting the control (your DataGridView). columnName is the name of the Column used for sorting (you can specify more than one Column):

myBindingSource.Sort = $"{columnName} ASC"

Then, when the User sets the DateTimePicker.Value, update the Cell value, corresponding to DateTime Column of the current Row, using the ValueChanged event:

Method 1: Bound DateTimePicker

In the DateTimePicker.ValueChanged, the BindingSource.EndEdit() method is called, to apply immediately the new value to the data source.

Note 1: for this method to work as expected, the BindingSource data source must be a DataTable or another container that implements the IEditableObject interface.

DateTimePicker1.DataBindings.Add(
    New Binding("Value", myBindingSource, "MyDateTimeColumn", False, DataSourceUpdateMode.OnValidation))

'(...)

Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    myBindingSource.EndEdit()
End Sub

Note 2: the DateTimePicker doesn't support a null/DbNull value. If the DataSouce may contain DBNull values, it may become erratic. You'll probably need to create a custom control from it, to manage its behavior. Otherwise, see Method 2

Method 2: UnBound DateTimePicker

The userSetValue field is used when setting the DateTimePicker value in code, to prevent the procedure in the ValueChanged event to update the DateTime Columns's Value. This way, the event will only update the Column when a User changes the date manually.

Private columnName As String = String.Empty
Private userSetValue As Boolean = True

Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
    If (Not userSetValue) Then Return
    If (DataGridView1.CurrentRow Is Nothing) OrElse
        (DataGridView1.CurrentRow.Cells($"{columnName}").ValueType IsNot GetType(Date)) Then Return

    'DataGridView1.SuspendLayout()
    DataGridView1.CurrentRow.Cells($"{columnName}").Value = DateTimePicker1.Value
    myBindingSource.EndEdit()
    'DataGridView1.ResumeLayout(False)
End Sub

► Test both methods with and without SuspendLayout() / ResumeLayout().

The RowPostPaint event (for example) can be used to update the DateTimePicker.Value the associated Columns' value:

Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
    userSetValue = False
    Dim currentValue = DataGridView1.CurrentRow.Cells("MyDateTimeColumn").Value
    If currentValue Is Nothing OrElse currentValue Is DBNull.Value Then currentValue = Date.Now
    DateTimePicker1.Value = DirectCast(currentValue, Date)
    userSetValue = True
End Sub

Using any of the two methods, this is the result:

这篇关于绑定的DataGridView不更新以显示信息+排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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