[英]datagridview control continues update, gui flickers when scrolling window
問題:我有一個Winform應用程序,該表單上有一個表單en,我有一個數據綁定的DataGridView。 通過使用計時器連續更新綁定對象來從后端更新datagridview,以每10秒獲取一次數據。 為了使用此新數據更新gui,我調用RefreshDatabindings。 (如果我不這樣做,則gui將被更新,我將綁定到BindingList,並且該對象將實現INotifyPropertyChanged)
當表單大到足以立即顯示整個datagridview時,一切都會正常進行。 但是,當窗體的大小不足以顯示hole datagridview時,將出現一個滾動條。
當我向右滾動以查看其余的datagridview時,我看到gui閃爍(僅滾動前不可見的部分)。 當我再次拉伸表格以使其適合de gridview時,一切都將正常工作(沒有閃爍)。 僅當我必須滾動時才發生閃爍。
我迷路了,請有人幫助我:)?
提前致謝!
BindingList<InstanceTableViewModel> viewModelList;
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
functionParamList = new List<FunctionParameter>();
functionParamList.Add(new FunctionParameter { DeviceValue = 100, InstanceId = "1", Name = "A" });
functionParamList.Add(new FunctionParameter { DeviceValue = 200, InstanceId = "2", Name = "B" });
functionParamList.Add(new FunctionParameter { DeviceValue = 300, InstanceId = "3", Name = "C" });
viewModelList = CreateInstanceTableViewModelList();
dataGridView1.DataSource = viewModelList;
//Create timer
updateDataTimer = new System.Timers.Timer();
updateDataTimer.Interval = 500;
updateDataTimer.Elapsed += updateDataTimer_Elapsed;
updateDataTimer.Start();
}
private void updateDataTimer_Elapsed(object sender, ElapsedEventArgs e)
{
ThreadPool.QueueUserWorkItem(ReadDataThreadPoolMethod);
}
private void ReadDataThreadPoolMethod(object state)
{
Random random = new Random();
int randomNumber = random.Next(0, 100);
foreach (FunctionParameter param in functionParamList)
{
param.DeviceValue = Convert.ToInt64(randomNumber);
}
}
void functionParameter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var functionParameter = sender as FunctionParameter;
var propertyName = e.PropertyName;
var propertyValue = functionParameter.DeviceValue;
var parameterName = functionParameter.Name;
UpdateViewModel(functionParameter.InstanceId, propertyName, propertyValue, parameterName);
}
private void UpdateViewModel(string instanceId, string propertyName, long propertyValue, string parameterName)
{
var instanceViewModel = viewModelList.Single(x => x.InstanceId == instanceId && x.NameLabel == parameterName);
if (instanceViewModel != null)
{
instanceViewModel.ValueHex = Convert.ToUInt16(propertyValue);
}
ResetBindingsSource();
}
delegate void UpdateBindingsInvoker();
public void ResetBindingsSource()
{
if (!this.IsDisposed)
{
if (this.InvokeRequired)
{
this.Invoke(new UpdateBindingsInvoker(UpdateDataGrid));
}
else
{
UpdateDataGrid();
}
}
}
private void UpdateDataGrid()
{
dataGridView1.Refresh();
}
所以這是我的解決方案:
您僅使用Forms DoubleBuffering,但是以下代碼是DataGridview的擴展方法,並且可以成功運行(在我的測試中;)
public static void DoubleBuffered(this DataGridView dgv, bool setting)
{
Type dgvType = dgv.GetType();
PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(dgv, setting, null);
}
我在Codeprojct上找到了此代碼。
您可以通過以下方式使用它:
YourDataGridView.DoubleBuffered(true);
我希望我能幫助你^^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.