wpf相关知识补充

PRISM框架举例:以及和MVVMLight的区别?

  1. 模块化开发‌:将应用拆分为独立模块(如用户管理、数据分析),支持动态加载与卸载,便于团队协作与维护 。
  2. ‌MVVM 模式支持‌:内置 ViewModel 基类与命令实现(如 DelegateCommand),简化数据绑定与交互逻辑,提升代码可测试性 。
  3. ‌依赖注入与解耦‌:集成 Unity 或 Autofac 等容器,管理服务生命周期,减少组件间直接依赖,通过事件聚合器(EventAggregator)实现模块间通信 。
  4. ‌导航与区域管理‌:使用 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虚拟化失败

  1. 外层嵌套了ScrollViewer(ScrollViewer 给子元素无限空间,控件会一次性渲染全部 Item)
  2. 外层StackPanel包裹列表(同样无限高度)
  3. Item 里包含嵌套的 ItemsControl 且没有单独虚拟化
  4. 直接手动 Add ListBoxItem(而不是绑定 ItemsSource)
  5. 行高不固定 + 大量复杂模板,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
}));

 

posted @ 2026-08-28 23:01  HelloWorld庄先生  阅读(6)  评论(0)    收藏  举报