我的问题是我需要在WPF中向ListBox添加很多项.在WinForms中,您只需使用BeginUpdate(); 方法,添加所有内容,最后使用EndUpdate(); 方法.
那么,在添加每个项目然后一次性绘制所有项目之前,如何在WPF列表框中停止绘图?
Dan*_*zey 12
正确使用Dispatcher.
您必须从Dispatcher线程向ListBox(或其数据源)添加内容,否则UI将爆炸.当你这样做时,你或者已经在该线程的方法中或者(希望更有可能)你在后台线程中并使用Dispatcher.BeginInvoke添加项目.
当您将更新踢到Dispatcher时,Dispatcherpriority.Normal请将其用作优先级.Dispatcher有一个工作项队列,您的Normal项目将在该队列中推入(可能令人惊讶地).
当底层数据发生变化时,WPF运行以更新数据绑定的代码DispatcherPriority.DataBind位于低于Normal.这意味着在添加所有项目之前通常不会更新数据绑定(或者,如果您的项目需要很长时间才能添加,则可能会在Dispatcher在添加项目之间空闲时发生).
实际呈现您的控件的代码(例如,当其绑定发出更新信号时)运行在DispatcherPriority.Render并且甚至比绑定更低的优先级.这意味着您的控件将仅在Dispatcher用完更新绑定时呈现,而这只会在Dispatcher用完项目添加到进程时发生.
如果这听起来很奇怪,请记住每个图层(更新 - 绑定 - 渲染)会导致在下面的图层上设置隐喻标记 - 您不会获得10个绑定,然后会发生10个渲染.如果您的项目添加速度很快,您将获得所有添加,然后是一个绑定和一个渲染 - 这是完美的.
基本上:如果您使用Dispatcher作为其预期,您将无需担心.在Dispatcher上将渲染作为一个相对较低的优先级似乎是"错误的",但实际上,它非常聪明:-)
听起来您可能以编程方式逐个将项目添加到列表框中.更好的方法是将要显示的项目存储在模型中,并将模型绑定到列表框的数据上下文.这将允许WPF处理渲染更新.
如果您将XAML的片段和代码添加到问题中(向我们展示您当前正在做的事情),我们可能会提供更好的答案.
编辑:添加了一个非常简单的例子.
这是一个将视图模型绑定到主窗口(视图)的示例,然后XAML声明ListBox的数据绑定到视图模型的Numbers属性.
MainViewModel.cs
public class MainViewModel
{
public IEnumerable<int> Numbers
{
get { return Enumerable.Range(1, 1000); }
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您刚刚开始使用WPF,我强烈推荐Adam Nathan 释放的Windows Presentation Foundation.这是一本很棒的书,它的颜色很好.在此之后阅读其他书籍就像使用Visual Studio后返回记事本一样.
有关这个Model-View-ViewModel的更多信息,请查看Josh Smith的高级MVVM书籍.
| 归档时间: |
|
| 查看次数: |
6639 次 |
| 最近记录: |