我的应用包含许多ListBox
。每个ListBox
包含许多ListBoxItem
。我想要强制执行的是,ListBoxItem的MaxWidth
始终是ListBox宽度的80%。目前,我这样绑定它:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="MaxWidth" Value="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=ListBox}, Converter={StaticResource MessageWidthConverter}}"/>
它可以工作,但不幸的是它使应用程序的大小非常缓慢。在重新调整大小的过程中,i7 2600的CPU使用率超过了50%,我理解这是由于数千个ListBoxItem的新MaxWidth
的大量计算所致。
有没有办法在不调整大小的过程中造成巨大的减速,或以任何方式要求绑定不经常更新?
答案 0 :(得分:1)
在WinForm中托管Wpf控件时,我们遇到了类似的问题。对我们来说,最好的解决方案是在OnResize Event
:
protected override void OnResize(EventArgs e)
{
// supress flickering if dockstate is float
if (DockHandler.DockState == WeifenLuo.WinFormsUI.Docking.DockState.Float) {
WpfInteropHelper.Suspend(this);
}
base.OnResize(e);
if (DockHandler.DockState == WeifenLuo.WinFormsUI.Docking.DockState.Float) {
WpfInteropHelper.Resume(this);
}
}
因此我们添加了一个辅助类:
/// <summary>
/// Class containing helper functions for wpf interoperability
/// </summary>
public static class WpfInteropHelper
{
private const int WMSETREDRAW = 0x000B;
/// <summary>
/// Suspends the specified control.
/// </summary>
/// <param name="control">The control.</param>
public static void Suspend(Control control)
{
Message msgSuspendUpdate = Message.Create(control.Handle, WMSETREDRAW, IntPtr.Zero, IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(control.Handle);
window.DefWndProc(ref msgSuspendUpdate);
}
/// <summary>
/// Resumes the specified control.
/// </summary>
/// <param name="control">The control.</param>
public static void Resume(Control control)
{
control.Visible = false;
var wparam = new IntPtr(1);
Message msgResumeUpdate = Message.Create(control.Handle, WMSETREDRAW, wparam, IntPtr.Zero);
NativeWindow window = NativeWindow.FromHandle(control.Handle);
if (window != null) {
window.DefWndProc(ref msgResumeUpdate);
}
control.Invalidate();
control.Visible = true;
}
}
我希望您也可以将它用于WPF控件。