datagridview控件继续更新,滚动窗口时gui闪烁



问题:我有一个Winform应用程序,在这个表单上有一个表单en。datagridview是从后端更新的,方法是连续更新绑定对象,并使用计时器每10秒获取一次数据。为了用这个新数据更新gui,我调用了RefreshDatabindings。(如果我不这样做,gui将不更新,我将绑定到BindingList,并且对象实现INotifyPropertyChanged)

当表单足够大,可以同时显示整个数据网格视图时,一切都很好。但是,当窗体不够大,无法显示孔数据网格视图时,会出现滚动条。

当我向右滚动查看数据网格视图的其余部分时,我看到gui在闪烁(只有滚动前不可见的部分)。当我拉伸表单以使网格视图再次适合时,一切都很好(没有闪烁和闪烁)只有当我必须滚动时才会出现闪烁

我迷路了,能请人帮帮我吗:)?

  • 我已经试过DoubleBuffered=true了

提前感谢!

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

我希望我能帮助你^^

最新更新