DataGridView – 同时输入和输出 – 这是DataGridView中的错误

我已经创建了一个C#Windows窗体应用程序,我试图尽可能简单地演示我遇到的问题。 我正在尝试使用DataGridView允许用户在一列中输入,同时从后台线程获取另一列中的更新。

问题是输入列实际上是不可编辑的,因为 – 我认为 – 用于输出列的更新会导致输入列在用户尝试更改时使用其当前值进行更新。

这是DataGridView中的错误吗? 有没有更好的方法来做这种事情? 谁能推荐一个好的解决方法?

以下代码演示了此问题。 “输出”列将不断更新,“输入”列几乎不可编辑。 我已将设计器代码(Form1.designer.cs)和Main(来自Program.cs)合并到表单代码(Form1.cs)中 – 因此以下代码应该自行运行。

using System; using System.ComponentModel; using System.Windows.Forms; using System.Timers; public partial class Form1 : Form { private System.ComponentModel.IContainer components = null; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  private void InitializeComponent() { this.dataGridView = new System.Windows.Forms.DataGridView(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); // // dataGridView // this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dataGridView.Location = new System.Drawing.Point(3, 12); this.dataGridView.Name = "dataGridView"; this.dataGridView.RowTemplate.Height = 24; this.dataGridView.Size = new System.Drawing.Size(322, 158); this.dataGridView.TabIndex = 0; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(328, 174); this.Controls.Add(this.dataGridView); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.DataGridView dataGridView; public Form1() { InitializeComponent(); } BindingSource bindingSource = new BindingSource(); BindingList items = new BindingList(); private System.Timers.Timer timer; private void Form1_Load(object sender, EventArgs e) { dataGridView.DataSource = bindingSource; bindingSource.DataSource = items; items.Add(new Item(dataGridView)); timer = new System.Timers.Timer {Interval = 50}; timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } private Random random = new Random(); void timer_Elapsed(object sender, ElapsedEventArgs e) { items[0].SetOutput(random.Next(100)); } } class Item : INotifyPropertyChanged { public int Input { get; set; } private int output; public int Output { get { return output; } private set { output = value; OnPropertyChanged("Output"); } } public Control control; public Item(Control control) { this.control = control; } public void SetOutput(int outputValue) { Output = outputValue; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { if(!control.IsDisposed) control.BeginInvoke(handler, this, new PropertyChangedEventArgs(name)); } } } static class Program { ///  /// The main entry point for the application. ///  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } 

我怀疑当一个PropertyChanged事件发生时, DataGridView刷新所有单元格,或者可能只刷新行中更改的单元格(当你编辑另一行时会发生什么?),丢失所有未经修改的更改。

如果您可以在DataGridView刷新单元格之前拦截事件,则可以保存未提交的更改以在刷新后恢复它们。 但这将是一个丑陋的解决方法……

你有没有在MSDN论坛上提问? 也许MS的某个人可以给你一个更有用的答案

也许被编辑的细胞正在失去焦点? 也许每次更新另一列时,存储您正在编辑的位置,并在更新后重置焦点?

尝试更新列不在50毫秒,但在像intervale等于4000的东西,它的工作可以改变另一列中的值,仍然可以在另一列上更改