ElementHost 布局问题
我有一堆 ElementHosts,正在加载到我的表单中。发生这种情况时,元素主机全部显示为黑色背景。如果我将另一个控件放在前面,然后关闭另一个控件,ElementHosts 将正常重新绘制。经过一番谷歌搜索后,我发现如果我对 ElementHost 进行子类化并在构造函数中执行此操作,
using (CreateGraphics()) { }
则 ElementHost 都会以良好的背景绘制......但是,每个元素主机需要大约 300 毫秒才能出现在表单上......并且它们按顺序出现...所以这就像观看表单的布局...我当然手动调用了 SuspendLayout 和 ResumeLayout ,但这不会改变结果。
这只是 Windows 窗体集成错误吗?或者我可以做些什么来使控件以合理的速度正确显示?
谢谢。
更新:我可以用非常简单的代码重现问题:
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();
}
}
I have a bunch of ElementHosts that I'm loading onto my form. When this happens, the element hosts all appear with a black background. If I bring another control to front, then close the other control, the ElementHosts are repainted normally. After some googling, I found that if I sub-class ElementHost and do this in the constructor
using (CreateGraphics()) { }
The ElementHosts are all drawn with good backgrounds....BUT, they take about 300ms per element host to appear on the form...and they appear sequentially...so it's like watching the form getting laid out... I have, of course called SuspendLayout and ResumeLayout manually, but this doesn't change the result.
Is this just Windows Forms integration bugginess? Or is there something I can do about this to make the controls appear correctly and at a reasonable rate?
Thanks.
UPDATE: I am able to reproduce the problem with the very simple code:
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
天哪,我终于让它工作了。我尝试了来自谷歌的这段代码(有几个来源...... and-its-children">我如何暂停控件及其子控件的绘制? ...举一个例子):
它没有解决我的问题,给我留下了黑色混乱的背景...但我想尝试将以下内容添加到简历中方法:
然后砰!!!有用。
Holy sh*t, I finally got it working. I tried this code from Google (there were a couple of sources.... How do I suspend painting for a control and its children? ...to name one):
It didn't solve my problem and left me with the black messed up backgrounds...BUT I thought to try adding the following to the Resume method:
and BAM!!! it works.
虽然这不是问题的直接答案,但您是否尝试过仅向 WindowsForm 添加一个 ElementHost(因此仅添加一个 WPF UserControl)。
如果您创建一个聚合所有单独的 WPF UserControl 的 WPF UserControl,则可能会实现此目的。
这对您来说是一个可行的解决方案吗?可能会减少
或者您必须将 Windows 窗体控件与 WPF 控件混合使用吗?
Although not being a direct answer to your problem, have you tried to add just one ElementHost (and hence just one WPF UserControl) to your WindowsForm.
You might achieve this if you create a WPF UserControl which aggregates all your individual WPF UserControl.
Is this a viable solution for you? t might reduve
Or do you have to mix windows forms controls with wpf ones?