обновить свойство кнопки из другого класса и потока в c # - PullRequest
0 голосов
/ 19 сентября 2011

Я новичок в языке C #, и я был бы признателен за любую помощь / обратную связь по следующей проблеме.

По сути, я пытаюсь разработать программу так, чтобы она имела два класса class1 (основной поток) и class2.У class1 есть кнопка, а class2 запускает поток и выполняет некоторые вычисления.Как я могу обновить любое свойство кнопки в class1 (main) из class2 в потоке в class2?

вот пример, который я хотел бы сделать

// CLASS 1 is a win form 
class1:form
{

public btn_click()
{
// call function startthread from class2
 btn.Enabled = false;
 startthread()
}

}
// CLASS 2 is not a winform
class2
{
 public startthread()
 {
  Thread worker = new Thread(doCalculation)
 }

 public doCalculation()
 {
  // do some calculation then
  // blahhh
  // blahhh
  // HERE I NEED SOMEHOW ENABLED MY BUTTON 
}
}

Ответы [ 3 ]

2 голосов
/ 19 сентября 2011

Вы должны вернуть модифицирующий код обратно в основной поток, независимо от того, является ли его WPF или Winforms, межпоточный доступ к пользовательскому интерфейсу либо явно запрещенным (обычно), либо категорически не рекомендуется и глючит.

Есть много способов сделать это, в Winforms я обычно использую Control.Invoke, например:

public void UpdateMyTextBox(string NewText) 
{
    if(InvokeRequired)
       Invoke(new Action<string>(UpdateMyTextBox), NewText);
    else
       myTextBox.Text = NewText;
}

В этом примере свойство InvokeRequired проверит, вызывается ли оно в пользовательском интерфейсе.thread, а если нет, мы будем вызывать Invoke, который поместит запрос в поток пользовательского интерфейса.

В WPF вы наблюдаете за использованием Dispatcher, и вы делаете это очень похожим образом:

public void UpdateMyWpfTextBox(string NewText)
{
    if(!CheckAccess())
       Dispatcher.Invoke(new Action<string>(UpdateMyWpfTextBox), NewText);
    else
       myTextBox.Text = NewText;
}
2 голосов
/ 19 сентября 2011

Это немного зависит от используемой вами структуры пользовательского интерфейса. Например, скажем, вы хотели обновить текст, написанный на кнопке.

Если вы используете WPF, вы можете использовать:

class1Instance.TheButton.Dispatcher
      .BeginInvoke( (Action) () => class1Instance.TheButton.Content = "Foo" );

В Windows Forms вы будете использовать:

class1Instance.TheButton
      .BeginInvoke( (Action) () => class1Instance.TheButton.Text = "Foo" );
0 голосов
/ 19 сентября 2011

Не уверен, что вы пытаетесь сделать здесь, но это лучший ответ, который я могу придумать, учитывая вопросы.Я собираюсь предположить, что это приложение winforms

Class2 понадобится ссылка на кнопку в классе 1. Поэтому вам нужно будет передать это ей.

Once Class2содержит ссылку на кнопку, которую вы можете попытаться изменить для свойства:

btn.Text = "New Text";

Я собираюсь снова предположить, что вы пробовали этот маршрут, получили исключение и поэтому отправили свой вопрос.Причина, по которой вы получили исключение, заключалась в том, что ваш btn и ваш class2 работают в разных потоках.Чтобы обойти это, вы можете вызвать вызов на кнопку.Я часто с этим справляюсь.

private void SetButtonText(string newText) {
    if (btn.InvokeRequired) {
        Invoke((MethodInvoker)(() => SetButtonText(newText)));
    }
    else {
        btn.Text = newText;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...