簡體   English   中英

datagridview控件繼續更新,滾動窗口時gui閃爍

[英]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時,一切都將正常工作(沒有閃爍)。 僅當我必須滾動時才發生閃爍。

我迷路了,請有人幫助我:)?

  • 我已經嘗試過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);

我希望我能幫助你^^

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM