Как я могу установить свойства DataGridViewComboBoxColumn в потоке? (C # Winforms) - PullRequest
1 голос
/ 29 сентября 2010

Я изучаю делегаты и простые потоки, я попробовал это в ComboBox элементе управления и экспериментировал с DataGridViewComboBoxColumn (потому что я думал, что это будет то же самое), но кажется, что для этого нет свойства Invoke вид.

Как настроить свойства DataGridViewComboBoxColumn в потоке?
Пожалуйста, смотрите мой код, это работает для установки свойств элемента управления ComboBox с помощью потока:

    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 Thread(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" });
});
    }        

Пожалуйста, помогите ... заранее спасибо.

Ответы [ 2 ]

1 голос
/ 29 сентября 2010

Создайте функцию, как показано ниже

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 });
  }
}

Назовите ее как

// 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);

ИЛИ

Если вы используете .NET 3.5 или выше, вы можетеперепишите вышеупомянутый метод как метод расширения класса Control, который затем упростит вызов:

    myLabel.SetPropertyThreadSafe("Text", status);
//In your case get the object of the dgv combo column

     dgvComboColumn.SetPropertyThreadSafe("Property", Value);

ИЛИ


Попробуйте это

this.Invoke((MethodInvoker)delegate {
    dgvComboColumn.FieldName= xColumnName; // runs on UI thread
    dgvComboColumn2.Visible = true; // runs on UI thread
});

Справочник по Stackoverflow: Как обновить графический интерфейс из другого потока в C #?

1 голос
/ 29 сентября 2010

Используйте свойство InvokeRequired и метод Invoke экземпляра DataGridView, с которым вы работаете.Поскольку столбцы связаны с определенным DGV, они должны находиться в одном потоке.

Редактировать: Пример кода

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";
}      

и изменить строку с надписью
//dataGridViewComboBoxColumn1.Invoke(delegateSetEvents, new object[] { dataSource, "ShortName", "LongName" }); });

должно быть
SetProperties(dataSource, "ShortName", "LongName");

Вы хотите выполнить проверку InvokeRequired внутри SetProperties, чтобы убедиться, что метод является потокобезопасным.В противном случае, если метод не убедился, что он находится в нужном потоке перед вызовом SetProperties, это может привести к недопустимой операции перекрестного потока

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...