Обновление текстового поля Windows Forms - PullRequest
1 голос
/ 10 июня 2009

У меня есть текстовое поле в пользовательском элементе управления Windows Forms, которое я пытаюсь обновить из другого места моего решения.

Я динамически добавляю UserControl к своей форме, и у меня есть статическое свойство Instance в UserControl, чтобы я мог получить к нему доступ из библиотеки ссылок.

Я исключил проверку двойного замка для краткости ...

public partial class MyForm : Form {

   private MyControl ctl;

   public MyForm() {
      ctl = new MyControl();
      MyControl.Instance = ctl;
      Controls.Add(ctl);
   }

}


public partial class MyControl : UserControl {

   public static MyControl Instance;

   public void LogMessage(string msg) {

       if (MyInnerTextBox.InvokeRequired) {
           MyInnerTextBox.Invoke(LogMessage, msg);
           return;
       }

       MyInnerTextBox.AppendText(msg);
       MyInnerTextBox.Refresh();
       this.Refresh();
   }

}

Когда я вызываю MyControl.Instance.LogMessage("blah") из другого класса, кажется, что мой текст добавляется к другому экземпляру элемента управления MyControl ... а не к экземпляру в форме.

Чего мне не хватает? Разве статическая ссылка на экземпляр не должна позволять мне ссылаться на экземпляр MyControl в MyForm?

Ответы [ 2 ]

2 голосов
/ 10 июня 2009

Статический Instance является общим для всех экземпляров MyControl. Если у вас есть несколько экземпляров MyForm, каждый из них изменится на Instance ссылки, поэтому все экземпляры MyForm будут указывать на один и тот же экземпляр MyControl.

Обновление

Поскольку существует только один экземпляр MyForm, это, конечно, необычно.

Однако, если вам нужна система ведения журнала, вы должны действительно отделить эту систему и иметь класс, который выполняет события ведения журнала и запуска, а затем заставить форму прослушивать событие MessageLogged в этом классе ведения журнала и обновить текстовое поле соответственно. Что-то вроде:

static class Logger
{
  public static event EventHandler<MessageLogEventArgs> MessageLogged;

  public static void LogMessage(object caller, string message)
  {
    if (MessageLogged != null)
    {
       MessageLogged(caller, new MessageLogEventArgs(message);
    }
  }
}

Таким образом, вам не нужно беспокоиться о наличии статических ссылок на элементы управления и попытке их обновления. Отсоединение системы таким образом значительно облегчит понимание и отладку вашего кода.

Классы, желающие использовать журнал вызова Logger.LogMessage и ваша форма прослушивает событие.

public partial class MyForm : Form {

   private MyControl ctl;

   public MyForm() {
      ctl = new MyControl();
      Controls.Add(ctl);

      Logger.MessageLogged += MyMessageLogHandler;
   }

   private void MyMessageLogHandler(object sender, MessageLogEventArgs e)
   {
      this.ctl.LogMessage(e.Message);
   }
}

public partial class MyControl : UserControl {

   public void LogMessage(string msg) {

       if (MyInnerTextBox.InvokeRequired) {
           MyInnerTextBox.Invoke(LogMessage, msg);
           return;
       }

       MyInnerTextBox.AppendText(msg);
       MyInnerTextBox.Refresh();
       this.Refresh();
   }
}
0 голосов
/ 10 июня 2009

Нет. Во всем приложении есть только один экземпляр MyControl.Instance (потому что он статический). Каждый раз, когда вы устанавливаете его, вы перезаписываете его предыдущий экземпляр. По сути, последний выигрывает.

Вам нужно сделать публичный метод получения в MyForm для экземпляра MyControl (или сделать его общедоступной переменной-членом). И установить текст таким образом. т.е. myForm1.ctl.LogMessage ("бла").

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