C# 降低绑定更新速度?
我的应用程序包含许多C# 降低绑定更新速度?,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,我的应用程序包含许多列表框。每个ListBox都包含许多ListBoxItem。我试图强制执行的是,ListBoxItem的MaxWidth始终是ListBox宽度的80%。目前,我将其绑定如下: <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="MaxWidth" Value="{Binding Path=ActualWidth, RelativeSource={RelativeSource Anc
列表框
。每个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
计算量过大所致
有什么方法可以做到这一点而不会在调整大小时造成巨大的减速,或者有什么方法可以要求绑定不那么频繁地更新?在WinForm中托管Wpf控件时,我们也遇到了类似的问题。我们的最佳解决方案是在
OnResize事件中暂停控件的布局,如下所示:
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互操作性的帮助器函数
///
公共静态类WpfInteropHelper
{
私有常量int WMSETREDRAW=0x000B;
///
///挂起指定的控件。
///
///控制。
公共静态无效暂停(控制)
{
Message msgSuspendUpdate=Message.Create(control.Handle、WMSETREDRAW、IntPtr.Zero、IntPtr.Zero);
NativeWindow=NativeWindow.FromHandle(control.Handle);
DefWndProc(参考msgSuspendUpdate);
}
///
///恢复指定的控件。
///
///控制。
公共静态无效恢复(控制)
{
control.Visible=false;
var wparam=新IntPtr(1);
Message msgResumeUpdate=Message.Create(control.Handle、WMSETREDRAW、wparam、IntPtr.Zero);
NativeWindow=NativeWindow.FromHandle(control.Handle);
如果(窗口!=null){
window.DefWndProc(参考msgResumeUpdate);
}
控件。使无效();
control.Visible=true;
}
}
我希望您也可以将其用于WPF控件。您想要它做什么?只需使用包含2个网格列(“.8*”和“.2*”)的适当模板。您的方法完全错误。这是一个聊天程序,因此它有一个典型的界面,其中传入消息位于左侧(.8*,带.2*间隔),传出消息位于右侧(.2*间隔,带.8*)。在这种情况下,我不确定定义GridColumn是否有效…?这些都与ListBoxItem.Width
无关。开始阅读。只需使用DataTrigger将TextAlignment设置为左或右。否则,使用DataTrigger
更改文本的Grid.Column等。