问题描述
我有一个绑定的DataGridView1以及几个绑定的TextBoxes和DateTimePickers。
一切正常,除非我尝试同时完成这两件事:
- 按特定列(日期)对DataGridView1进行排序。
- 基于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:
- Sort the DataGridView1 by a specific column (date).
- 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.
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
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不更新以显示信息+排序问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!