【发布时间】:2010-12-28 16:21:22
【问题描述】:
我有一个 COM 服务器应用程序,它使用一些 WinForms 控件,坦率地说,当它们的属性(文本、背景色等)发生更改时,这些控件似乎不会重绘。
我尝试过调用txtControlName.Invalidate() 和.Update(),但似乎都没有任何影响。
我们坚持 .Net 2.0 并提供视觉响应和有趣的 UI 是一项业务需求,虽然我意识到我可能可以使用 WinAPI SendMessage() 强制重绘,但我宁愿让 .Net 处理所有这些东西 - - 已有足够多的 hack,我们不想再添加了。
最后,我想指出 .Net COM 服务器托管在非托管应用程序中。
谢谢!
汤姆
附录:
此时实际更新代码如下:
public void UpdateSt(int? seq, string text) {
Control.CheckForIllegalCrossThreadCalls = true;
if (this.lblText.InvokeRequired) {
this.lblText.Invoke(new MethodInvoker(() => {
UpdateSt(seq, text);
}));
} else {
if (text != String.Empty) {
lblText.Text = text;
//WinAPI.InvalidateRect(lblText, true);
lblText.Refresh();
//WinAPI.SendMessage(lblText.Handle, (uint)WinAPI.WM.SETTEXT, 0, new StringBuilder(text));
DebugTrace("lblText says '" + lblText.Text + "', is supposed to say '" + text + "'.");
}
if (imgSeq.HasValue) {
// not implemented yet
}
}
}
附录#2:
Spy++ 报告来自 .Net 的 Text setter 的 WM_SETTEXT 调用失败,就像我自己的 WM_SETTEXT 调用一样。
附录 #3:已解决
事实证明,问题在于消息泵损坏和一些弊大于利的 P/Invoke 调用的组合。由于库是通过 COM 启动的,因此没有 .Net 消息泵,并且在新线程中添加 Application.Run() 允许一切以应有的方式响应。确保所有基于表单的交互都从具有该调用的线程开始似乎是一个好主意。
【问题讨论】:
标签: c# .net winforms user-interface com