【问题标题】:How to make non-modal WPF window fully draw before thread waiting如何在线程等待之前使非模态WPF窗口完全绘制
【发布时间】:2013-08-27 10:18:10
【问题描述】:

我想显示非模态信息窗口并等待其他线程中的智能卡触摸。我需要阻止我的主 UI 线程以防止用户操作,除非智能卡将被读卡器触摸。 我在主线程中这样做:

InformationWindow infoWindow = new InformationWindow();
infoWindow.tblockInfo.Text = someInfoAboutRequieredAction;
infoWindow.Show();

Semaphore.WaitOne();

infoWindow.Close();

它工作正常,在某些情况下可以正常绘制,但我的信息 WPF 窗口通常没有完全绘制。只有标题部分,窗口内没有一个控件(和背景颜色)在悬挂时可见

请帮忙,我一个星期不明白该怎么办

附:我在Semaphore.WaitOne() 之前尝试过InvalidateVisual()UpdateLayout()Thread.Sleep,但没有帮助

【问题讨论】:

  • 尽量不要阻塞 UI 线程,一切都应该画得很好。通常对于后台任务,您会使用第二个线程,但新的异步功能应该很容易解决这个问题。
  • 我的应用程序与智能卡处理有关。我需要阻止我的主 UI 线程以防止用户操作,除非智能卡将被读卡器触摸(用于在其上写入新数据)
  • ShowDialog() 是专门为它发明的。使用它并为所有后台工作使用 Threads/Tasks/BackgroundWorker 等
  • 是的,谢谢,但是在这种情况下,当它完成对智能卡的处理时,如何在其他线程中关闭此窗口?我需要排除任何关闭此窗口和下一个用户在不使用智能卡的情况下工作的可能性......

标签: c# wpf multithreading window non-modal


【解决方案1】:

阻塞主 UI 线程与阻塞 UI 非常不同。你最好禁用 UI(例如MainWindow.IsEnabled = false)并让 UI 线程来绘制窗口。

这还允许您向InformationWindow 添加一个取消按钮,以防有人启动此过程并且手头没有智能卡。

【讨论】:

  • 是的,我可以用“MainWindow.IsEnabled = false”阻止我的用户界面,但是当它在用户提交智能卡后完成处理时,如何在我的其他线程(处理智能卡)中取消阻止它卡片。如果我在其他线程中写“((MainWindow)Application.Current.MainWindow).IsEnabled = true”或“((MainWindow)Application.Current.MainWindow).infoWindow.Close()”将导致异常“调用线程无法访问此对象,因为不同的线程拥有它”
  • @KonstantinGertsenberger 如果您从非 UI 线程调用,请使用调度程序
  • @dnr3 好的,谢谢。我知道如何使用它。我希望这是一个好的决定,并且没有任何方法可以在“Semaphore.WaitOne()”之前重新绘制完全非模态窗口以正确显示它。
  • @KonstantinGertsenberger,正如 toerhs 所说,不要执行硬等待,例如 GUI 线程中的“Semaphore.WaitOne()”。绘制表单通常意味着绘制多个窗口和发送/发布多个消息,这是必须处理的。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多