![](/img/trans.png)
[英]How do I prevent a copy of a grid's datasource from not getting changed when the grid's data changes?
[英]How do I prevent a DataGridView from autoscrolling when the datasource changes?
我在DataTable的“RowChanged”事件中嘗試了這個( http://brainof-dave.blogspot.com/2007/08/turning-off-auto-scrolling-in-bound.html ),該事件是數據源的DataGridView,但無濟於事。
基本上,我有一個帶有BindingSource的DataGridView,因為它是DataSource。 BindingSource的DataSource是一個包含DataTable的DataView。 每當其中一行中的數據發生變化時,DataGridView就會滾動回到頂部。 有一個簡單的解決方案嗎?
看起來我找到了它: http : //seewinapp.blogspot.com/2005/09/is-your-autoscroll-too-auto.html
我覆蓋了DataTable上的RowChanged事件,存儲了FirstDisplayedScrollingRowIndex,調用了以該索引作為參數的委托方法,然后將FirstDisplayedScrollingRowIndex重置為委托方法中的該參數。 事實證明,直到所有事件都被觸發后才會發生自動滾動,因此在事件中嘗試破解它是沒用的。 委托是有效的,因為它是在事件之后調用的。
這是經過測試的代碼,用於在更改數據源后恢復RowIndex。 這也會恢復排序順序和最后一個單元格位置。 語言:C#7.0。 這是我親自編寫的代碼,在網絡搜索的幫助下。
private void UpdateDataSource()
{
SuspendLayout();
//Save last position and sort order
DataGridView g = DataGridView1;
Int32 idxFirstDisplayedScrollingRow = g.FirstDisplayedScrollingRowIndex;
SortOrder dgvLastSortDirection = g.SortOrder;
Int32 lastSortColumnPos = g.SortedColumn?.Index ?? -1;
Int32 dgvLastCellRow = g.CurrentCell?.RowIndex ?? -1;
Int32 dgvLastCellColumn = g.CurrentCell?.ColumnIndex ?? -1;
//Set new datasource
g.DataSource = myNewDataTableSource;
//Restore sort order, scroll row, and active cell
g.InvokeIfRequired( o =>
{
if(lastSortColumnPos > -1)
{
DataGridViewColumn newColumn = o.Columns[lastSortColumnPos];
switch(dgvLastSortDirection)
{
case SortOrder.Ascending:
o.Sort(newColumn, ListSortDirection.Ascending);
break;
case SortOrder.Descending:
o.Sort(newColumn, ListSortDirection.Descending);
break;
case SortOrder.None:
//No sort
break;
}
}
if(idxFirstDisplayedScrollingRow >= 0)
o.FirstDisplayedScrollingRowIndex = idxFirstDisplayedScrollingRow;
if(dgvLastCellRow>-1 && dgvLastCellColumn>-1)
o.CurrentCell = g[dgvLastCellColumn, dgvLastCellRow];
} );
ResumeLayout();
}
public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action) where T : ISynchronizeInvoke
{
if (obj.InvokeRequired)
{
obj.Invoke(action, new Object[] { obj });
}
else
{
action(obj);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.