WPF性能优化集锦
一、UI渲染性能优化
1. 虚拟化技术
ListView/GridView虚拟化:
<ListView VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True">
<!-- ItemTemplate... -->
</ListView>
关键点:
IsVirtualizing="True"
:启用虚拟化(默认值)VirtualizationMode="Recycling"
:重用容器(比标准虚拟化更高效)IsDeferredScrollingEnabled="True"
:延迟滚动更新
DataGrid虚拟化:
<DataGrid VirtualizingStackPanel.IsVirtualizing="True"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
ScrollViewer.IsDeferredScrollingEnabled="True">
<!-- 列定义... -->
</DataGrid>
2. 减少不必要的重绘
冻结静态资源:
<Window.Resources>
<SolidColorBrush x:Key="StaticBrush" Color="Blue" PresentationOptions:Freeze="True"/>
</Window.Resources>
使用x:Shared="False":
<Window.Resources>
<DataTemplate x:Key="ItemTemplate" x:Shared="False">
<!-- 模板内容 -->
</DataTemplate>
</Window.Resources>
避免频繁触发InvalidateArrange/InvalidateMeasure:
// 不好的做法
private void UpdateUI()
{
// 多次修改属性会触发多次布局计算
myControl.Width = 100;
myControl.Height = 200;
myControl.Margin = new Thickness(10);
}
// 好的做法 - 批量更新
private void UpdateUI()
{
myControl.BeginInit();
myControl.Width = 100;
myControl.Height = 200;
myControl.Margin = new Thickness(10);
myControl.EndInit();
}
二、数据绑定优化
1. 高效的数据绑定模式
使用INotifyPropertyChanged最小化通知:
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged(nameof(Name));
// 只有当Name变化会影响其他属性时才通知
if (value.Length > 10) OnPropertyChanged(nameof(IsNameLong));
}
}
}
使用OneTime绑定减少开销:
<TextBlock Text="{Binding StaticText, Mode=OneTime}"/>
2. 高级绑定技术
使用x:Reference减少绑定路径:
<StackPanel>
<TextBox x:Name="InputBox" Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding Text, ElementName=InputBox}"/>
</StackPanel>
使用MultiBinding与优先级绑定:
<TextBlock>
<TextBlock.Text>
<PriorityBinding>
<Binding Path="FastProperty" IsAsync="True"/>
<Binding Path="SlowProperty"/>
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
三、样式与模板优化
1. 样式共享
定义可重用样式:
<Window.Resources>
<Style x:Key="CommonButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#FFDDDDDD"/>
<Setter Property="Foreground" Value="#FF333333"/>
</Style>
<!-- 应用样式 -->
<Button Style="{StaticResource CommonButtonStyle}" Content="按钮1"/>
<Button Style="{StaticResource CommonButtonStyle}" Content=