wpf相关知识补充
PRISM框架举例:以及和MVVMLight的区别?
- 模块化开发:将应用拆分为独立模块(如用户管理、数据分析),支持动态加载与卸载,便于团队协作与维护 。
- MVVM 模式支持:内置 ViewModel 基类与命令实现(如 DelegateCommand),简化数据绑定与交互逻辑,提升代码可测试性 。
- 依赖注入与解耦:集成 Unity 或 Autofac 等容器,管理服务生命周期,减少组件间直接依赖,通过事件聚合器(EventAggregator)实现模块间通信 。
- 导航与区域管理:使用 RegionManager 定义 UI 布局区域,支持视图动态切换与参数传递,灵活应对复杂界面需求
WPF 的依赖属性、附加属性原理是什么?
1.依赖属性基于 DependencyObject 和静态注册的 DependencyProperty,使用稀疏存储(只保存被显式修改过的属性(本地值、动画、表达式等);没修改过的属性直接用元数据里的默认值,极大节省大控件实例的内存开销),按固定优先级自动求值(当调用GetValue时,WPF 属性系统按顺序找最终有效值),支持绑定动画继承;
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(Button), new PropertyMetadata(true, OnChanged, CoerceValue)); // CLR包装器,XAML解析器会直接绕过包装器调用GetValue/SetValue,不要在这里写业务逻辑! public bool IsEnabled { get => (bool)GetValue(IsEnabledProperty); set => SetValue(IsEnabledProperty, value); }
Coerce 强制值
正在运行的动画(Hold 动画)
本地值(代码 SetValue / XAML 直接赋值 / Binding)
Template 触发器
Style 触发器
Style Setter
主题样式
属性继承(元数据标记Inherits,如 FontSize)
元数据默认值
2.附加属性是 RegisterAttached 注册的特殊依赖属性,允许给任意 DependencyObject 附加属性,用于跨类型传递信息,典型布局场景。
WPF 大数据渲染卡顿怎么优化?
WPF 卡顿 90% 都是可视化树节点太多、频繁 Layout/Measure、频繁 CollectionChanged、UI 线程过载。
第一步开启UI虚拟化
<!-- ListView / ListBox 标准虚拟化写法 --> <ListView VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" ScrollViewer.CanContentScroll="True" VirtualizingPanel.ScrollUnit="Pixel"> <ListView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> <!-- DataGrid 表格 --> <DataGrid EnableRowVirtualization="True" EnableColumnVirtualization="True" VirtualizingPanel.ScrollUnit="Pixel"/>
这些会导致UI虚拟化失败
- 外层嵌套了
ScrollViewer(ScrollViewer 给子元素无限空间,控件会一次性渲染全部 Item) - 外层
StackPanel包裹列表(同样无限高度) - Item 里包含嵌套的 ItemsControl 且没有单独虚拟化
- 直接手动 Add ListBoxItem(而不是绑定 ItemsSource)
- 行高不固定 + 大量复杂模板,Virtualizing 计算开销暴涨
第二步数据层优化
1.不要频繁单独Add/Remove ObservableCollection (ObservableCollection每一次增删都会触发CollectionChanged,触发全量布局)
var tempList = new List<DataItem>();//先缓存临时表然后一次性赋值 // 填充数据 _collection = new ObservableCollection<DataItem>(tempList); // 或者使用DynamicData SourceCache,增量更新(工业实时项目首选)
2.INotifyPropertyChanged优化
- 只有值真正变化才触发通知
if(_val == newVal) return; - 批量更新时临时屏蔽 PropertyChanged,更新完一次性通知
3.绑定模式精简
能用OneTime / OneWay绝不使用TwoWay;减少不必要的绑定。
什么是领域驱动 DDD?你有没有在项目里实践过?聚合根、值对象怎么划分?
第五步Dispatcher调度优化
UI 更新使用低优先级DispatcherPriority.Background / ApplicationIdle,不要抢占输入、渲染消息
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { // 更新UI }));
浙公网安备 33010602011771号