WPF中的BeginUpdate等价物?

时间:2010-05-04 22:34:08

标签: c# wpf

我的问题是我需要在WPF中向ListBox添加很多项。在WinForms中,您只需使用 BeginUpdate(); 方法,添加所有内容,最后使用 EndUpdate(); 方法。

那么,在添加每个项目然后一次性绘制所有项目之前,如何在WPF列表框中停止绘图?

3 个答案:

答案 0 :(得分:12)

正确使用Dispatcher。

您必须从Dispatcher线程向ListBox(或其数据源)添加内容,否则UI将爆炸。当你这样做时,你或者已经在该线程的方法中,或者(希望更有可能)你在后台线程中并使用Dispatcher.BeginInvoke来添加项目。

当您将更新推送到Dispatcher时,请使用Dispatcherpriority.Normal作为优先级。 Dispatcher有一个工作项队列,您的Normal项将在该队列中推入(可能令人惊讶地)。

当底层数据发生变化时,WPF运行以更新数据绑定的代码位于DispatcherPriority.DataBind,低于Normal。这意味着在添加所有项目之前通常不会更新数据绑定(或者,如果您的项目需要很长时间才能添加,则在调度程序在添加项目之间空闲时可能会发生这种情况。)

实际呈现控件的代码(例如,当其绑定表示更新时)运行在DispatcherPriority.Render并且甚至比绑定更低的优先级。这意味着只有在Dispatcher用完更新绑定时才会呈现您的控件,而这只会在Dispatcher用完项目添加时才会发生。

如果这听起来很奇怪,请记住每个图层(更新 - 绑定 - 渲染)会导致在下面的图层上设置隐喻标记 - 您不会获得10个绑定,然后会发生10次渲染。如果您的项目添加速度很快,您将获得所有添加,然后是一个绑定和一个渲染 - 这是完美的。

基本上:如果您使用Dispatcher作为其预期,您将无需担心。在Dispatcher上将渲染作为一个相对较低的优先级似乎是“错误的”,但实际上,它非常聪明: - )

答案 1 :(得分:5)

听起来您可能会以编程方式逐个将项目添加到列表框中。更好的方法是将要显示的项目存储在模型中,并将模型绑定到列表框的数据上下文。这将允许WPF处理渲染更新。

如果您在问题中添加XAML的片段和代码(向我们展示您目前正在做的事情),我们可能会提供更好的答案。

编辑:添加了一个非常简单的示例。

这是一个将视图模型绑定到主窗口(视图)的示例,然后XAML声明ListBox的数据绑定到视图模型的 Numbers 属性。

<强> MainViewModel.cs

public class MainViewModel
{
    public IEnumerable<int> Numbers
    {
        get { return Enumerable.Range(1, 1000); }
    }
}

<强> MainWindow.xaml

<Window
  x:Class="WpfApplication1.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Height="350"
  Width="525"
  >
  <ListBox ItemsSource="{Binding Numbers}"/>
</Window>

<强> MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainViewModel();
    }
}

如果您刚刚开始使用WPF,我可以高度推荐Adam Nathan的Windows Presentation Foundation Unleashed。这是一本很棒的书,它的颜色很好。在此之后阅读其他书籍就像使用Visual Studio后返回记事本一样。

有关此Model-View-ViewModel内容的更多信息,请查看Josh Smith的Advanced MVVM书。

答案 2 :(得分:3)

看到您正在使用大型列表,您可能希望了解WPF UI虚拟化。以下是关于它的一系列博客文章:

http://blogs.msdn.com/dancre/archive/tags/VirtualizingTilePanel/default.aspx

通常,您会将项目添加到集合中,并将该集合数据绑定到列表框控件。如果填写正确,列表框不应刷新正在添加且不可见的项目。