Windows窗体文本框刷新

时间:2009-06-10 19:23:55

标签: .net winforms

我在Windows窗体UserControl上有一个文本框,我试图更新解决方案中其他地方的内容。

我正在动态地将UserControl添加到我的表单中,并且我在UserControl上有一个静态Instance属性,以便我可以从引用库访问它。

为了简洁,我在这里排除了双锁检查......

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控件的另一个实例...而不是表单上的实例。

我错过了什么?静态实例引用是否应该允许我在MyForm上引用MyControl的实例?

2 个答案:

答案 0 :(得分:2)

静态InstanceMyControl的所有实例共享。如果您有多个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();
   }
}

答案 1 :(得分:0)

没有。在整个应用程序中只有一个MyControl.Instance实例(因为它是静态的)。每次设置它时,都会覆盖它的前一个实例。基本上,胜利中的最后一个。

您必须在MyForm中为MyControl实例创建一个公共getter(或使其成为公共成员变量)。并以这种方式设置文本。即myForm1.ctl.LogMessage(“blah”)。