C#的WinForms在.net COM服务器控件将不会重绘 [英] C# WinForms control in .Net COM Server won't redraw

查看:233
本文介绍了C#的WinForms在.net COM服务器控件将不会重绘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个COM服务器应用程序,它使用了一些WinForms控件其中,坦率地说,似乎并没有在它们的属性(文字,背景色等)的变化进行重画。

I have a COM server app which uses some WinForms controls which, frankly, do not seem to be redrawing when their properties (Text, BackColor, etc) are changed.

我试图调用 txtControlName.Invalidate()以及 .Update()既不似乎是影响什么。

I have tried invoking txtControlName.Invalidate() as well as .Update() and neither seem to be affecting anything.

这是我们坚持的.Net 2.0,并提供了一​​个视觉敏感而有趣的用户界面业务需求,虽然我知道我大概可以强制重绘WinAPI的的SendMessage()我宁愿有净应付这一切的东西 - 有足够多的黑客在地方,我们不希望添加更多

It is a business requirement that we stick to .Net 2.0 and provide a visually responsive and interesting UI, and while I realize I can probably force redraws with WinAPI SendMessage() I would much rather have .Net handle all this stuff -- there are enough hacks in place and we don't want to add any more.

最后,我想指出,净COM服务器托管非托管应用程序中。

Finally, I wanted to note that the .Net COM server is hosted inside an unmanaged application.

谢谢!

汤姆

附录:

这时,实际更新code是这样的:

At this time, the actual updating code looks like:

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:

间谍++报告说,WM_SETTEXT打来NET的文本制定者发起失败,就像我自己的WM_SETTEXT电话​​。

Spy++ reports that the WM_SETTEXT call originating from .Net's Text setter is failing, much like my own WM_SETTEXT calls.

附录#3:解决

原来的问题是一个破碎的消息泵和一些P的组合/ Invoke的调用,确实弊大于利。由于库是通过COM开始没有的.Net消息泵并添加 Application.Run()里面的一个新的线程使一切应对的方式应该。这似乎是一个不错的主意,以确保所有形式为基础的互动从与该呼叫线程启动。

Turns out the problem was a combination of a broken message pump and some P/Invoke calls that did more harm than good. As the library was started via COM there was no .Net message pump and adding Application.Run() inside a new thread allows everything to respond the way it should. It seems to be a good idea to make sure all forms-based interactions start from a thread with that call.

推荐答案

通用的诊断是,有一些错误的消息泵。你是不是抱怨控件不涂料本身都如此看来不太可能,这是彻底打破。如果这是一个偶然的绘画问题,那么诊断是,你已经有了一个线程的问题。换句话说,要更新的控件的属性,或者调用Invalidate /更新,从错误的线程。

The generic diagnostic is that there is something wrong with the message pump. You are not complaining that the controls do not paint themselves at all so it seems unlikely that this is completely broken. If this is an occasional painting problem then the diagnostic is that you've got a threading problem. In other words, you are updating the control properties, or calling Invalidate/Update, from the wrong thread.

Windows窗体有内置的诊断对于这一点,主动当一个调试器附加。请确保您没有设置Control.CheckForIllegalCrossThreadCalls为false。

Windows Forms has built-in diagnostics for this, active when a debugger is attached. Make sure you don't set the Control.CheckForIllegalCrossThreadCalls to false.

接下来寻找的地方是消息泵本身。当显示的形式与他们的Show()方法而不是ShowDialog的(),那么你的非托管的消息泵将调度信息。有一些不良的副作用本身,键盘快捷键将无法正常工作了,也没有跳格。检查如果你使用的ShowDialog(),问题消失

Next place to look is the message pump itself. When you display the forms with their Show() method instead of ShowDialog() then your unmanaged message pump will be dispatching messages. That has some undesirable side-effects by itself, keyboard accelerators won't work anymore, nor does tabbing. Check if the problem disappears if you use ShowDialog().


您的评论提供了另一种暗示可能是什么问题。如果从InvokeRequired获取假,当你知道你从另一个线程调用的的你没看到您的更新,那么你使用了错误的窗体对象引用的任何明显的迹象。可能一个你使用new运算符创建的。请确保你使用现有的,Application.OpenForms []可以给大家一个参考,如果你有麻烦之一。

Your comment provides another hint at what might the problem. If you get False from InvokeRequired when you know that you're calling from another thread and you don't see any visible sign of your update then you are using the wrong Form object reference. Possibly one you created with the new operator. Make sure you use the existing one, Application.OpenForms[] can give you a reference if you have trouble getting one.

这篇关于C#的WinForms在.net COM服务器控件将不会重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆