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

时间:2014-04-11 07:27:44

标签: winforms data-binding datagridview scroll refresh

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

当表单足够大以显示整个datagridview时,一切正常。但是当表单不足以显示空洞数据视图时,会出现一个滚动条。

当我向右滚动以查看datagridview的其余部分时,我看到gui闪烁(只有在滚动之前看不到的部分)。当我拉伸表格以使de gridview再次适合时,一切都正常工作(没有闪烁和闪烁)。 闪烁只发生在我必须滚动时。

我迷路了,可以请有人帮助我:)?

  • 我已经尝试过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();
    }

1 个答案:

答案 0 :(得分:1)

所以这是我的解决方案:

您只使用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);

我希望我能帮到你^^