[{"data":1,"prerenderedAt":2500},["ShallowReactive",2],{"page-\u002Fcsharp\u002Fwpf\u002Fwpf-ui组件库使用":3},{"id":4,"title":5,"body":6,"description":19,"extension":2494,"meta":2495,"navigation":193,"path":2496,"seo":2497,"stem":2498,"__hash__":2499},"content\u002Fcsharp\u002FWPF\u002Fwpf-ui组件库使用.md","Wpf Ui组件库使用",{"type":7,"value":8,"toc":2474},"minimark",[9,20,28,31,34,38,41,295,299,304,309,319,324,335,340,348,352,357,368,373,381,385,390,395,400,408,413,421,426,434,439,447,451,456,464,469,477,482,490,494,499,507,512,520,524,559,585,589,639,659,663,693,710,713,746,749,752,1343,1350,1502,1505,1516,1519,2253,2279,2283,2288,2302,2306,2310,2318,2321,2324,2328,2348,2352,2355,2427,2430,2441,2459,2470],[10,11,16],"pre",{"className":12,"code":14,"language":15},[13],"language-text","WPFUI 是一个为 WPF 应用程序提供现代化 UI 组件的框架，它旨在简化开发过程并增强用户界面体验。WPFUI 的目标是提供现代、直观且易于使用的控件和样式，帮助开发者更快地构建美观的应用程序。以下是对 WPFUI 框架的介绍：\n","text",[17,18,14],"code",{"__ignoreMap":19},"",[21,22,23,24],"p",{},"​\t",[25,26,27],"strong",{},"主要特点",[21,29,30],{},"**现代化设计：**WPFUI 提供了一组符合现代设计规范的 UI 组件，使应用程序看起来更时尚和专业。\n**易用性：**框架设计简洁，使用方便，开发者可以快速上手，并在项目中轻松集成 WPFUI 提供的控件和样式。\n**丰富的控件库：**WPFUI 包含许多常用的控件，如按钮、文本框、菜单、对话框等，并且这些控件都经过精心设计，具有良好的用户体验。\n**高可定制性：**开发者可以根据项目需求对 WPFUI 提供的控件进行自定义，从而实现符合特定要求的用户界面。\n**响应式布局：**WPFUI 支持响应式布局，可以在不同大小的屏幕上保持良好的显示效果。\n**持续更新与支持：**WPFUI 框架有活跃的开发社区和官方支持，定期发布更新和新特性，确保框架始终处于最新状态。",[21,32,33],{},"他实际上依靠社区完成的，因为现在只提供了WinUi继承了fluentUI，因此我们需要依靠这个社区工具完成fluent风格的ui搭建",[35,36,37],"h2",{"id":37},"导航栏",[21,39,40],{},"这里先给出一个大致的实现过程：",[10,42,46],{"className":43,"code":44,"language":45,"meta":19,"style":19},"language-xaml shiki shiki-themes github-light github-dark"," \u003Cui:NavigationView\n     x:Name=\"NavigationView\"\n     Padding=\"42,0,42,0\"\n     BreadcrumbBar=\"{Binding ElementName=BreadcrumbBar}\"\n     EnableDebugMessages=\"True\"\n     FooterMenuItemsSource=\"{Binding ViewModel.FooterMenuItems, Mode=OneWay}\"\n     FrameMargin=\"0\"\n     IsBackButtonVisible=\"Visible\"\n     IsPaneToggleVisible=\"True\"\n     MenuItemsSource=\"{Binding ViewModel.MenuItems, Mode=OneWay}\"\n     OpenPaneLength=\"310\"\n     PaneClosed=\"NavigationView_OnPaneClosed\"\n     PaneDisplayMode=\"Left\"\n     PaneOpened=\"NavigationView_OnPaneOpened\"\n     SelectionChanged=\"OnNavigationSelectionChanged\"\n     TitleBar=\"{Binding ElementName=TitleBar, Mode=OneWay}\"\n     Transition=\"FadeInWithSlide\">\n     \u003Cui:NavigationView.Header>\n         \u003CStackPanel Margin=\"42,32,42,20\">\n             \u003Cui:BreadcrumbBar x:Name=\"BreadcrumbBar\" \u002F>\n             \u003C!--\u003Ccontrols:PageControlDocumentation Margin=\"0,10,0,0\" NavigationView=\"{Binding ElementName=NavigationView}\" \u002F>-->\n         \u003C\u002FStackPanel>\n     \u003C\u002Fui:NavigationView.Header>\n\n     \u003Cui:NavigationView.AutoSuggestBox>\n         \u003Cui:AutoSuggestBox x:Name=\"AutoSuggestBox\" PlaceholderText=\"{i18n:StringLocalizer 'Search'}\">\n             \u003Cui:AutoSuggestBox.Icon>\n                 \u003Cui:IconSourceElement>\n                     \u003Cui:SymbolIconSource Symbol=\"Search24\" \u002F>\n                 \u003C\u002Fui:IconSourceElement>\n             \u003C\u002Fui:AutoSuggestBox.Icon>\n         \u003C\u002Fui:AutoSuggestBox>\n     \u003C\u002Fui:NavigationView.AutoSuggestBox>\n\n     \u003Cui:NavigationView.ContentOverlay>\n         \u003CGrid>\n             \u003Cui:SnackbarPresenter x:Name=\"SnackbarPresenter\" \u002F>\n         \u003C\u002FGrid>\n     \u003C\u002Fui:NavigationView.ContentOverlay>\n\n \u003C\u002Fui:NavigationView>\n","xaml",[17,47,48,56,62,68,74,80,86,92,98,104,110,116,122,128,134,140,146,152,158,164,170,176,182,188,195,201,207,213,219,225,231,237,243,249,254,260,266,272,278,284,289],{"__ignoreMap":19},[49,50,53],"span",{"class":51,"line":52},"line",1,[49,54,55],{}," \u003Cui:NavigationView\n",[49,57,59],{"class":51,"line":58},2,[49,60,61],{},"     x:Name=\"NavigationView\"\n",[49,63,65],{"class":51,"line":64},3,[49,66,67],{},"     Padding=\"42,0,42,0\"\n",[49,69,71],{"class":51,"line":70},4,[49,72,73],{},"     BreadcrumbBar=\"{Binding ElementName=BreadcrumbBar}\"\n",[49,75,77],{"class":51,"line":76},5,[49,78,79],{},"     EnableDebugMessages=\"True\"\n",[49,81,83],{"class":51,"line":82},6,[49,84,85],{},"     FooterMenuItemsSource=\"{Binding ViewModel.FooterMenuItems, Mode=OneWay}\"\n",[49,87,89],{"class":51,"line":88},7,[49,90,91],{},"     FrameMargin=\"0\"\n",[49,93,95],{"class":51,"line":94},8,[49,96,97],{},"     IsBackButtonVisible=\"Visible\"\n",[49,99,101],{"class":51,"line":100},9,[49,102,103],{},"     IsPaneToggleVisible=\"True\"\n",[49,105,107],{"class":51,"line":106},10,[49,108,109],{},"     MenuItemsSource=\"{Binding ViewModel.MenuItems, Mode=OneWay}\"\n",[49,111,113],{"class":51,"line":112},11,[49,114,115],{},"     OpenPaneLength=\"310\"\n",[49,117,119],{"class":51,"line":118},12,[49,120,121],{},"     PaneClosed=\"NavigationView_OnPaneClosed\"\n",[49,123,125],{"class":51,"line":124},13,[49,126,127],{},"     PaneDisplayMode=\"Left\"\n",[49,129,131],{"class":51,"line":130},14,[49,132,133],{},"     PaneOpened=\"NavigationView_OnPaneOpened\"\n",[49,135,137],{"class":51,"line":136},15,[49,138,139],{},"     SelectionChanged=\"OnNavigationSelectionChanged\"\n",[49,141,143],{"class":51,"line":142},16,[49,144,145],{},"     TitleBar=\"{Binding ElementName=TitleBar, Mode=OneWay}\"\n",[49,147,149],{"class":51,"line":148},17,[49,150,151],{},"     Transition=\"FadeInWithSlide\">\n",[49,153,155],{"class":51,"line":154},18,[49,156,157],{},"     \u003Cui:NavigationView.Header>\n",[49,159,161],{"class":51,"line":160},19,[49,162,163],{},"         \u003CStackPanel Margin=\"42,32,42,20\">\n",[49,165,167],{"class":51,"line":166},20,[49,168,169],{},"             \u003Cui:BreadcrumbBar x:Name=\"BreadcrumbBar\" \u002F>\n",[49,171,173],{"class":51,"line":172},21,[49,174,175],{},"             \u003C!--\u003Ccontrols:PageControlDocumentation Margin=\"0,10,0,0\" NavigationView=\"{Binding ElementName=NavigationView}\" \u002F>-->\n",[49,177,179],{"class":51,"line":178},22,[49,180,181],{},"         \u003C\u002FStackPanel>\n",[49,183,185],{"class":51,"line":184},23,[49,186,187],{},"     \u003C\u002Fui:NavigationView.Header>\n",[49,189,191],{"class":51,"line":190},24,[49,192,194],{"emptyLinePlaceholder":193},true,"\n",[49,196,198],{"class":51,"line":197},25,[49,199,200],{},"     \u003Cui:NavigationView.AutoSuggestBox>\n",[49,202,204],{"class":51,"line":203},26,[49,205,206],{},"         \u003Cui:AutoSuggestBox x:Name=\"AutoSuggestBox\" PlaceholderText=\"{i18n:StringLocalizer 'Search'}\">\n",[49,208,210],{"class":51,"line":209},27,[49,211,212],{},"             \u003Cui:AutoSuggestBox.Icon>\n",[49,214,216],{"class":51,"line":215},28,[49,217,218],{},"                 \u003Cui:IconSourceElement>\n",[49,220,222],{"class":51,"line":221},29,[49,223,224],{},"                     \u003Cui:SymbolIconSource Symbol=\"Search24\" \u002F>\n",[49,226,228],{"class":51,"line":227},30,[49,229,230],{},"                 \u003C\u002Fui:IconSourceElement>\n",[49,232,234],{"class":51,"line":233},31,[49,235,236],{},"             \u003C\u002Fui:AutoSuggestBox.Icon>\n",[49,238,240],{"class":51,"line":239},32,[49,241,242],{},"         \u003C\u002Fui:AutoSuggestBox>\n",[49,244,246],{"class":51,"line":245},33,[49,247,248],{},"     \u003C\u002Fui:NavigationView.AutoSuggestBox>\n",[49,250,252],{"class":51,"line":251},34,[49,253,194],{"emptyLinePlaceholder":193},[49,255,257],{"class":51,"line":256},35,[49,258,259],{},"     \u003Cui:NavigationView.ContentOverlay>\n",[49,261,263],{"class":51,"line":262},36,[49,264,265],{},"         \u003CGrid>\n",[49,267,269],{"class":51,"line":268},37,[49,270,271],{},"             \u003Cui:SnackbarPresenter x:Name=\"SnackbarPresenter\" \u002F>\n",[49,273,275],{"class":51,"line":274},38,[49,276,277],{},"         \u003C\u002FGrid>\n",[49,279,281],{"class":51,"line":280},39,[49,282,283],{},"     \u003C\u002Fui:NavigationView.ContentOverlay>\n",[49,285,287],{"class":51,"line":286},40,[49,288,194],{"emptyLinePlaceholder":193},[49,290,292],{"class":51,"line":291},41,[49,293,294],{}," \u003C\u002Fui:NavigationView>\n",[35,296,298],{"id":297},"navigationview-详细解析","NavigationView 详细解析",[300,301,303],"h3",{"id":302},"_1-基本属性配置","1. 基本属性配置",[21,305,306],{},[25,307,308],{},"Padding=\"42,0,42,0\"",[310,311,312,316],"ul",{},[313,314,315],"li",{},"设置导航视图的内边距，左右各42像素，上下为0",[313,317,318],{},"这确保了内容与边缘有适当的间距，提供更好的视觉体验",[21,320,321],{},[25,322,323],{},"BreadcrumbBar=\"{Binding ElementName=BreadcrumbBar}\"",[310,325,326,332],{},[313,327,328,329],{},"绑定面包屑导航栏，用于显示当前",[25,330,331],{},"页面在导航层次结构中的位置",[313,333,334],{},"通过ElementName绑定到同名的BreadcrumbBar控件",[21,336,337],{},[25,338,339],{},"EnableDebugMessages=\"True\"",[310,341,342,345],{},[313,343,344],{},"启用调试消息，在开发阶段有助于排查问题",[313,346,347],{},"生产环境建议设置为False",[300,349,351],{"id":350},"_2-数据绑定配置","2. 数据绑定配置",[21,353,354],{},[25,355,356],{},"FooterMenuItemsSource=\"{Binding ViewModel.FooterMenuItems, Mode=OneWay}\"",[310,358,359,362,365],{},[313,360,361],{},"绑定底部菜单项数据源",[313,363,364],{},"OneWay模式表示数据从ViewModel流向UI，UI变化不会影响数据源",[313,366,367],{},"通常用于设置、帮助等固定菜单项",[21,369,370],{},[25,371,372],{},"MenuItemsSource=\"{Binding ViewModel.MenuItems, Mode=OneWay}\"",[310,374,375,378],{},[313,376,377],{},"绑定主导航菜单项数据源",[313,379,380],{},"这是导航视图的核心数据，包含所有可导航的页面项",[300,382,384],{"id":383},"_3-布局和显示控制","3. 布局和显示控制",[21,386,387],{},[25,388,389],{},"FrameMargin=\"0\"",[310,391,392],{},[313,393,394],{},"设置内容框架的边距为0，使内容占满整个可用空间",[21,396,397],{},[25,398,399],{},"IsBackButtonVisible=\"Visible\"",[310,401,402,405],{},[313,403,404],{},"显示返回按钮，允许用户返回到上一级页面，应该本质上就是个历史路由，他会记录每一次你路由的信息。",[313,406,407],{},"在导航层次结构中提供后退功能",[21,409,410],{},[25,411,412],{},"IsPaneToggleVisible=\"True\"",[310,414,415,418],{},[313,416,417],{},"显示面板切换按钮，允许用户展开\u002F收起侧边栏",[313,419,420],{},"提供更好的空间利用和用户体验",[21,422,423],{},[25,424,425],{},"OpenPaneLength=\"310\"",[310,427,428,431],{},[313,429,430],{},"设置侧边栏展开时的宽度为310像素，可自行调整。",[313,432,433],{},"这个宽度需要根据内容长度和设计需求来调整",[21,435,436],{},[25,437,438],{},"PaneDisplayMode=\"Left\"",[310,440,441,444],{},[313,442,443],{},"设置侧边栏显示在左侧",[313,445,446],{},"这是最常见的布局方式，符合用户习惯",[300,448,450],{"id":449},"_4-事件处理","4. 事件处理",[21,452,453],{},[25,454,455],{},"PaneClosed=\"NavigationView_OnPaneClosed\"",[310,457,458,461],{},[313,459,460],{},"侧边栏关闭时触发的事件处理程序",[313,462,463],{},"可以用于保存状态、更新UI等操作",[21,465,466],{},[25,467,468],{},"PaneOpened=\"NavigationView_OnPaneOpened\"",[310,470,471,474],{},[313,472,473],{},"侧边栏打开时触发的事件处理程序",[313,475,476],{},"可以用于加载数据、更新显示等操作",[21,478,479],{},[25,480,481],{},"SelectionChanged=\"OnNavigationSelectionChanged\"",[310,483,484,487],{},[313,485,486],{},"导航选择改变时触发的事件处理程序",[313,488,489],{},"这是导航功能的核心，用于处理页面切换逻辑",[300,491,493],{"id":492},"_5-标题栏和过渡效果","5. 标题栏和过渡效果",[21,495,496],{},[25,497,498],{},"TitleBar=\"{Binding ElementName=TitleBar, Mode=OneWay}\"",[310,500,501,504],{},[313,502,503],{},"绑定自定义标题栏控件",[313,505,506],{},"允许完全自定义标题栏的外观和行为",[21,508,509],{},[25,510,511],{},"Transition=\"FadeInWithSlide\"",[310,513,514,517],{},[313,515,516],{},"设置页面切换的过渡动画效果",[313,518,519],{},"FadeInWithSlide提供淡入和滑动效果，提升用户体验",[300,521,523],{"id":522},"_6-头部区域-header","6. 头部区域 (Header)",[10,525,527],{"className":43,"code":526,"language":45,"meta":19,"style":19},"\u003Cui:NavigationView.Header>\n    \u003CStackPanel Margin=\"42,32,42,20\">\n        \u003Cui:BreadcrumbBar x:Name=\"BreadcrumbBar\" \u002F>\n        \u003C!--\u003Ccontrols:PageControlDocumentation Margin=\"0,10,0,0\" NavigationView=\"{Binding ElementName=NavigationView}\" \u002F>-->\n    \u003C\u002FStackPanel>\n\u003C\u002Fui:NavigationView.Header>\n",[17,528,529,534,539,544,549,554],{"__ignoreMap":19},[49,530,531],{"class":51,"line":52},[49,532,533],{},"\u003Cui:NavigationView.Header>\n",[49,535,536],{"class":51,"line":58},[49,537,538],{},"    \u003CStackPanel Margin=\"42,32,42,20\">\n",[49,540,541],{"class":51,"line":64},[49,542,543],{},"        \u003Cui:BreadcrumbBar x:Name=\"BreadcrumbBar\" \u002F>\n",[49,545,546],{"class":51,"line":70},[49,547,548],{},"        \u003C!--\u003Ccontrols:PageControlDocumentation Margin=\"0,10,0,0\" NavigationView=\"{Binding ElementName=NavigationView}\" \u002F>-->\n",[49,550,551],{"class":51,"line":76},[49,552,553],{},"    \u003C\u002FStackPanel>\n",[49,555,556],{"class":51,"line":82},[49,557,558],{},"\u003C\u002Fui:NavigationView.Header>\n",[310,560,561,567,573,579],{},[313,562,563,566],{},[25,564,565],{},"StackPanel",": 垂直堆叠布局容器",[313,568,569,572],{},[25,570,571],{},"Margin=\"42,32,42,20\"",": 设置上下左右边距",[313,574,575,578],{},[25,576,577],{},"BreadcrumbBar",": 面包屑导航，显示当前页面路径",[313,580,581,584],{},[25,582,583],{},"注释部分",": 可能是文档控件，用于显示页面说明",[300,586,588],{"id":587},"_7-自动建议框-autosuggestbox","7. 自动建议框 (AutoSuggestBox)",[10,590,592],{"className":43,"code":591,"language":45,"meta":19,"style":19},"\u003Cui:NavigationView.AutoSuggestBox>\n    \u003Cui:AutoSuggestBox x:Name=\"AutoSuggestBox\" PlaceholderText=\"{i18n:StringLocalizer 'Search'}\">\n        \u003Cui:AutoSuggestBox.Icon>\n            \u003Cui:IconSourceElement>\n                \u003Cui:SymbolIconSource Symbol=\"Search24\" \u002F>\n            \u003C\u002Fui:IconSourceElement>\n        \u003C\u002Fui:AutoSuggestBox.Icon>\n    \u003C\u002Fui:AutoSuggestBox>\n\u003C\u002Fui:NavigationView.AutoSuggestBox>\n",[17,593,594,599,604,609,614,619,624,629,634],{"__ignoreMap":19},[49,595,596],{"class":51,"line":52},[49,597,598],{},"\u003Cui:NavigationView.AutoSuggestBox>\n",[49,600,601],{"class":51,"line":58},[49,602,603],{},"    \u003Cui:AutoSuggestBox x:Name=\"AutoSuggestBox\" PlaceholderText=\"{i18n:StringLocalizer 'Search'}\">\n",[49,605,606],{"class":51,"line":64},[49,607,608],{},"        \u003Cui:AutoSuggestBox.Icon>\n",[49,610,611],{"class":51,"line":70},[49,612,613],{},"            \u003Cui:IconSourceElement>\n",[49,615,616],{"class":51,"line":76},[49,617,618],{},"                \u003Cui:SymbolIconSource Symbol=\"Search24\" \u002F>\n",[49,620,621],{"class":51,"line":82},[49,622,623],{},"            \u003C\u002Fui:IconSourceElement>\n",[49,625,626],{"class":51,"line":88},[49,627,628],{},"        \u003C\u002Fui:AutoSuggestBox.Icon>\n",[49,630,631],{"class":51,"line":94},[49,632,633],{},"    \u003C\u002Fui:AutoSuggestBox>\n",[49,635,636],{"class":51,"line":100},[49,637,638],{},"\u003C\u002Fui:NavigationView.AutoSuggestBox>\n",[310,640,641,647,653],{},[313,642,643,646],{},[25,644,645],{},"PlaceholderText",": 使用国际化字符串本地化占位符文本",[313,648,649,652],{},[25,650,651],{},"Icon",": 设置搜索图标，使用SymbolIconSource提供统一的图标样式",[313,654,655,658],{},[25,656,657],{},"Symbol=\"Search24\"",": 使用24像素的搜索图标",[300,660,662],{"id":661},"_8-内容覆盖层-contentoverlay","8. 内容覆盖层 (ContentOverlay)",[10,664,666],{"className":43,"code":665,"language":45,"meta":19,"style":19},"\u003Cui:NavigationView.ContentOverlay>\n    \u003CGrid>\n        \u003Cui:SnackbarPresenter x:Name=\"SnackbarPresenter\" \u002F>\n    \u003C\u002FGrid>\n\u003C\u002Fui:NavigationView.ContentOverlay>\n",[17,667,668,673,678,683,688],{"__ignoreMap":19},[49,669,670],{"class":51,"line":52},[49,671,672],{},"\u003Cui:NavigationView.ContentOverlay>\n",[49,674,675],{"class":51,"line":58},[49,676,677],{},"    \u003CGrid>\n",[49,679,680],{"class":51,"line":64},[49,681,682],{},"        \u003Cui:SnackbarPresenter x:Name=\"SnackbarPresenter\" \u002F>\n",[49,684,685],{"class":51,"line":70},[49,686,687],{},"    \u003C\u002FGrid>\n",[49,689,690],{"class":51,"line":76},[49,691,692],{},"\u003C\u002Fui:NavigationView.ContentOverlay>\n",[310,694,695,701,707],{},[313,696,697,700],{},[25,698,699],{},"ContentOverlay",": 内容覆盖层，用于显示浮动在内容之上的UI元素",[313,702,703,706],{},[25,704,705],{},"SnackbarPresenter",": 消息提示组件，用于显示通知、警告等信息",[313,708,709],{},"这种设计允许在不影响主内容的情况下显示临时信息",[35,711,712],{"id":712},"实现原理总结",[714,715,716,722,728,734,740],"ol",{},[313,717,718,721],{},[25,719,720],{},"MVVM模式",": 通过数据绑定将UI与ViewModel分离，实现松耦合",[313,723,724,727],{},[25,725,726],{},"响应式设计",": 支持侧边栏展开\u002F收起，适应不同屏幕尺寸",[313,729,730,733],{},[25,731,732],{},"导航管理",": 通过SelectionChanged事件处理页面切换逻辑",[313,735,736,739],{},[25,737,738],{},"用户体验",": 提供过渡动画、面包屑导航、搜索功能等现代化交互",[313,741,742,745],{},[25,743,744],{},"可扩展性",": 通过绑定和事件处理，支持自定义扩展和功能增强",[21,747,748],{},"这种设计模式使得NavigationView成为一个功能完整、易于维护的现代化导航组件。",[21,750,751],{},"然后就是xaml.cs绑定的函数实例：",[10,753,757],{"className":754,"code":755,"language":756,"meta":19,"style":19},"language-csharp shiki shiki-themes github-light github-dark","using Animation.Pages.Dashboard;\nusing Microsoft.Extensions.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Forms;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Shapes;\nusing Wpf.Ui;\nusing Wpf.Ui.Controls;\n\nnamespace Animation.Pages.ToolWindow;\n\n\u002F\u002F\u002F \u003Csummary>\n\u002F\u002F\u002F ToolWindow.xaml 的交互逻辑\n\u002F\u002F\u002F \u003C\u002Fsummary>\npublic partial class ToolWindow : IWindow\n{\n    public ToolWindowViewModel ViewModel { get; }\n    private bool _isUserClosedPane;\n    private bool _isPaneOpenedOrClosedFromCode;\n\n\n    private void OnNavigationSelectionChanged(object sender, RoutedEventArgs e)\n    {\n        if (sender is not NavigationView navigationView)\n        {\n            return;\n        }\n\n        navigationView.SetCurrentValue(\n            NavigationView.HeaderVisibilityProperty,\n            navigationView.SelectedItem?.TargetPageType != typeof(DashboardPage)\n                ? Visibility.Visible\n                : Visibility.Collapsed\n        );\n    }\n\n    private void NavigationView_OnPaneOpened(NavigationView sender, RoutedEventArgs args)\n    {\n        if (_isPaneOpenedOrClosedFromCode)\n        {\n            return;\n        }\n\n        _isUserClosedPane = false;\n    }\n\n    private void NavigationView_OnPaneClosed(NavigationView sender, RoutedEventArgs args)\n    {\n        if (_isPaneOpenedOrClosedFromCode)\n        {\n            return;\n        }\n\n        _isUserClosedPane = true;\n    }\n\n    public ToolWindow(ToolWindowViewModel viewModel,INavigationService navigationService,IServiceProvider serviceProvider,\n        ISnackbarService snackbarService,IContentDialogService contentDialogService)\n    {\n        this.DataContext = this;\n        ViewModel = viewModel; \n\n        InitializeComponent();\n\n        snackbarService.SetSnackbarPresenter(SnackbarPresenter);\n        navigationService.SetNavigationControl(NavigationView);\n        contentDialogService.SetDialogHost(RootContentDialog);\n\n        \u002F\u002F 订阅窗口关闭事件\n        this.Loaded += ToolWindow_Loaded;\n        this.Closed += ToolWindow_Closed;\n\n    }\n\n    private void ToolWindow_Loaded(object sender, RoutedEventArgs e)\n    { \n       this.NavigationView.Navigate(typeof(DashboardPage));\n    }\n    \n    private void ToolWindow_Closed(object sender, EventArgs e)\n    {\n        \u002F\u002F 当ToolWindow关闭时，显示MainWindow\n        try\n        {\n            Dispatcher.BeginInvoke(new Action(() =>\n            {\n                if (App.MainWindow != null && !App.MainWindow.IsVisible)\n                {\n                    App.MainWindow.Show();\n                    App.MainWindow.Activate(); \u002F\u002F 激活窗口并置于前台\n                }\n            }), System.Windows.Threading.DispatcherPriority.Background);\n        }\n        catch (Exception ex)\n        {\n            \u002F\u002F 处理错误，可以记录日志或显示错误消息\n            Console.WriteLine($\"Failed to show MainWindow: {ex.Message}\");\n        }\n    }\n}\n\n","csharp",[17,758,759,764,769,774,779,784,789,794,799,804,809,814,819,824,829,834,839,844,849,853,858,862,867,872,877,882,887,892,897,902,906,910,915,920,925,930,935,940,944,949,954,959,965,971,977,983,988,994,999,1005,1010,1015,1020,1025,1031,1036,1041,1047,1052,1057,1062,1067,1072,1077,1083,1088,1093,1099,1105,1110,1116,1122,1127,1133,1138,1144,1150,1156,1161,1167,1173,1179,1184,1189,1194,1200,1206,1212,1217,1223,1229,1234,1240,1246,1251,1257,1263,1269,1275,1281,1287,1293,1299,1304,1310,1315,1321,1327,1332,1337],{"__ignoreMap":19},[49,760,761],{"class":51,"line":52},[49,762,763],{},"using Animation.Pages.Dashboard;\n",[49,765,766],{"class":51,"line":58},[49,767,768],{},"using Microsoft.Extensions.DependencyInjection;\n",[49,770,771],{"class":51,"line":64},[49,772,773],{},"using System;\n",[49,775,776],{"class":51,"line":70},[49,777,778],{},"using System.Collections.Generic;\n",[49,780,781],{"class":51,"line":76},[49,782,783],{},"using System.Linq;\n",[49,785,786],{"class":51,"line":82},[49,787,788],{},"using System.Text;\n",[49,790,791],{"class":51,"line":88},[49,792,793],{},"using System.Threading.Tasks;\n",[49,795,796],{"class":51,"line":94},[49,797,798],{},"using System.Windows;\n",[49,800,801],{"class":51,"line":100},[49,802,803],{},"using System.Windows.Controls;\n",[49,805,806],{"class":51,"line":106},[49,807,808],{},"using System.Windows.Data;\n",[49,810,811],{"class":51,"line":112},[49,812,813],{},"using System.Windows.Documents;\n",[49,815,816],{"class":51,"line":118},[49,817,818],{},"using System.Windows.Forms;\n",[49,820,821],{"class":51,"line":124},[49,822,823],{},"using System.Windows.Input;\n",[49,825,826],{"class":51,"line":130},[49,827,828],{},"using System.Windows.Media;\n",[49,830,831],{"class":51,"line":136},[49,832,833],{},"using System.Windows.Media.Imaging;\n",[49,835,836],{"class":51,"line":142},[49,837,838],{},"using System.Windows.Shapes;\n",[49,840,841],{"class":51,"line":148},[49,842,843],{},"using Wpf.Ui;\n",[49,845,846],{"class":51,"line":154},[49,847,848],{},"using Wpf.Ui.Controls;\n",[49,850,851],{"class":51,"line":160},[49,852,194],{"emptyLinePlaceholder":193},[49,854,855],{"class":51,"line":166},[49,856,857],{},"namespace Animation.Pages.ToolWindow;\n",[49,859,860],{"class":51,"line":172},[49,861,194],{"emptyLinePlaceholder":193},[49,863,864],{"class":51,"line":178},[49,865,866],{},"\u002F\u002F\u002F \u003Csummary>\n",[49,868,869],{"class":51,"line":184},[49,870,871],{},"\u002F\u002F\u002F ToolWindow.xaml 的交互逻辑\n",[49,873,874],{"class":51,"line":190},[49,875,876],{},"\u002F\u002F\u002F \u003C\u002Fsummary>\n",[49,878,879],{"class":51,"line":197},[49,880,881],{},"public partial class ToolWindow : IWindow\n",[49,883,884],{"class":51,"line":203},[49,885,886],{},"{\n",[49,888,889],{"class":51,"line":209},[49,890,891],{},"    public ToolWindowViewModel ViewModel { get; }\n",[49,893,894],{"class":51,"line":215},[49,895,896],{},"    private bool _isUserClosedPane;\n",[49,898,899],{"class":51,"line":221},[49,900,901],{},"    private bool _isPaneOpenedOrClosedFromCode;\n",[49,903,904],{"class":51,"line":227},[49,905,194],{"emptyLinePlaceholder":193},[49,907,908],{"class":51,"line":233},[49,909,194],{"emptyLinePlaceholder":193},[49,911,912],{"class":51,"line":239},[49,913,914],{},"    private void OnNavigationSelectionChanged(object sender, RoutedEventArgs e)\n",[49,916,917],{"class":51,"line":245},[49,918,919],{},"    {\n",[49,921,922],{"class":51,"line":251},[49,923,924],{},"        if (sender is not NavigationView navigationView)\n",[49,926,927],{"class":51,"line":256},[49,928,929],{},"        {\n",[49,931,932],{"class":51,"line":262},[49,933,934],{},"            return;\n",[49,936,937],{"class":51,"line":268},[49,938,939],{},"        }\n",[49,941,942],{"class":51,"line":274},[49,943,194],{"emptyLinePlaceholder":193},[49,945,946],{"class":51,"line":280},[49,947,948],{},"        navigationView.SetCurrentValue(\n",[49,950,951],{"class":51,"line":286},[49,952,953],{},"            NavigationView.HeaderVisibilityProperty,\n",[49,955,956],{"class":51,"line":291},[49,957,958],{},"            navigationView.SelectedItem?.TargetPageType != typeof(DashboardPage)\n",[49,960,962],{"class":51,"line":961},42,[49,963,964],{},"                ? Visibility.Visible\n",[49,966,968],{"class":51,"line":967},43,[49,969,970],{},"                : Visibility.Collapsed\n",[49,972,974],{"class":51,"line":973},44,[49,975,976],{},"        );\n",[49,978,980],{"class":51,"line":979},45,[49,981,982],{},"    }\n",[49,984,986],{"class":51,"line":985},46,[49,987,194],{"emptyLinePlaceholder":193},[49,989,991],{"class":51,"line":990},47,[49,992,993],{},"    private void NavigationView_OnPaneOpened(NavigationView sender, RoutedEventArgs args)\n",[49,995,997],{"class":51,"line":996},48,[49,998,919],{},[49,1000,1002],{"class":51,"line":1001},49,[49,1003,1004],{},"        if (_isPaneOpenedOrClosedFromCode)\n",[49,1006,1008],{"class":51,"line":1007},50,[49,1009,929],{},[49,1011,1013],{"class":51,"line":1012},51,[49,1014,934],{},[49,1016,1018],{"class":51,"line":1017},52,[49,1019,939],{},[49,1021,1023],{"class":51,"line":1022},53,[49,1024,194],{"emptyLinePlaceholder":193},[49,1026,1028],{"class":51,"line":1027},54,[49,1029,1030],{},"        _isUserClosedPane = false;\n",[49,1032,1034],{"class":51,"line":1033},55,[49,1035,982],{},[49,1037,1039],{"class":51,"line":1038},56,[49,1040,194],{"emptyLinePlaceholder":193},[49,1042,1044],{"class":51,"line":1043},57,[49,1045,1046],{},"    private void NavigationView_OnPaneClosed(NavigationView sender, RoutedEventArgs args)\n",[49,1048,1050],{"class":51,"line":1049},58,[49,1051,919],{},[49,1053,1055],{"class":51,"line":1054},59,[49,1056,1004],{},[49,1058,1060],{"class":51,"line":1059},60,[49,1061,929],{},[49,1063,1065],{"class":51,"line":1064},61,[49,1066,934],{},[49,1068,1070],{"class":51,"line":1069},62,[49,1071,939],{},[49,1073,1075],{"class":51,"line":1074},63,[49,1076,194],{"emptyLinePlaceholder":193},[49,1078,1080],{"class":51,"line":1079},64,[49,1081,1082],{},"        _isUserClosedPane = true;\n",[49,1084,1086],{"class":51,"line":1085},65,[49,1087,982],{},[49,1089,1091],{"class":51,"line":1090},66,[49,1092,194],{"emptyLinePlaceholder":193},[49,1094,1096],{"class":51,"line":1095},67,[49,1097,1098],{},"    public ToolWindow(ToolWindowViewModel viewModel,INavigationService navigationService,IServiceProvider serviceProvider,\n",[49,1100,1102],{"class":51,"line":1101},68,[49,1103,1104],{},"        ISnackbarService snackbarService,IContentDialogService contentDialogService)\n",[49,1106,1108],{"class":51,"line":1107},69,[49,1109,919],{},[49,1111,1113],{"class":51,"line":1112},70,[49,1114,1115],{},"        this.DataContext = this;\n",[49,1117,1119],{"class":51,"line":1118},71,[49,1120,1121],{},"        ViewModel = viewModel; \n",[49,1123,1125],{"class":51,"line":1124},72,[49,1126,194],{"emptyLinePlaceholder":193},[49,1128,1130],{"class":51,"line":1129},73,[49,1131,1132],{},"        InitializeComponent();\n",[49,1134,1136],{"class":51,"line":1135},74,[49,1137,194],{"emptyLinePlaceholder":193},[49,1139,1141],{"class":51,"line":1140},75,[49,1142,1143],{},"        snackbarService.SetSnackbarPresenter(SnackbarPresenter);\n",[49,1145,1147],{"class":51,"line":1146},76,[49,1148,1149],{},"        navigationService.SetNavigationControl(NavigationView);\n",[49,1151,1153],{"class":51,"line":1152},77,[49,1154,1155],{},"        contentDialogService.SetDialogHost(RootContentDialog);\n",[49,1157,1159],{"class":51,"line":1158},78,[49,1160,194],{"emptyLinePlaceholder":193},[49,1162,1164],{"class":51,"line":1163},79,[49,1165,1166],{},"        \u002F\u002F 订阅窗口关闭事件\n",[49,1168,1170],{"class":51,"line":1169},80,[49,1171,1172],{},"        this.Loaded += ToolWindow_Loaded;\n",[49,1174,1176],{"class":51,"line":1175},81,[49,1177,1178],{},"        this.Closed += ToolWindow_Closed;\n",[49,1180,1182],{"class":51,"line":1181},82,[49,1183,194],{"emptyLinePlaceholder":193},[49,1185,1187],{"class":51,"line":1186},83,[49,1188,982],{},[49,1190,1192],{"class":51,"line":1191},84,[49,1193,194],{"emptyLinePlaceholder":193},[49,1195,1197],{"class":51,"line":1196},85,[49,1198,1199],{},"    private void ToolWindow_Loaded(object sender, RoutedEventArgs e)\n",[49,1201,1203],{"class":51,"line":1202},86,[49,1204,1205],{},"    { \n",[49,1207,1209],{"class":51,"line":1208},87,[49,1210,1211],{},"       this.NavigationView.Navigate(typeof(DashboardPage));\n",[49,1213,1215],{"class":51,"line":1214},88,[49,1216,982],{},[49,1218,1220],{"class":51,"line":1219},89,[49,1221,1222],{},"    \n",[49,1224,1226],{"class":51,"line":1225},90,[49,1227,1228],{},"    private void ToolWindow_Closed(object sender, EventArgs e)\n",[49,1230,1232],{"class":51,"line":1231},91,[49,1233,919],{},[49,1235,1237],{"class":51,"line":1236},92,[49,1238,1239],{},"        \u002F\u002F 当ToolWindow关闭时，显示MainWindow\n",[49,1241,1243],{"class":51,"line":1242},93,[49,1244,1245],{},"        try\n",[49,1247,1249],{"class":51,"line":1248},94,[49,1250,929],{},[49,1252,1254],{"class":51,"line":1253},95,[49,1255,1256],{},"            Dispatcher.BeginInvoke(new Action(() =>\n",[49,1258,1260],{"class":51,"line":1259},96,[49,1261,1262],{},"            {\n",[49,1264,1266],{"class":51,"line":1265},97,[49,1267,1268],{},"                if (App.MainWindow != null && !App.MainWindow.IsVisible)\n",[49,1270,1272],{"class":51,"line":1271},98,[49,1273,1274],{},"                {\n",[49,1276,1278],{"class":51,"line":1277},99,[49,1279,1280],{},"                    App.MainWindow.Show();\n",[49,1282,1284],{"class":51,"line":1283},100,[49,1285,1286],{},"                    App.MainWindow.Activate(); \u002F\u002F 激活窗口并置于前台\n",[49,1288,1290],{"class":51,"line":1289},101,[49,1291,1292],{},"                }\n",[49,1294,1296],{"class":51,"line":1295},102,[49,1297,1298],{},"            }), System.Windows.Threading.DispatcherPriority.Background);\n",[49,1300,1302],{"class":51,"line":1301},103,[49,1303,939],{},[49,1305,1307],{"class":51,"line":1306},104,[49,1308,1309],{},"        catch (Exception ex)\n",[49,1311,1313],{"class":51,"line":1312},105,[49,1314,929],{},[49,1316,1318],{"class":51,"line":1317},106,[49,1319,1320],{},"            \u002F\u002F 处理错误，可以记录日志或显示错误消息\n",[49,1322,1324],{"class":51,"line":1323},107,[49,1325,1326],{},"            Console.WriteLine($\"Failed to show MainWindow: {ex.Message}\");\n",[49,1328,1330],{"class":51,"line":1329},108,[49,1331,939],{},[49,1333,1335],{"class":51,"line":1334},109,[49,1336,982],{},[49,1338,1340],{"class":51,"line":1339},110,[49,1341,1342],{},"}\n",[21,1344,1345,1346,1349],{},"​\t然后是数据业务逻辑层面的ViewModel代码，里面定义了路由的测栏内容等信息。当然如果是为了方便你可以用另一种方式躲避每一次的手动注册，使用",[25,1347,1348],{},"程序集反射加载","实现了对应接口的页面，然后返回封装成列表",[10,1351,1353],{"className":754,"code":1352,"language":756,"meta":19,"style":19},"using Animation.Pages.ColorCollecter;\nusing Animation.Pages.Dashboard;\nusing Animation.Res;\nusing CommunityToolkit.Mvvm.ComponentModel;\nusing Microsoft.Extensions.Localization;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing Wpf.Ui.Controls;\n\nnamespace Animation.Pages.ToolWindow;\n\npublic partial class ToolWindowViewModel(IStringLocalizer\u003CTranslation> localizer) : ViewModel\n{\n    [ObservableProperty]\n    private string title = localizer[\"toolbox\"];\n\n    [ObservableProperty]\n    private string description = localizer[\"toolbox_description\"];\n\n    #region 定义菜单栏\n    [ObservableProperty]\n    private ObservableCollection\u003Cobject> _menuItems = [\n        new NavigationViewItem(\"Home\",SymbolRegular.Home24,typeof(DashboardPage)),\n        new NavigationViewItem(\"Color采集\",SymbolRegular.Color24,typeof(ColorCollecterPage)),\n        ];\n    #endregion\n\n}\n\n",[17,1354,1355,1360,1364,1369,1374,1379,1383,1387,1392,1396,1400,1404,1408,1412,1416,1420,1424,1429,1433,1438,1443,1447,1451,1456,1460,1465,1469,1474,1479,1484,1489,1494,1498],{"__ignoreMap":19},[49,1356,1357],{"class":51,"line":52},[49,1358,1359],{},"using Animation.Pages.ColorCollecter;\n",[49,1361,1362],{"class":51,"line":58},[49,1363,763],{},[49,1365,1366],{"class":51,"line":64},[49,1367,1368],{},"using Animation.Res;\n",[49,1370,1371],{"class":51,"line":70},[49,1372,1373],{},"using CommunityToolkit.Mvvm.ComponentModel;\n",[49,1375,1376],{"class":51,"line":76},[49,1377,1378],{},"using Microsoft.Extensions.Localization;\n",[49,1380,1381],{"class":51,"line":82},[49,1382,773],{},[49,1384,1385],{"class":51,"line":88},[49,1386,778],{},[49,1388,1389],{"class":51,"line":94},[49,1390,1391],{},"using System.Collections.ObjectModel;\n",[49,1393,1394],{"class":51,"line":100},[49,1395,783],{},[49,1397,1398],{"class":51,"line":106},[49,1399,788],{},[49,1401,1402],{"class":51,"line":112},[49,1403,793],{},[49,1405,1406],{"class":51,"line":118},[49,1407,798],{},[49,1409,1410],{"class":51,"line":124},[49,1411,848],{},[49,1413,1414],{"class":51,"line":130},[49,1415,194],{"emptyLinePlaceholder":193},[49,1417,1418],{"class":51,"line":136},[49,1419,857],{},[49,1421,1422],{"class":51,"line":142},[49,1423,194],{"emptyLinePlaceholder":193},[49,1425,1426],{"class":51,"line":148},[49,1427,1428],{},"public partial class ToolWindowViewModel(IStringLocalizer\u003CTranslation> localizer) : ViewModel\n",[49,1430,1431],{"class":51,"line":154},[49,1432,886],{},[49,1434,1435],{"class":51,"line":160},[49,1436,1437],{},"    [ObservableProperty]\n",[49,1439,1440],{"class":51,"line":166},[49,1441,1442],{},"    private string title = localizer[\"toolbox\"];\n",[49,1444,1445],{"class":51,"line":172},[49,1446,194],{"emptyLinePlaceholder":193},[49,1448,1449],{"class":51,"line":178},[49,1450,1437],{},[49,1452,1453],{"class":51,"line":184},[49,1454,1455],{},"    private string description = localizer[\"toolbox_description\"];\n",[49,1457,1458],{"class":51,"line":190},[49,1459,194],{"emptyLinePlaceholder":193},[49,1461,1462],{"class":51,"line":197},[49,1463,1464],{},"    #region 定义菜单栏\n",[49,1466,1467],{"class":51,"line":203},[49,1468,1437],{},[49,1470,1471],{"class":51,"line":209},[49,1472,1473],{},"    private ObservableCollection\u003Cobject> _menuItems = [\n",[49,1475,1476],{"class":51,"line":215},[49,1477,1478],{},"        new NavigationViewItem(\"Home\",SymbolRegular.Home24,typeof(DashboardPage)),\n",[49,1480,1481],{"class":51,"line":221},[49,1482,1483],{},"        new NavigationViewItem(\"Color采集\",SymbolRegular.Color24,typeof(ColorCollecterPage)),\n",[49,1485,1486],{"class":51,"line":227},[49,1487,1488],{},"        ];\n",[49,1490,1491],{"class":51,"line":233},[49,1492,1493],{},"    #endregion\n",[49,1495,1496],{"class":51,"line":239},[49,1497,194],{"emptyLinePlaceholder":193},[49,1499,1500],{"class":51,"line":245},[49,1501,1342],{},[35,1503,1504],{"id":1504},"重写组件实现自定义",[21,1506,1507,1508,1511,1512,1515],{},"​\t因为默认的ItemsPanel 因此我决定重写组件实现包装WrapPanel。",[25,1509,1510],{},"ItemsControl 默认使用 StackPanel 作为 ItemsPanel","，这会覆盖我们在 XAML 中设置的 WrapPanel。",[25,1513,1514],{},"即使我们在 XAML 中设置了 WrapPanel，ItemsControl 仍然会使用默认的 StackPanel","。",[21,1517,1518],{},"下面是代码的全部：",[10,1520,1522],{"className":754,"code":1521,"language":756,"meta":19,"style":19},"static ColorStackContent()\n    {\n        DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorStackContent), new FrameworkPropertyMetadata(typeof(ColorStackContent)));\n        \n        \u002F\u002F 设置默认的ItemsPanel为WrapPanel\n        ItemsPanelProperty.OverrideMetadata(typeof(ColorStackContent), \n            new FrameworkPropertyMetadata(CreateDefaultItemsPanel()));\n    }\n    \n    private static ItemsPanelTemplate CreateDefaultItemsPanel()\n    {\n        var template = new ItemsPanelTemplate();\n        var factory = new FrameworkElementFactory(typeof(WrapPanel));\n        template.VisualTree = factory;\n        return template;\n    }\n\n    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)\n    {\n        base.PrepareContainerForItemOverride(element, item);\n\n        if (element is ContentPresenter presenter)\n        {\n            \u002F\u002F 将字符串转换为Color\n            Color color;\n            if (item is string colorString)\n            {\n                try\n                {\n                    color = (Color)ColorConverter.ConvertFromString(colorString);\n                }\n                catch\n                {\n                    color = Colors.Gray; \u002F\u002F 如果转换失败，使用默认颜色\n                }\n            }\n            else\n            {\n                color = Colors.Gray; \u002F\u002F 如果不是字符串，使用默认颜色\n            }\n\n            \u002F\u002F 创建带有动画效果的Border\n            var border = new Border\n            {\n                CornerRadius = new CornerRadius(8),\n                Height = 50,\n                Width = 50,\n                Background = new SolidColorBrush(color),\n                BorderBrush = Brushes.Black,\n                BorderThickness = new Thickness(1),\n                Margin = new Thickness(5),\n                Effect = null \u002F\u002F 初始无阴影\n            };\n\n            \u002F\u002F 创建阴影效果\n            var shadowEffect = new System.Windows.Media.Effects.DropShadowEffect\n            {\n                Color = Colors.Black,\n                Direction = 315,\n                ShadowDepth = 0,\n                BlurRadius = 0,\n                Opacity = 0\n            };\n\n            \u002F\u002F 创建动画\n            var shadowAnimation = new DoubleAnimation\n            {\n                To = 8,\n                Duration = TimeSpan.FromMilliseconds(200),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }\n            };\n\n            var blurAnimation = new DoubleAnimation\n            {\n                To = 10,\n                Duration = TimeSpan.FromMilliseconds(200),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }\n            };\n\n            var opacityAnimation = new DoubleAnimation\n            {\n                To = 0.5,\n                Duration = TimeSpan.FromMilliseconds(200),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }\n            };\n\n            \u002F\u002F 反向动画（鼠标离开时）\n            var shadowAnimationOut = new DoubleAnimation\n            {\n                To = 0,\n                Duration = TimeSpan.FromMilliseconds(150),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }\n            };\n\n            var blurAnimationOut = new DoubleAnimation\n            {\n                To = 0,\n                Duration = TimeSpan.FromMilliseconds(150),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }\n            };\n\n            var opacityAnimationOut = new DoubleAnimation\n            {\n                To = 0,\n                Duration = TimeSpan.FromMilliseconds(150),\n                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }\n            };\n\n            \u002F\u002F 设置阴影效果\n            border.Effect = shadowEffect;\n\n            \u002F\u002F 鼠标进入事件\n            border.MouseEnter += (s, e) =>\n            {\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.ShadowDepthProperty, shadowAnimation);\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.BlurRadiusProperty, blurAnimation);\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.OpacityProperty, opacityAnimation);\n            };\n\n            \u002F\u002F 鼠标离开事件\n            border.MouseLeave += (s, e) =>\n            {\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.ShadowDepthProperty, shadowAnimationOut);\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.BlurRadiusProperty, blurAnimationOut);\n                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.OpacityProperty, opacityAnimationOut);\n            };\n\n            \u002F\u002F 创建包含颜色名称的StackPanel\n            var stackPanel = new StackPanel\n            {\n                Orientation = Orientation.Horizontal,\n                HorizontalAlignment = HorizontalAlignment.Left,\n                VerticalAlignment = VerticalAlignment.Top,\n                Margin = new Thickness(5)\n            };\n\n            stackPanel.Children.Add(border);\n\n            var textBlock = new TextBlock\n            {\n                Text = item.ToString(),\n                VerticalAlignment = VerticalAlignment.Center,\n                Margin = new Thickness(5, 0, 0, 0),\n                Foreground = Brushes.White\n            };\n\n            stackPanel.Children.Add(textBlock);\n\n            presenter.Content = stackPanel;\n        }\n    }\n",[17,1523,1524,1529,1533,1538,1543,1548,1553,1558,1562,1566,1571,1575,1580,1585,1590,1595,1599,1603,1608,1612,1617,1621,1626,1630,1635,1640,1645,1649,1654,1658,1663,1667,1672,1676,1681,1685,1690,1695,1699,1704,1708,1712,1717,1722,1726,1731,1736,1741,1746,1751,1756,1761,1766,1771,1775,1780,1785,1789,1794,1799,1804,1809,1814,1818,1822,1827,1832,1836,1841,1846,1851,1855,1859,1864,1868,1873,1877,1881,1885,1889,1894,1898,1903,1907,1911,1915,1919,1924,1929,1933,1938,1943,1948,1952,1956,1961,1965,1969,1973,1977,1981,1985,1990,1994,1998,2002,2006,2010,2014,2019,2024,2029,2035,2041,2046,2052,2058,2064,2069,2074,2080,2086,2091,2097,2103,2109,2114,2119,2125,2131,2136,2142,2148,2154,2160,2165,2170,2176,2181,2187,2192,2198,2204,2210,2216,2221,2226,2232,2237,2243,2248],{"__ignoreMap":19},[49,1525,1526],{"class":51,"line":52},[49,1527,1528],{},"static ColorStackContent()\n",[49,1530,1531],{"class":51,"line":58},[49,1532,919],{},[49,1534,1535],{"class":51,"line":64},[49,1536,1537],{},"        DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorStackContent), new FrameworkPropertyMetadata(typeof(ColorStackContent)));\n",[49,1539,1540],{"class":51,"line":70},[49,1541,1542],{},"        \n",[49,1544,1545],{"class":51,"line":76},[49,1546,1547],{},"        \u002F\u002F 设置默认的ItemsPanel为WrapPanel\n",[49,1549,1550],{"class":51,"line":82},[49,1551,1552],{},"        ItemsPanelProperty.OverrideMetadata(typeof(ColorStackContent), \n",[49,1554,1555],{"class":51,"line":88},[49,1556,1557],{},"            new FrameworkPropertyMetadata(CreateDefaultItemsPanel()));\n",[49,1559,1560],{"class":51,"line":94},[49,1561,982],{},[49,1563,1564],{"class":51,"line":100},[49,1565,1222],{},[49,1567,1568],{"class":51,"line":106},[49,1569,1570],{},"    private static ItemsPanelTemplate CreateDefaultItemsPanel()\n",[49,1572,1573],{"class":51,"line":112},[49,1574,919],{},[49,1576,1577],{"class":51,"line":118},[49,1578,1579],{},"        var template = new ItemsPanelTemplate();\n",[49,1581,1582],{"class":51,"line":124},[49,1583,1584],{},"        var factory = new FrameworkElementFactory(typeof(WrapPanel));\n",[49,1586,1587],{"class":51,"line":130},[49,1588,1589],{},"        template.VisualTree = factory;\n",[49,1591,1592],{"class":51,"line":136},[49,1593,1594],{},"        return template;\n",[49,1596,1597],{"class":51,"line":142},[49,1598,982],{},[49,1600,1601],{"class":51,"line":148},[49,1602,194],{"emptyLinePlaceholder":193},[49,1604,1605],{"class":51,"line":154},[49,1606,1607],{},"    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)\n",[49,1609,1610],{"class":51,"line":160},[49,1611,919],{},[49,1613,1614],{"class":51,"line":166},[49,1615,1616],{},"        base.PrepareContainerForItemOverride(element, item);\n",[49,1618,1619],{"class":51,"line":172},[49,1620,194],{"emptyLinePlaceholder":193},[49,1622,1623],{"class":51,"line":178},[49,1624,1625],{},"        if (element is ContentPresenter presenter)\n",[49,1627,1628],{"class":51,"line":184},[49,1629,929],{},[49,1631,1632],{"class":51,"line":190},[49,1633,1634],{},"            \u002F\u002F 将字符串转换为Color\n",[49,1636,1637],{"class":51,"line":197},[49,1638,1639],{},"            Color color;\n",[49,1641,1642],{"class":51,"line":203},[49,1643,1644],{},"            if (item is string colorString)\n",[49,1646,1647],{"class":51,"line":209},[49,1648,1262],{},[49,1650,1651],{"class":51,"line":215},[49,1652,1653],{},"                try\n",[49,1655,1656],{"class":51,"line":221},[49,1657,1274],{},[49,1659,1660],{"class":51,"line":227},[49,1661,1662],{},"                    color = (Color)ColorConverter.ConvertFromString(colorString);\n",[49,1664,1665],{"class":51,"line":233},[49,1666,1292],{},[49,1668,1669],{"class":51,"line":239},[49,1670,1671],{},"                catch\n",[49,1673,1674],{"class":51,"line":245},[49,1675,1274],{},[49,1677,1678],{"class":51,"line":251},[49,1679,1680],{},"                    color = Colors.Gray; \u002F\u002F 如果转换失败，使用默认颜色\n",[49,1682,1683],{"class":51,"line":256},[49,1684,1292],{},[49,1686,1687],{"class":51,"line":262},[49,1688,1689],{},"            }\n",[49,1691,1692],{"class":51,"line":268},[49,1693,1694],{},"            else\n",[49,1696,1697],{"class":51,"line":274},[49,1698,1262],{},[49,1700,1701],{"class":51,"line":280},[49,1702,1703],{},"                color = Colors.Gray; \u002F\u002F 如果不是字符串，使用默认颜色\n",[49,1705,1706],{"class":51,"line":286},[49,1707,1689],{},[49,1709,1710],{"class":51,"line":291},[49,1711,194],{"emptyLinePlaceholder":193},[49,1713,1714],{"class":51,"line":961},[49,1715,1716],{},"            \u002F\u002F 创建带有动画效果的Border\n",[49,1718,1719],{"class":51,"line":967},[49,1720,1721],{},"            var border = new Border\n",[49,1723,1724],{"class":51,"line":973},[49,1725,1262],{},[49,1727,1728],{"class":51,"line":979},[49,1729,1730],{},"                CornerRadius = new CornerRadius(8),\n",[49,1732,1733],{"class":51,"line":985},[49,1734,1735],{},"                Height = 50,\n",[49,1737,1738],{"class":51,"line":990},[49,1739,1740],{},"                Width = 50,\n",[49,1742,1743],{"class":51,"line":996},[49,1744,1745],{},"                Background = new SolidColorBrush(color),\n",[49,1747,1748],{"class":51,"line":1001},[49,1749,1750],{},"                BorderBrush = Brushes.Black,\n",[49,1752,1753],{"class":51,"line":1007},[49,1754,1755],{},"                BorderThickness = new Thickness(1),\n",[49,1757,1758],{"class":51,"line":1012},[49,1759,1760],{},"                Margin = new Thickness(5),\n",[49,1762,1763],{"class":51,"line":1017},[49,1764,1765],{},"                Effect = null \u002F\u002F 初始无阴影\n",[49,1767,1768],{"class":51,"line":1022},[49,1769,1770],{},"            };\n",[49,1772,1773],{"class":51,"line":1027},[49,1774,194],{"emptyLinePlaceholder":193},[49,1776,1777],{"class":51,"line":1033},[49,1778,1779],{},"            \u002F\u002F 创建阴影效果\n",[49,1781,1782],{"class":51,"line":1038},[49,1783,1784],{},"            var shadowEffect = new System.Windows.Media.Effects.DropShadowEffect\n",[49,1786,1787],{"class":51,"line":1043},[49,1788,1262],{},[49,1790,1791],{"class":51,"line":1049},[49,1792,1793],{},"                Color = Colors.Black,\n",[49,1795,1796],{"class":51,"line":1054},[49,1797,1798],{},"                Direction = 315,\n",[49,1800,1801],{"class":51,"line":1059},[49,1802,1803],{},"                ShadowDepth = 0,\n",[49,1805,1806],{"class":51,"line":1064},[49,1807,1808],{},"                BlurRadius = 0,\n",[49,1810,1811],{"class":51,"line":1069},[49,1812,1813],{},"                Opacity = 0\n",[49,1815,1816],{"class":51,"line":1074},[49,1817,1770],{},[49,1819,1820],{"class":51,"line":1079},[49,1821,194],{"emptyLinePlaceholder":193},[49,1823,1824],{"class":51,"line":1085},[49,1825,1826],{},"            \u002F\u002F 创建动画\n",[49,1828,1829],{"class":51,"line":1090},[49,1830,1831],{},"            var shadowAnimation = new DoubleAnimation\n",[49,1833,1834],{"class":51,"line":1095},[49,1835,1262],{},[49,1837,1838],{"class":51,"line":1101},[49,1839,1840],{},"                To = 8,\n",[49,1842,1843],{"class":51,"line":1107},[49,1844,1845],{},"                Duration = TimeSpan.FromMilliseconds(200),\n",[49,1847,1848],{"class":51,"line":1112},[49,1849,1850],{},"                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }\n",[49,1852,1853],{"class":51,"line":1118},[49,1854,1770],{},[49,1856,1857],{"class":51,"line":1124},[49,1858,194],{"emptyLinePlaceholder":193},[49,1860,1861],{"class":51,"line":1129},[49,1862,1863],{},"            var blurAnimation = new DoubleAnimation\n",[49,1865,1866],{"class":51,"line":1135},[49,1867,1262],{},[49,1869,1870],{"class":51,"line":1140},[49,1871,1872],{},"                To = 10,\n",[49,1874,1875],{"class":51,"line":1146},[49,1876,1845],{},[49,1878,1879],{"class":51,"line":1152},[49,1880,1850],{},[49,1882,1883],{"class":51,"line":1158},[49,1884,1770],{},[49,1886,1887],{"class":51,"line":1163},[49,1888,194],{"emptyLinePlaceholder":193},[49,1890,1891],{"class":51,"line":1169},[49,1892,1893],{},"            var opacityAnimation = new DoubleAnimation\n",[49,1895,1896],{"class":51,"line":1175},[49,1897,1262],{},[49,1899,1900],{"class":51,"line":1181},[49,1901,1902],{},"                To = 0.5,\n",[49,1904,1905],{"class":51,"line":1186},[49,1906,1845],{},[49,1908,1909],{"class":51,"line":1191},[49,1910,1850],{},[49,1912,1913],{"class":51,"line":1196},[49,1914,1770],{},[49,1916,1917],{"class":51,"line":1202},[49,1918,194],{"emptyLinePlaceholder":193},[49,1920,1921],{"class":51,"line":1208},[49,1922,1923],{},"            \u002F\u002F 反向动画（鼠标离开时）\n",[49,1925,1926],{"class":51,"line":1214},[49,1927,1928],{},"            var shadowAnimationOut = new DoubleAnimation\n",[49,1930,1931],{"class":51,"line":1219},[49,1932,1262],{},[49,1934,1935],{"class":51,"line":1225},[49,1936,1937],{},"                To = 0,\n",[49,1939,1940],{"class":51,"line":1231},[49,1941,1942],{},"                Duration = TimeSpan.FromMilliseconds(150),\n",[49,1944,1945],{"class":51,"line":1236},[49,1946,1947],{},"                EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn }\n",[49,1949,1950],{"class":51,"line":1242},[49,1951,1770],{},[49,1953,1954],{"class":51,"line":1248},[49,1955,194],{"emptyLinePlaceholder":193},[49,1957,1958],{"class":51,"line":1253},[49,1959,1960],{},"            var blurAnimationOut = new DoubleAnimation\n",[49,1962,1963],{"class":51,"line":1259},[49,1964,1262],{},[49,1966,1967],{"class":51,"line":1265},[49,1968,1937],{},[49,1970,1971],{"class":51,"line":1271},[49,1972,1942],{},[49,1974,1975],{"class":51,"line":1277},[49,1976,1947],{},[49,1978,1979],{"class":51,"line":1283},[49,1980,1770],{},[49,1982,1983],{"class":51,"line":1289},[49,1984,194],{"emptyLinePlaceholder":193},[49,1986,1987],{"class":51,"line":1295},[49,1988,1989],{},"            var opacityAnimationOut = new DoubleAnimation\n",[49,1991,1992],{"class":51,"line":1301},[49,1993,1262],{},[49,1995,1996],{"class":51,"line":1306},[49,1997,1937],{},[49,1999,2000],{"class":51,"line":1312},[49,2001,1942],{},[49,2003,2004],{"class":51,"line":1317},[49,2005,1947],{},[49,2007,2008],{"class":51,"line":1323},[49,2009,1770],{},[49,2011,2012],{"class":51,"line":1329},[49,2013,194],{"emptyLinePlaceholder":193},[49,2015,2016],{"class":51,"line":1334},[49,2017,2018],{},"            \u002F\u002F 设置阴影效果\n",[49,2020,2021],{"class":51,"line":1339},[49,2022,2023],{},"            border.Effect = shadowEffect;\n",[49,2025,2027],{"class":51,"line":2026},111,[49,2028,194],{"emptyLinePlaceholder":193},[49,2030,2032],{"class":51,"line":2031},112,[49,2033,2034],{},"            \u002F\u002F 鼠标进入事件\n",[49,2036,2038],{"class":51,"line":2037},113,[49,2039,2040],{},"            border.MouseEnter += (s, e) =>\n",[49,2042,2044],{"class":51,"line":2043},114,[49,2045,1262],{},[49,2047,2049],{"class":51,"line":2048},115,[49,2050,2051],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.ShadowDepthProperty, shadowAnimation);\n",[49,2053,2055],{"class":51,"line":2054},116,[49,2056,2057],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.BlurRadiusProperty, blurAnimation);\n",[49,2059,2061],{"class":51,"line":2060},117,[49,2062,2063],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.OpacityProperty, opacityAnimation);\n",[49,2065,2067],{"class":51,"line":2066},118,[49,2068,1770],{},[49,2070,2072],{"class":51,"line":2071},119,[49,2073,194],{"emptyLinePlaceholder":193},[49,2075,2077],{"class":51,"line":2076},120,[49,2078,2079],{},"            \u002F\u002F 鼠标离开事件\n",[49,2081,2083],{"class":51,"line":2082},121,[49,2084,2085],{},"            border.MouseLeave += (s, e) =>\n",[49,2087,2089],{"class":51,"line":2088},122,[49,2090,1262],{},[49,2092,2094],{"class":51,"line":2093},123,[49,2095,2096],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.ShadowDepthProperty, shadowAnimationOut);\n",[49,2098,2100],{"class":51,"line":2099},124,[49,2101,2102],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.BlurRadiusProperty, blurAnimationOut);\n",[49,2104,2106],{"class":51,"line":2105},125,[49,2107,2108],{},"                shadowEffect.BeginAnimation(System.Windows.Media.Effects.DropShadowEffect.OpacityProperty, opacityAnimationOut);\n",[49,2110,2112],{"class":51,"line":2111},126,[49,2113,1770],{},[49,2115,2117],{"class":51,"line":2116},127,[49,2118,194],{"emptyLinePlaceholder":193},[49,2120,2122],{"class":51,"line":2121},128,[49,2123,2124],{},"            \u002F\u002F 创建包含颜色名称的StackPanel\n",[49,2126,2128],{"class":51,"line":2127},129,[49,2129,2130],{},"            var stackPanel = new StackPanel\n",[49,2132,2134],{"class":51,"line":2133},130,[49,2135,1262],{},[49,2137,2139],{"class":51,"line":2138},131,[49,2140,2141],{},"                Orientation = Orientation.Horizontal,\n",[49,2143,2145],{"class":51,"line":2144},132,[49,2146,2147],{},"                HorizontalAlignment = HorizontalAlignment.Left,\n",[49,2149,2151],{"class":51,"line":2150},133,[49,2152,2153],{},"                VerticalAlignment = VerticalAlignment.Top,\n",[49,2155,2157],{"class":51,"line":2156},134,[49,2158,2159],{},"                Margin = new Thickness(5)\n",[49,2161,2163],{"class":51,"line":2162},135,[49,2164,1770],{},[49,2166,2168],{"class":51,"line":2167},136,[49,2169,194],{"emptyLinePlaceholder":193},[49,2171,2173],{"class":51,"line":2172},137,[49,2174,2175],{},"            stackPanel.Children.Add(border);\n",[49,2177,2179],{"class":51,"line":2178},138,[49,2180,194],{"emptyLinePlaceholder":193},[49,2182,2184],{"class":51,"line":2183},139,[49,2185,2186],{},"            var textBlock = new TextBlock\n",[49,2188,2190],{"class":51,"line":2189},140,[49,2191,1262],{},[49,2193,2195],{"class":51,"line":2194},141,[49,2196,2197],{},"                Text = item.ToString(),\n",[49,2199,2201],{"class":51,"line":2200},142,[49,2202,2203],{},"                VerticalAlignment = VerticalAlignment.Center,\n",[49,2205,2207],{"class":51,"line":2206},143,[49,2208,2209],{},"                Margin = new Thickness(5, 0, 0, 0),\n",[49,2211,2213],{"class":51,"line":2212},144,[49,2214,2215],{},"                Foreground = Brushes.White\n",[49,2217,2219],{"class":51,"line":2218},145,[49,2220,1770],{},[49,2222,2224],{"class":51,"line":2223},146,[49,2225,194],{"emptyLinePlaceholder":193},[49,2227,2229],{"class":51,"line":2228},147,[49,2230,2231],{},"            stackPanel.Children.Add(textBlock);\n",[49,2233,2235],{"class":51,"line":2234},148,[49,2236,194],{"emptyLinePlaceholder":193},[49,2238,2240],{"class":51,"line":2239},149,[49,2241,2242],{},"            presenter.Content = stackPanel;\n",[49,2244,2246],{"class":51,"line":2245},150,[49,2247,939],{},[49,2249,2251],{"class":51,"line":2250},151,[49,2252,982],{},[2254,2255,2256,2261,2265],"blockquote",{},[21,2257,2258],{},[49,2259,2260],{},"!NOTE",[300,2262,2264],{"id":2263},"_1-defaultstylekeypropertyoverridemetadata","1. DefaultStyleKeyProperty.OverrideMetadata",[310,2266,2267,2273,2276],{},[313,2268,2269,2270],{},"作用：告诉 WPF 这个控件",[25,2271,2272],{},"使用哪个样式模板",[313,2274,2275],{},"参数：typeof(ColorStackContent) 表示使用名为 \"ColorStackContent\" 的样式",[313,2277,2278],{},"效果：WPF 会在 XAML 资源中查找对应的样式来渲染控件",[300,2280,2282],{"id":2281},"createdefaultitemspanel-方法","CreateDefaultItemsPanel() 方法：",[2284,2285,2287],"h4",{"id":2286},"为什么需要这个方法","为什么需要这个方法？",[310,2289,2290,2293,2299],{},[313,2291,2292],{},"ItemsPanelProperty 需要的是 ItemsPanelTemplate 类型，不是直接的 WrapPanel",[313,2294,2295,2296],{},"ItemsPanelTemplate 是一个模板，",[25,2297,2298],{},"告诉 WPF 如何创建面板",[313,2300,2301],{},"FrameworkElementFactory 是创建面板实例的工厂",[300,2303,2305],{"id":2304},"preparecontainerforitemoverride-方法","PrepareContainerForItemOverride 方法",[2284,2307,2309],{"id":2308},"这个方法的作用","这个方法的作用：",[310,2311,2312,2315],{},[313,2313,2314],{},"时机：每当 ItemsControl 需要显示一个项目时调用",[313,2316,2317],{},"参数：",[21,2319,2320],{},"​\t\telement：容器元素（通常是 ContentPresenter）",[21,2322,2323],{},"​\t\titem：数据项（在我们的例子中是颜色字符串，如 \"#FF0000\"）",[2284,2325,2327],{"id":2326},"处理流程","处理流程：",[714,2329,2330,2333,2336,2339,2342],{},[313,2331,2332],{},"颜色转换：将字符串（如 \"#FF0000\"）转换为 Color 对象",[313,2334,2335],{},"创建颜色块：创建 50x50 的 Border 作为颜色显示",[313,2337,2338],{},"添加动画效果：创建阴影效果和鼠标悬停动画",[313,2340,2341],{},"创建布局：用 StackPanel 水平排列颜色块和文本",[313,2343,2344,2345],{},"设置内容：将整",[25,2346,2347],{},"个布局设置为 ContentPresenter 的内容",[35,2349,2351],{"id":2350},"新的开始-从net-9开始","新的开始 从.NET 9开始",[21,2353,2354],{},"从.net 9 开始，已经对WPF的fluentUI有了原生的支持，我们可以直接通过在App.xaml中引用这个资源。",[10,2356,2360],{"className":2357,"code":2358,"language":2359,"meta":19,"style":19},"language-xml shiki shiki-themes github-light github-dark","\u003CApplication x:Class=\"TheTestSolutionForWPF.App\"  \n             xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\"  \n             xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\"  \n             xmlns:local=\"clr-namespace:TheTestSolutionForWPF\"  \n             StartupUri=\"MainWindow.xaml\">  \n    \u003CApplication.Resources>  \n         \u003CResourceDictionary>  \n             \u003CResourceDictionary.MergedDictionaries>  \n                 \u003CResourceDictionary Source=\"pack:\u002F\u002Fapplication:,,,\u002FPresentationFramework.Fluent;component\u002FThemes\u002FFluent.xaml\" \u002F>  \n             \u003C\u002FResourceDictionary.MergedDictionaries>  \n         \u003C\u002FResourceDictionary>  \n    \u003C\u002FApplication.Resources>  \n\u003C\u002FApplication>\n","xml",[17,2361,2362,2367,2372,2377,2382,2387,2392,2397,2402,2407,2412,2417,2422],{"__ignoreMap":19},[49,2363,2364],{"class":51,"line":52},[49,2365,2366],{},"\u003CApplication x:Class=\"TheTestSolutionForWPF.App\"  \n",[49,2368,2369],{"class":51,"line":58},[49,2370,2371],{},"             xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\u002Fpresentation\"  \n",[49,2373,2374],{"class":51,"line":64},[49,2375,2376],{},"             xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2006\u002Fxaml\"  \n",[49,2378,2379],{"class":51,"line":70},[49,2380,2381],{},"             xmlns:local=\"clr-namespace:TheTestSolutionForWPF\"  \n",[49,2383,2384],{"class":51,"line":76},[49,2385,2386],{},"             StartupUri=\"MainWindow.xaml\">  \n",[49,2388,2389],{"class":51,"line":82},[49,2390,2391],{},"    \u003CApplication.Resources>  \n",[49,2393,2394],{"class":51,"line":88},[49,2395,2396],{},"         \u003CResourceDictionary>  \n",[49,2398,2399],{"class":51,"line":94},[49,2400,2401],{},"             \u003CResourceDictionary.MergedDictionaries>  \n",[49,2403,2404],{"class":51,"line":100},[49,2405,2406],{},"                 \u003CResourceDictionary Source=\"pack:\u002F\u002Fapplication:,,,\u002FPresentationFramework.Fluent;component\u002FThemes\u002FFluent.xaml\" \u002F>  \n",[49,2408,2409],{"class":51,"line":106},[49,2410,2411],{},"             \u003C\u002FResourceDictionary.MergedDictionaries>  \n",[49,2413,2414],{"class":51,"line":112},[49,2415,2416],{},"         \u003C\u002FResourceDictionary>  \n",[49,2418,2419],{"class":51,"line":118},[49,2420,2421],{},"    \u003C\u002FApplication.Resources>  \n",[49,2423,2424],{"class":51,"line":124},[49,2425,2426],{},"\u003C\u002FApplication>\n",[21,2428,2429],{},"通过这样我们就可以直接使用Fluent主题了，这是版本9的一个新特性。在此之前（.NET 8 及更早版本），WPF 的默认主题还是古老的 Aero2（Windows 8 风格），想要 Windows 11 的样式必须依赖第三方库。",[21,2431,2432,2433,2436,2437,2440],{},"在 .NET 9 中，微软向 .NET Desktop Runtime 添加了一个",[25,2434,2435],{},"全新的官方程序集","，名为 ",[17,2438,2439],{},"PresentationFramework.Fluent.dll","。\n![[Pasted image 20251211205538.png]]",[21,2442,2443,2444,2447,2448,2451,2452,2451,2455,2458],{},"就是这个，只有679KB，还挺小的！",[25,2445,2446],{},"它只是“皮肤” (Styles\u002FTemplates)"," 这个文件里面几乎没有复杂的 C# 逻辑代码。它主要包含的是编译后的 XAML (即 BAML)，定义了 ",[17,2449,2450],{},"Button","、",[17,2453,2454],{},"TextBox",[17,2456,2457],{},"ListBox"," 等标准控件在 Windows 11 下该长什么样（圆角、颜色、字体、边框粗细）",[21,2460,2461,2462,2465,2466,2469],{},"引入它的开销几乎可以忽略不计，应用启动速度不会受到影响，",[25,2463,2464],{},"不仅仅是“好看”","：微软把它做得这么小，意味着它是作为 ",[25,2467,2468],{},"WPF 核心的一部分"," 来设计的，而不是一个臃肿的插件。",[2471,2472,2473],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":19,"searchDepth":58,"depth":58,"links":2475},[2476,2477,2487,2488,2493],{"id":37,"depth":58,"text":37},{"id":297,"depth":58,"text":298,"children":2478},[2479,2480,2481,2482,2483,2484,2485,2486],{"id":302,"depth":64,"text":303},{"id":350,"depth":64,"text":351},{"id":383,"depth":64,"text":384},{"id":449,"depth":64,"text":450},{"id":492,"depth":64,"text":493},{"id":522,"depth":64,"text":523},{"id":587,"depth":64,"text":588},{"id":661,"depth":64,"text":662},{"id":712,"depth":58,"text":712},{"id":1504,"depth":58,"text":1504,"children":2489},[2490,2491,2492],{"id":2263,"depth":64,"text":2264},{"id":2281,"depth":64,"text":2282},{"id":2304,"depth":64,"text":2305},{"id":2350,"depth":58,"text":2351},"md",{},"\u002Fcsharp\u002Fwpf\u002Fwpf-ui组件库使用",{"description":19},"csharp\u002FWPF\u002Fwpf-ui组件库使用","-5SH_9JR2H41hO28co47U_QYmlkZvPyWA5xNkxqv0fE",1791042465648]