[英]Update a Modeless Dialog from the Main Window with Windows Forms
我正在使用C#/。NET 3.5 / Windows Forms程序。 我想创建一个“无模式对话框”,然后使用从主窗体生成的信息对其进行更新。 我已经找到了另一个方向的示例-对话框中的信息会更新主窗口,但是在反向时遇到了麻烦。 对话框中的GUI不能正常运行。 鼠标光标是一个沙漏。 我有时会看到更新,但是我经常会看到一个白色的实心框,曾经位于对话框顶部的其他窗口的残留或冻结。
最终,对话框将显示更复杂的信息,但是现在我只是想复制一个在主窗口中显示为标签的计数器。 要启动对话框,请执行以下操作:
bool secondWindowOpen = false;
Thread secondWindowThread;
MyPopupWindow secondWindow;
delegate void TextBoxDelegate(string message);
private void buttonPop_Click(object sender, EventArgs e)
{
// If the second window is not open, then open it
if (!secondWindowOpen)
{
secondWindowOpen = true;
secondWindow = new MyPopupWindow();
secondWindowThread = new Thread(secondWindow.MyMethod);
secondWindowThread.Start();
}
else // Close the second window
{
secondWindowOpen = false;
secondWindow.ShouldStop = true;
secondWindowThread.Join();
}
}
我使用以下代码更新计数器:
if (secondWindow != null)
{
secondWindow.CounterText = args.FrameNumber.ToString();
}
用于控制“无模式对话框”的代码如下所示。 我承认设置文本字段的代码可能是错误的,但这是我目前最好的工作(调用给我带来了麻烦)。
public partial class MyPopupWindow : Form
{
public MyPopupWindow()
{
InitializeComponent();
}
public bool ShouldStop
{
get { return shouldStop; }
set { shouldStop = value; }
}
private bool shouldStop = false;
public void MyMethod()
{
this.Show();
this.Refresh();
while (!shouldStop)
{
Thread.Sleep(100);
labelCounter.Text = CounterText;
Refresh();
}
this.Close();
}
public string CounterText;
}
我的主要问题如下:当仅需要更新自己的GUI元素时,将无模式对话框放入第二个线程的最佳方法是什么? 从主窗口/线程更新那些GUI元素的最佳方法是什么? 谢谢!
表单的工作方式是,如果程序是处理消息并将其传递到要处理的表单的循环,则其核心是核心。 如果您的窗体从不将控制权返回到消息循环,则程序将停止正常运行。 您试图通过添加更多线程来解决此问题,但是那样会导致它自己的痛苦。
您不能在线程中执行此操作,因为应用于表单的所有操作都必须在UI线程上完成。 您可以使用BeginInvoke将诸如Invalidate之类的调用传递回UI线程,但这确实很麻烦-编写在一个UI线程上运行的协作窗口比触发许多线程然后尝试将UI线程插入其中要好得多为他们做事。
为此,您将创建表单,然后将控制权返回到消息处理循环。 在将来的某个时间,您将关闭诸如单击按钮之类的事件的窗口。 如果由于任何事件而需要更新窗口,则可以在事件处理程序中调用invalidate然后返回。
根据Jason的建议,我最终简化了事情并使之真正起作用。
首先,当我显示第二个窗口时,不再需要启动新线程。 相反,我执行以下操作:
bool secondWindowOpen = false;
MyPopupWindow secondWindow;
private void buttonPop_Click(object sender, EventArgs e)
{
// If the second window is not open, then open it
if (!secondWindowOpen)
{
secondWindowOpen = true;
secondWindow = new MyPopupWindow();
secondWindow.Show();
}
else // Close the second window
{
secondWindowOpen = false;
secondWindow.Close();
}
}
然后,我将第二个窗口中的代码简化为以下内容:
public partial class MyPopupWindow : Form
{
public MyPopupWindow()
{
InitializeComponent();
}
public string CounterText
{
set { labelCounter.Text = value; }
}
}
首先,因为我是法国人,请为我的英语道歉。
然后,如果我理解您的问题,那么您想从第一个Form更新第二个Form的控件。
请使用表单的Tag对象。
从第一个Form创建第二个Form的实例,如下所示:
Form2 f = new Form2();
f.Tag = MyDataObject();
显示形式像
f.Show() => Modeless way
或f.ShowDialog => Modal way
在Form2的构造函数中,您可以从Tag对象更新控件,如下所示:
public Form2()
{
MyDataObject do = (MyDataObject)this.Tag;
MyLabel.Text = do.LabelText;
}
如果要从Form2到主窗体执行此操作,请执行以下操作:
进入Form2
this.Tag = MyDataObject;
this.Close();
进入主要形式:
`MyDataObject do = (MyDataObject)f2.Tag;`
我知道这个话题很旧,但希望对您有所帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.