我正在WPF中编写一个自定义控件。控件具有几个属性,这些属性会导致更新控件的逻辑树。这种形式有几种方法:
private static void OnXXXPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
((MyControl)obj).RebuildTree();
}
假设RebuildTree()
方法非常复杂和长,如果用户更改了几个属性,则会多次调用该方法,导致应用程序速度减慢和挂起。
我想以Windows窗体的方式介绍BeginUpdate()
和EndUpdate()
方法(以确保只调用一次更新),但这种做法在WPF中被广泛禁止。
我知道渲染器的优先级较低,可能不会出现闪烁,但为什么多次调用相同的更新方法会破坏宝贵的运行时间?
关于如何有效更新多个依赖属性(在设置每个属性后不更新整个控件),是否有任何官方最佳实践
只要在这些属性中的任何一个发生更改时设置一个标志,并且只将刷新方法排队到Dispatcher一次。
private static void OnXXXPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
((MyControl)obj).NeedsRefresh = true;
((MyControl)obj).OnNeedsRefresh();
}
void OnNeedsRefresh()
{
Dispatcher.BeginInvoke((Action)(() =>
{
if (NeedsRefresh)
{
NeedsRefresh = false;
RebuildTree();
}
}),DispatcherPriority.ContextIdle);
}
这样,所有属性都将更新,然后Dispatcher将调用BeginInvoke
,将标志设置为false,并只刷新一次。