How can I set the Properties of a DataGridViewComboBoxColumn in a thread? (C# Winforms)
I'm studying delegates and simple threading, I tried it in a ComboBox
control, and experimented in a DataGridViewComboBoxColumn
(cause I thought it would be the same) but it seems there's no Invoke
property for this kind.
How can I set DataGridViewComboBoxColumn properties in a thread?
Please see my code, this works for setting the properties of aComboBox
control using a thread:
private delegate void DelegateSetProperties(DataTable dataSource, string valueMember, string displayMember);
Thread thread1;
DelegateSetProperties delegateSetProperties;
private void Form1_Load(object sender, EventArgs e)
{
delegateSetProperties = new DelegateSetProperties(SetProperties);
thread1 = new Thr开发者_开发百科ead(new ThreadStart(InitValues));
thread1.IsBackground = true;
thread1.Start();
}
private void SetProperties(DataTable dataSource, string valueMember, string displayMember)
{
comboBox1.DataSource = dataSource;
comboBox1.ValueMember = valueMember;
comboBox1.DisplayMember = displayMember;
comboBox1.SelectedIndex = 0;
//dataGridViewComboBoxColumn1.DataSource = dataSource;
//dataGridViewComboBoxColumn1.DisplayMember = valueMember;
//dataGridViewComboBoxColumn1.ValueMember = displayMember";
}
void InitValues()
{
var dt = new DataTable
{
TableName = "CATEGORY",
Columns = {
{"CategoryCode", typeof(string)},
{"Name", typeof(string)},
}
};
dt.Rows.Add("C1", "Category1");
dt.Rows.Add("C2", "Category2");
dt.Rows.Add("C3", "Category3");
// and so on...
comboBox1.Invoke(delegateSetProperties, new object[] { dt, "CategoryCode", "Name"
//dataGridViewComboBoxColumn1.Invoke(delegateSetEvents, new object[] { dt, "CategoryCode", "Name" });
});
}
Please help...thanks in advance.
Create a function as shown below
private delegate void SetControlPropertyThreadSafeDelegate(Control control, string propertyName, object propertyValue);
public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
{
if (control.InvokeRequired)
{
control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
}
else
{
control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
}
}
Call it like
// thread-safe equivalent of
// myLabel.Text = status;
SetControlPropertyThreadSafe(myLabel, "Text", status);
//In your case get the object of the dgv combo column
SetControlPropertyThreadSafe(dgvComboColumn, "Property", Value);
OR
If you're using .NET 3.5 or above, you could rewrite the above method as an extension method of the Control class, which would then simplify the call to:
myLabel.SetPropertyThreadSafe("Text", status);
//In your case get the object of the dgv combo column
dgvComboColumn.SetPropertyThreadSafe("Property", Value);
OR
Try this
this.Invoke((MethodInvoker)delegate {
dgvComboColumn.FieldName= xColumnName; // runs on UI thread
dgvComboColumn2.Visible = true; // runs on UI thread
});
Stackoverflow Reference : How to update the GUI from another thread in C#?
Use the InvokeRequired
property and Invoke
method of the DataGridView instance you're working with. Because the columns are linked to a specific DGV, they should be on the same thread.
Edit: Some example code
private void SetProperties(DataTable dataSource, string valueMember, string displayMember)
{
if (dataGridView1.InvokeRequired){
dataGridView1.Invoke(new DelegateSetProperties(SetProperties), dataSource, valueMember, displayMember);
return;
}
dataGridViewComboBoxColumn1.DataSource = dataSource;
dataGridViewComboBoxColumn1.DisplayMember = valueMember;
dataGridViewComboBoxColumn1.ValueMember = displayMember";
}
and change your line that says
//dataGridViewComboBoxColumn1.Invoke(delegateSetEvents, new object[] { dataSource, "ShortName", "LongName" });
});
to be
SetProperties(dataSource, "ShortName", "LongName");
You want to do the InvokeRequired check inside of SetProperties to make sure that the method is thread safe. Otherwise, if a method didn't make sure it was on the right thread before calling SetProperties, it could cause an Illegal Cross Thread Operation
精彩评论