我有一堆ElementHosts,我正在加载到我的表单上。发生这种情况时,元素主机全部显示为黑色背景。如果我将另一个控件带到前面,然后关闭另一个控件,则ElementHosts会正常重新绘制。经过一些谷歌搜索后,我发现如果我对ElementHost进行子类化并在构造函数
中执行此操作 using (CreateGraphics()) { }
ElementHosts都是用很好的背景绘制的......但是,它们每个元素主机大约需要300毫秒才会出现在表单上......然后它们依次出现...所以就像看着表格一样......我当然手动调用SuspendLayout和ResumeLayout,但这不会改变结果。
这只是Windows Forms集成的烦恼吗?或者我可以做些什么来使控件正确且合理地显示出来?
感谢。
更新:我能够用非常简单的代码重现问题:
public partial class TestControl2 : UserControl
{
public TestControl2()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// deferring load with the BackgroundWorker seems to be related to the problem here...
var bw = new BackgroundWorker();
bw.DoWork += delegate { Thread.Sleep(2000); };
bw.RunWorkerCompleted += delegate
{
int x = 0;
int y = 0;
for (int i = 0; i < 20; i++)
{
var control = new Panel();
control.Width = 200;
control.Height = 80;
control.Controls.Add(new ElementHost { Child = new System.Windows.Controls.Label { Content = @"Hello" }, Dock = DockStyle.Left, Size = new System.Drawing.Size(75, 23) });
control.Controls.Add(new ElementHost { Child = new System.Windows.Controls.Button { Content = @"button" }, Dock = DockStyle.Fill });
var uc2 = new UserControl();
uc2.Controls.Add(control);
control.Dock = DockStyle.Fill;
uc2.Left = x;
uc2.Top = y;
x += control.Width + 10;
// adding using (uc2.CreateGraphics()) {} fixes the problem but slows down the load so it looks like each UserControl is being added one at a time
panel1.Controls.Add(uc2);
}
};
bw.RunWorkerAsync();
}
}
答案 0 :(得分:2)
天哪,我终于明白了。我尝试了来自Google的这段代码(有几个来源.... How do I suspend painting for a control and its children? ...来命名一个):
private const int WM_SETREDRAW = 0x000B;
public static void Suspend(this Control control)
{
Message msgSuspendUpdate = Message.Create(control.Handle, WM_SETREDRAW, IntPtr.Zero,
IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc(ref msgSuspendUpdate);
}
public static void Resume(this Control control)
{
var wparam = new IntPtr(1);
Message msgResumeUpdate = Message.Create(control.Handle, WM_SETREDRAW, wparam,
IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc(ref msgResumeUpdate);
control.Invalidate();
}
它没有解决我的问题并让我留下黑色混乱的背景......但我想尝试将以下内容添加到Resume方法中:
public static void Resume(this Control control)
{
control.Visible = false;
// existing code above....
control.Visible = true;
}
和BAM !!!它有效。
答案 1 :(得分:0)
虽然不能直接解决您的问题,但是您是否尝试过只添加一个ElementHost(因此只添加一个WPF UserControl)到您的WindowsForm中。
如果您创建一个聚合所有WPF UserControl的WPF UserControl,您可能会实现此目的。 这是一个可行的解决方案吗?可能会减少 或者你必须将Windows窗体控件与wpf混合使用吗?