He creado una aplicación C# Windows Forms que he intentado hacer lo más simple posible para demostrar un problema que me estoy encontrando. Intento utilizar un DataGridView para permitir la entrada del usuario en una columna y al mismo tiempo obtener actualizaciones en otra columna de una cadena de fondo.DataGridView - Entrada y salida simultáneas - ¿Esto es un error en DataGridView
El problema es que la columna Entrada no se puede editar porque, creo, las actualizaciones destinadas a la columna Salida hacen que la columna Entrada se actualice con su valor actual mientras el usuario intenta cambiar eso.
¿Este es un error en DataGridView? ¿Hay una mejor manera de hacer este tipo de cosas? ¿Alguien puede recomendar una buena solución?
El siguiente código demuestra el problema. La columna Salida se actualizará continuamente y la columna Entrada prácticamente no se puede editar. He fusionado el código de diseñador (Form1.designer.cs) y Main (de Program.cs) en el código de formulario (Form1.cs), por lo que el siguiente código debería funcionar por sí mismo.
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
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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<Item> items = new BindingList<Item>();
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
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Publiqué la misma pregunta en MSDN siguiendo su comentario aquí. Hasta ahora, en más de una semana, no he tenido respuesta. –