【问题标题】:C# Updating TextBox From Another ClassC# 从另一个类更新文本框
【发布时间】:2012-04-18 13:20:42
【问题描述】:

我要做的就是从另一个类更新一个文本框(在本例中为 txtInit)。我已经阅读了很多关于 UI 线程必须如何改变自身以及使用调度程序的内容。我在这里找到了一个似乎很接近的答案,但我无法让它为我工作......它说尝试使用这条线:

MainForm.Dispatcher.Invoke(new Action(delegate() {MainForm.myInstance.txtInit.Text = "Text"};);

在我的 ServerSide 类中,我需要向 MainForm 上的 txtInit 文本框发送一个字符串。这就是我需要做的一切。感谢您的帮助。

【问题讨论】:

  • 请添加一个标签来表明您是在桌面应用程序(WPF、WinForms)还是在 Web 应用程序(ASP.Net)中使用 C#。
  • 这将是一个桌面应用程序,如果这很重要,我正在使用 Visual Studio...我不确定它是否有用。

标签: c# multithreading desktop-application dispatcher


【解决方案1】:

类与线程无关(这是你现在的问题)。 每个控件都有一个Invoke 方法,它将为您执行正确的线程同步。 所以你可以做

MainForm.myInstance.txtInit.Invoke((sender, args) => (sender as TextBox).Text = "text");

为了提高性能,您可以测试(基本上告诉您是否在同一个线程中)Control.IsInvokeRequired 属性。

另一种方法是使用 UI 线程的SynchronizationContext,您需要在表单的构造函数中从 SynchronizationContext.Current 中捕获,然后执行

syncContext.Send((obj) =>  MainForm.myInstance.txtInit.Text = "Text", null);

【讨论】:

  • 好的,我该如何创建我的 MainForm 的实例?我知道我提供的代码使用了它,但我不确定它是什么以及如何使用它。
  • 啊 - 在 MainForm 类上放置一个静态字段并将实例存储在那里 - 这称为单例模式
【解决方案2】:

我可能只是在 MainForm 上创建一个公共方法,您可以将字符串传递给该方法,然后让该方法设置文本框的文本。您还可以控制是否需要我们调用 Invoke(不同的线程),这样您就不必担心在其他区域对此进行编码 - 只需调用方法并传递字符串。

这是一个例子:

 public partial class Form1 : Form
    {
        public delegate void UpdateText(string text);
        public Form1()
        {
            InitializeComponent();
        }
        public void SetTextBoxText(string text)
        {
            // Check to see if invoke required - (from another thread)
            if(textBox1.InvokeRequired)
            {
                textBox1.Invoke(new UpdateText(this.SetTextBoxText),

                    new object[]{text});
            }
            else
            {
                textBox1.Text = text;
            }
        }
    }

【讨论】:

  • 但是如果我不能访问 MainForm 来使用该方法,我就不能从我的其他线程调用该方法......我想我正在正确地考虑这个问题。在我的服务器类中,我不能说: MainForm.updateText("Text");
  • 您需要参考您的主表单。因此,如果您启动另一个窗体 - 在调用 ShowDialog() 之前 - 您需要在子窗体上设置一个属性 - 或者通过构造函数将引用传递给主窗体。
  • 好的,所以我不会启动任何其他表单。公共 MainForm() { InitializeComponent(); } [STAThread] public static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(新 MainForm());我不明白我需要在哪里“命名”?我的主窗体。
  • 您不会从 MainForm 处理产生的线程进行更新吗?把它传给那里。
  • 我将从主线程生成的线程更新主 UI 线程(主线程)。
【解决方案3】:

如果我理解正确,您似乎想从另一个线程或一些异步事件访问 Windows 窗体元素。在这种情况下,以下链接可能会对您有所帮助。

  1. http://msdn.microsoft.com/en-us/library/ms171728.aspx

  2. Update UI from multiple worker threads (.NET)

  3. Controlling form elements from a different thread in Windows Mobile

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    相关资源
    最近更新 更多