代码之家  ›  专栏  ›  技术社区  ›  Jeff Fritz

Windows窗体文本框刷新

  •  1
  • Jeff Fritz  · 技术社区  · 16 年前

    我在Windows窗体用户控件上有一个文本框,我正在尝试从解决方案的其他位置更新的内容。

    我正在动态地将UserControl添加到我的窗体中,并且在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控件的另一个实例中…不是窗体上的实例。

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

    2 回复  |  直到 16 年前
        1
  •  2
  •   Jeff Yates    16 年前

    静态 Instance 由的所有实例共享 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();
       }
    }
    
        2
  •  0
  •   NascarEd    16 年前

    不。整个应用程序中只有一个mycontrol.instance实例(因为它是静态的)。每次设置它时,都会覆盖它的上一个实例。基本上,最后一个获胜。

    您必须在myForm中为myControl实例生成一个公共getter(或使其成为公共成员变量)。然后按这种方式设置文本。即myform1.ctl.logmessage(“blah”)。

    推荐文章