欧美成人午夜精品久久久,国产?V天堂一区二区三区,欧美精品va在线观看,亚洲一区二区三区免费在线观看,av无码精品一区二区久久,欧美性爱视频不卡一区三区,欧美乱人伦视频在线观看,国产一级牲交高潮

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

WPF界面框架分層實(shí)踐:主題Token、MVVM與換膚避坑

WPF界面框架分層實(shí)踐:主題Token、MVVM與換膚避坑 簡介面向 WPF 桌面應(yīng)用開發(fā)者的一套現(xiàn)代化界面框架源碼與示例適合希望擺脫默認(rèn)控件外觀、快速搭建統(tǒng)一視覺風(fēng)格的中級(jí)開發(fā)者參考也可作為團(tuán)隊(duì) UI 規(guī)范與主題定制的基礎(chǔ)。壓縮包約 1.84MB共 336 個(gè)文件以 143 個(gè) C# 源碼與 115 個(gè) XAML 界面文件為主體另含 15 個(gè) csproj 工程文件、圖標(biāo)與圖片素材、Visual Studio 項(xiàng)目模板及少量說明文檔覆蓋控件實(shí)現(xiàn)、窗口外殼、主題資源到可復(fù)用模板的完整鏈路。目前已有 6464 人學(xué)習(xí)下載。內(nèi)容圍繞現(xiàn)代化窗口、菜單、對(duì)話框與過渡動(dòng)畫控件展開涉及主題外觀管理與系統(tǒng)版本適配等模塊可據(jù)此理解樣式模板、資源字典與 MVVM 在真實(shí)項(xiàng)目中的組織方式并直接改造為自己的應(yīng)用外殼。1. 一個(gè)漂亮的 WPF 界面框架漂亮之外到底解決什么問題上個(gè)月幫一個(gè)內(nèi)部工具做收尾功能全跑通了評(píng)審時(shí)被一句話打回來這套 WPF 界面看著像十年前的。真正動(dòng)手改才發(fā)現(xiàn)難點(diǎn)不在畫得好看而在主色散落在二十多個(gè) XAML 里、按鈕存在三套模板、每個(gè)窗口的標(biāo)題欄各寫各的。這份 WPF 界面框架源碼包就是把這堆散件整理成三層主題 Token、控件模板、窗口外殼再配一套 MVVM 骨架和若干示例頁。它主要解決兩件具體的事改一處顏色不用翻遍工程新頁面照著示例拼就能交付。適合正在用 WPF 做桌面端、要把界面從「能跑」推到「能驗(yàn)收」的人不適合想找拖拽式設(shè)計(jì)器、指望完全不寫 XAML 的人。2. 拆目錄結(jié)構(gòu)主題 Token、控件模板、窗口外殼這三層怎么分拿到一個(gè)界面框架先別急著運(yùn)行 Demo也別急著往自己的工程里復(fù)制。先看Themes目錄的層次因?yàn)樗鼪Q定了后面所有覆蓋、換膚、定制動(dòng)作能不能生效。這套框架的劃分是比較典型的做法Tokens放純值顏色、字號(hào)、圓角、間距、控件高度Controls放控件樣式與ControlTemplateSkins放皮膚覆蓋Shell放窗口外殼與標(biāo)題欄。分層的意義在于職責(zé)邊界清晰Token 里不該出現(xiàn)任何ControlTemplate控件模板里不該出現(xiàn)任何寫死的#2F6FED。我見過太多項(xiàng)目的資源字典是一個(gè)幾千行的Styles.xaml顏色、模板、動(dòng)畫、轉(zhuǎn)換器全塞在一起。這種文件在項(xiàng)目第三個(gè)月就會(huì)變成黑匣子誰都不敢刪任何一行因?yàn)椴恢绖h了會(huì)影響哪個(gè)頁面。分層不是潔癖是為了讓你敢改。2.1 先看資源字典的合并順序它決定后面所有覆蓋能不能生效WPF 在MergedDictionaries里查找同一個(gè) Key 時(shí)后加入的字典優(yōu)先級(jí)更高。這條規(guī)則很短但它是整套換膚機(jī)制的基石。很多人的皮膚切換做不出來原因就一個(gè)把皮膚字典加在了 Token 字典前面于是 Token 里的舊值一直勝出換膚看起來「沒反應(yīng)」。正確的合并順序是先 Token再 Controls最后 Skin。!-- App.xamlxmlns 省略實(shí)際工程里按模板生成的寫 -- Application.Resources ResourceDictionary ResourceDictionary.MergedDictionaries !-- 第 1 層純值沒有任何模板。換膚就是換這一層的值 -- ResourceDictionary SourceThemes/Tokens/Colors.Default.xaml/ ResourceDictionary SourceThemes/Tokens/Typography.xaml/ ResourceDictionary SourceThemes/Tokens/Metrics.xaml/ !-- 第 2 層控件模板只允許引用第 1 層的 Key -- ResourceDictionary SourceThemes/Controls/Button.xaml/ ResourceDictionary SourceThemes/Controls/TextBox.xaml/ ResourceDictionary SourceThemes/Controls/Card.xaml/ !-- 第 3 層皮膚覆蓋第 1 層同名 Key必須放最后 -- ResourceDictionary SourceThemes/Skins/Light.xaml/ /ResourceDictionary.MergedDictionaries /ResourceDictionary /Application.Resources這段順序背后有兩條必須記住的規(guī)則。第一條是查找方向MergedDictionaries的檢索是從后往前所以最后加載的皮膚能蓋住前面所有同名 Key。第二條是作用域Application.Resources是全局的窗口和控件會(huì)逐級(jí)向上查找一旦某一層出現(xiàn)了同名 Key上層的就永遠(yuǎn)取不到——調(diào)試時(shí)「樣式在別的頁面正常、就這個(gè)頁面不對(duì)」八成是這個(gè)頁面的Window.Resources里藏了一個(gè)同名項(xiàng)??绯绦蚣脮r(shí)路徑要改成 pack URI比如pack://application:,,,/YourApp;component/Themes/Tokens/Colors.Default.xaml程序集名寫錯(cuò)的話運(yùn)行時(shí)會(huì)拋IOException而不是編譯錯(cuò)誤這也是常見的第一道問題。2.2 顏色、字號(hào)、圓角三組 Token為什么主色要用 DynamicResourceToken 層只做一件事把「設(shè)計(jì)決定」變成「命名常量」。這套框架里大致是三類鍵名前綴即語義分類示例 Key典型值說明顏色Color.Accent.Base#2F6FED主色另配 Hover、Pressed 兩檔顏色Color.Surface.Card#FFFFFF卡片、面板底色字號(hào)Font.Size.Body13正文另有 Caption 12、Title 18圓角Radius.Control6按鈕、輸入框統(tǒng)一圓角間距Space.Unit8所有間距取它的整數(shù)倍尺寸Metric.Control.Height32單行控件標(biāo)準(zhǔn)高度主色不要只給一個(gè)值Hover 和 Pressed 要手調(diào)出來別用Opacity疊。原因是透明疊加的結(jié)果依賴背景色同一個(gè)按鈕放在白色卡片和深色側(cè)欄上淺色疊加出來的效果完全不同深色背景上會(huì)發(fā)灰。這是很常見的視覺問題單看沒問題一放到深色區(qū)域就顯得臟。!-- Tokens/Colors.Default.xaml -- ResourceDictionary xmlns... xmlns:x... !-- 主色三檔Hover/Pressed 手工調(diào)深保證在深色和淺色背景上都成立 -- Color x:KeyColor.Accent.Base#2F6FED/Color Color x:KeyColor.Accent.Hover#245BD0/Color Color x:KeyColor.Accent.Pressed#1C48A8/Color !-- Brush 單獨(dú)一層控件模板里用 Brush換膚時(shí)只換 Brush 即可 -- SolidColorBrush x:KeyBrush.Accent.Base Color{StaticResource Color.Accent.Base}/ SolidColorBrush x:KeyBrush.Accent.Hover Color{StaticResource Color.Accent.Hover}/ SolidColorBrush x:KeyBrush.Text.OnAccent Color#FFFFFF/ SolidColorBrush x:KeyBrush.Surface.Card Color#FFFFFF/ !-- 字號(hào)與度量數(shù)值型 Token 用 sys:Double必須帶命名空間 -- sys:Double x:KeyFont.Size.Body13/sys:Double sys:Double x:KeyFont.Size.Title18/sys:Double CornerRadius x:KeyRadius.Control6/CornerRadius sys:Double x:KeyMetric.Control.Height32/sys:Double /ResourceDictionary關(guān)鍵在于「顏色」和「畫筆」分成兩層。Color是不可變結(jié)構(gòu)體SolidColorBrush才是控件屬性真正吃的東西模板里引用的必須是 Brush。數(shù)值型 Token 要注意類型x:Double需要引入sys命名空間clr-namespace:System;assemblySystem.Runtime不同目標(biāo)框架程序集名略有差異CornerRadius直接寫元素即可不用額外命名空間?,F(xiàn)在說DynamicResource和StaticResource怎么選這是最常被問的一個(gè)問題。結(jié)論是會(huì)隨皮膚變化的 Key 用DynamicResource永不變的 Key 用StaticResource。StaticResource在 XAML 解析時(shí)就把值取出來定死換膚后不會(huì)重新求值所以把主色用StaticResource引到模板里切皮膚必然失敗DynamicResource每次取值走一次資源查找會(huì)帶來額外開銷在DataGrid單元格模板、ItemsControl項(xiàng)模板這種會(huì)實(shí)例化成千上萬次的地方能靜態(tài)就靜態(tài)。我的習(xí)慣是Token 里跟顏色相關(guān)的全用DynamicResource字號(hào)、圓角、間距這類換膚不動(dòng)的用StaticResource。這個(gè)劃分一句話能記住后面維護(hù)的人也不會(huì)亂改。2.3 拆一個(gè)按鈕從 Token 到 ControlTemplate 的完整鏈路理解了層次再拆一個(gè)具體控件看看這套框架里一個(gè)主按鈕是怎么拼起來的。這段值得逐行讀因?yàn)樗呛竺嫠锌丶哪0濉?-- Controls/Button.xaml只引用 Token不出現(xiàn)任何字面色值 -- Style x:KeyButton.Primary TargetTypeButton Setter PropertyHeight Value{StaticResource Metric.Control.Height}/ Setter PropertyMinWidth Value72/ Setter PropertyPadding Value16,0/ Setter PropertyFontSize Value{StaticResource Font.Size.Body}/ Setter PropertyForeground Value{DynamicResource Brush.Text.OnAccent}/ Setter PropertyBackground Value{DynamicResource Brush.Accent.Base}/ Setter PropertyBorderThickness Value0/ Setter PropertyCursor ValueHand/ Setter PropertyTemplate Setter.Value ControlTemplate TargetTypeButton Border x:NameBd Background{TemplateBinding Background} CornerRadius{StaticResource Radius.Control} SnapsToDevicePixelsTrue ContentPresenter HorizontalAlignmentCenter VerticalAlignmentCenter Margin{TemplateBinding Padding} RecognizesAccessKeyTrue/ /Border ControlTemplate.Triggers !-- 順序有講究后定義的觸發(fā)器優(yōu)先級(jí)更高 -- Trigger PropertyIsMouseOver ValueTrue Setter TargetNameBd PropertyBackground Value{DynamicResource Brush.Accent.Hover}/ /Trigger Trigger PropertyIsPressed ValueTrue Setter TargetNameBd PropertyBackground Value{DynamicResource Brush.Accent.Pressed}/ /Trigger Trigger PropertyIsEnabled ValueFalse Setter TargetNameBd PropertyOpacity Value0.45/ Setter PropertyCursor ValueArrow/ /Trigger /ControlTemplate.Triggers /ControlTemplate /Setter.Value /Setter /Style這里有幾個(gè)容易被忽略的細(xì)節(jié)每一個(gè)都可能變成后期幾分鐘甚至幾小時(shí)地去排查的問題。第一TemplateBinding是單向的、不支持轉(zhuǎn)換器且只能綁到模板化父級(jí)的屬性上。所以Padding能綁Background能綁但如果你想把Background轉(zhuǎn)成漸變就必須換成{Binding Background, RelativeSource{RelativeSource TemplatedParent}}再掛 Converter?;煊眠@兩者時(shí)不要抱有僥幸心理模板里一旦出現(xiàn)轉(zhuǎn)換需求就整體換成Binding。第二觸發(fā)器順序決定最終效果。IsMouseOver和IsPressed同時(shí)為真時(shí)后定義的IsPressed生效所以按下色必須寫在懸停色后面。反過來寫按下時(shí)看到的還是懸停色看起來就像「按下沒反饋」。第三IsEnabledFalse時(shí)如果只改OpacityCursorHand依然生效鼠標(biāo)移上去還是手型用戶會(huì)以為可以點(diǎn)。所以禁用態(tài)要順手把Cursor也改回來這類細(xì)節(jié)在驗(yàn)收時(shí)最容易被挑出來。最后控件模板里不要出現(xiàn)字面色值這是硬性約束。只要模板里出現(xiàn)一個(gè)#2F6FED換膚那一刻它就會(huì)變成色塊不一致的元兇而且很難靠肉眼定位到具體是哪個(gè)模板??蚣芾镞@類違規(guī)用一次文本搜索就能找出來接入前先搜一遍#順手清理掉。3. 接入現(xiàn)有工程從復(fù)制目錄到跑出第一個(gè)頁面3.1 目錄落位與 csproj 里的資源聲明把整個(gè)工程復(fù)制進(jìn)來是最快的驗(yàn)證方式但真正接入現(xiàn)有項(xiàng)目時(shí)建議只復(fù)制Themes和Infrastructure兩個(gè)目錄示例頁按需挑選著拿。目錄放在項(xiàng)目根下即可不要塞進(jìn)Properties或者obj旁邊obj目錄在清理時(shí)容易誤刪。csproj這塊有個(gè)高頻問題SDK 風(fēng)格工程的默認(rèn) glob 已經(jīng)把**/*.xaml編譯成Page你再手寫一遍Page IncludeThemes\**\*.xaml /就會(huì)報(bào)重復(fù)項(xiàng)NETSDK1022。所以大部分情況下什么都不用寫只在需要排除或者改變構(gòu)建方式時(shí)才動(dòng)它。ItemGroup !-- 默認(rèn) glob 已包含 **/*.xaml這里只做排除草稿目錄不參與編譯 -- Page RemoveThemes\_draft\**\*.xaml / !-- 字體、圖標(biāo)這類二進(jìn)制資源用 Resource隨程序集嵌入pack URI 才取得到 -- Resource IncludeAssets\Fonts\*.ttf / Resource IncludeAssets\Icons\*.png / !-- 示例數(shù)據(jù)用 Content 復(fù)制到輸出目錄別用 Resource 塞進(jìn)程序集 -- Content IncludeSampleData\*.json CopyToOutputDirectoryPreserveNewest / /ItemGroup構(gòu)建項(xiàng)的選擇直接決定資源能不能取到這張表建議存下來構(gòu)建項(xiàng)編譯結(jié)果適用場景取用方式Page編譯為 BAML所有 XAML包括資源字典Source相對(duì)路徑Resource嵌入程序集字體、圖標(biāo)、小圖片pack://application:,,,/程序集;component/路徑Content原樣復(fù)制到輸出目錄示例數(shù)據(jù)、可替換配置相對(duì)輸出目錄的路徑None不處理文檔、說明無字體用Resource嵌入之后在 XAML 里通過FontFamily/Assets/Fonts/#字體內(nèi)部名引用注意斜杠后面那個(gè)#后面跟的是字體家族名不是文件名。寫錯(cuò)了不會(huì)報(bào)錯(cuò)只會(huì)靜默回退到系統(tǒng)默認(rèn)字體——這類靜默失敗最耗時(shí)間。3.2 App.xaml 合并字典與運(yùn)行時(shí)換膚皮膚切換不要用「先清空再添加」的寫法。清空MergedDictionaries會(huì)在瞬間讓所有DynamicResource失效控件重繪時(shí)可能拋出找不到資源的異常而「只添加不移除」會(huì)讓字典越積越多切換五十次之后內(nèi)存和查找開銷都會(huì)肉眼可見地上漲。正確做法是把皮膚字典固定在MergedDictionaries的最后一位換膚就是替換這一項(xiàng)。public static class ThemeManager { // 皮膚字典固定放在 MergedDictionaries 的末位替換這一項(xiàng)即為換膚 private static readonly Uri LightSkin new(pack://application:,,,/YourApp;component/Themes/Skins/Light.xaml); private static readonly Uri DarkSkin new(pack://application:,,,/YourApp;component/Themes/Skins/Dark.xaml); public static void Apply(bool dark) { var merged Application.Current.Resources.MergedDictionaries; if (merged.Count 0) return; var skin new ResourceDictionary { Source dark ? DarkSkin : LightSkin }; // 關(guān)鍵替換而不是 Add避免字典無限增長 merged[merged.Count - 1] skin; } }替換完成后不需要手動(dòng)刷新任何控件DynamicResource會(huì)自動(dòng)重新求值。這里有個(gè)前提所有隨皮膚變化的引用必須是DynamicResource只要模板里漏了一個(gè)StaticResource換膚后那個(gè)控件就會(huì)保持舊色在一片新配色里顯得很突兀。還要注意換膚的時(shí)機(jī)。啟動(dòng)時(shí)在App構(gòu)造函數(shù)里調(diào)用是最穩(wěn)的如果放在窗口Loaded之后用戶會(huì)看到一次明顯的閃爍。真想做到無閃爍就得在窗口顯示前把皮膚定好也就是把配置讀取提前到App初始化階段。3.3 無邊框窗口外殼與自定義標(biāo)題欄這套框架的外殼用的是WindowChrome而不是WindowStyleNone加AllowsTransparencyTrue。后者雖然也能做出無邊框效果但會(huì)讓窗口失去硬件加速路徑拖動(dòng)和縮放時(shí)明顯發(fā)澀圓角邊緣還會(huì)有鋸齒。WindowChrome保留系統(tǒng)窗口的非客戶區(qū)行為只把繪制權(quán)交給你。!-- Shell/AppWindow.xaml無邊框外殼保留系統(tǒng)縮放與拖拽行為 -- Window x:ClassYourApp.Shell.AppWindow WindowStyleNone ResizeModeCanResize AllowsTransparencyFalse Background{DynamicResource Brush.Surface.Card} !-- CaptionHeight頂部可拖拽區(qū)高度等于標(biāo)題欄高度 -- !-- ResizeBorderThickness邊緣拖拽熱區(qū)觸屏場景建議放大到 8 -- WindowChrome.WindowChrome WindowChrome CaptionHeight40 ResizeBorderThickness6 GlassFrameThickness0 CornerRadius0 UseAeroCaptionButtonsFalse/ /WindowChrome.WindowChrome Grid Grid.RowDefinitions RowDefinition Height40/ RowDefinition Height*/ /Grid.RowDefinitions !-- 標(biāo)題欄區(qū)域內(nèi)的按鈕必須聲明 IsHitTestVisibleInChrome否則點(diǎn)不到 -- StackPanel Grid.Row0 OrientationHorizontal HorizontalAlignmentRight WindowChrome.IsHitTestVisibleInChromeTrue Button Content— Style{StaticResource Button.Caption}/ Button Content□ Style{StaticResource Button.Caption}/ Button Content× Style{StaticResource Button.Caption}/ /StackPanel ContentPresenter Grid.Row1 Content{Binding Body}/ /Grid /Window三個(gè)參數(shù)決定了使用手感。CaptionHeight要和標(biāo)題欄那一行的高度嚴(yán)格對(duì)齊寫 40 就是 40寫小了頂部會(huì)剩一條既不能拖也不能點(diǎn)的死區(qū)ResizeBorderThickness在鼠標(biāo)場景 6 夠了觸屏設(shè)備建議 8 到 10否則邊緣拖不動(dòng)GlassFrameThickness0去掉系統(tǒng)玻璃層避免深色皮膚下邊緣發(fā)亮。標(biāo)題欄里的按鈕必須加WindowChrome.IsHitTestVisibleInChromeTrue這一條不加按鈕會(huì)變成「看得見點(diǎn)不著」鼠標(biāo)事件被拖拽區(qū)吃掉了。這是無邊框窗口最常見的一個(gè)問題排查時(shí)容易往命令綁定上想繞一圈才發(fā)現(xiàn)是命中測試。另一個(gè)是最大化蓋住任務(wù)欄。無邊框窗口最大化時(shí)系統(tǒng)給的尺寸包含非工作區(qū)直接鋪滿會(huì)頂?shù)羧蝿?wù)欄。簡單的做法是在窗口構(gòu)造里設(shè)MaxHeight SystemParameters.MaximizedPrimaryScreenHeight多顯示器場景下這個(gè)值只在主屏正確需要監(jiān)聽WM_GETMINMAXINFO自己算工作區(qū)框架的Shell目錄里有對(duì)應(yīng)的輔助類接入時(shí)按屏幕數(shù)量確認(rèn)一下。3.4 驗(yàn)收入口DPI、縮放、多屏的檢查清單界面框架接進(jìn)去功能點(diǎn)兩下都正常不代表能交付。下面這張表是我每次接入必過的一遍成本不到十分鐘能提前擋掉大部分返工。檢查項(xiàng)操作不通過的表現(xiàn)單屏 100%系統(tǒng)縮放調(diào)到 100%逐頁翻一遍1px 邊框消失或變粗單屏 150%縮放到 150%看文字與圖標(biāo)文字發(fā)虛、圖標(biāo)模糊多屏不同縮放兩屏分別設(shè) 100% 和 150%拖窗口來回拖到另一屏后整體變糊高對(duì)比度切換系統(tǒng)高對(duì)比度主題文字與背景同色看不見觸摸觸屏設(shè)備上點(diǎn)邊緣縮放邊緣拖不動(dòng)最小尺寸拖到最小寬高標(biāo)題欄按鈕被擠出可視區(qū)DPI 那一欄解釋一下WPF 是邏輯像素體系縮放變化時(shí)如果圖片資源只準(zhǔn)備了一份系統(tǒng)會(huì)拉伸結(jié)果就是模糊。圖標(biāo)盡量用矢量路徑位圖則按 100%、150%、200% 各備一份靠Image的尺寸選擇邏輯去匹配。這條不做用戶在 150% 縮放的筆記本上第一眼就會(huì)覺得「這軟件有點(diǎn)舊」。4. MVVM 骨架命令、通知、導(dǎo)航與對(duì)話框怎么切界面層的活干完接著看骨架。這套框架的Infrastructure目錄里放的是一套很薄的基礎(chǔ)設(shè)施ViewModelBase、RelayCommand、AsyncCommand、導(dǎo)航服務(wù)、對(duì)話框服務(wù)。判斷一套 MVVM 骨架好不好標(biāo)準(zhǔn)只有一條ViewModel 里能不能完全不出現(xiàn)Window、MessageBox、Application.Current。出現(xiàn)了單測就廢了復(fù)用也別想了。4.1 ViewModelBase屬性通知與 SetProperty 的寫法public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; // 返回 bool方便 setter 里鏈?zhǔn)酵ㄖ缮鷮傩?protected bool SetPropertyT(ref T field, T value, [CallerMemberName] string? name null) { // 用 EqualityComparer 而不是 object.Equals避免值類型裝箱 if (EqualityComparerT.Default.Equals(field, value)) return false; field value; OnPropertyChanged(name); return true; } protected void OnPropertyChanged([CallerMemberName] string? name null) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }CallerMemberName省掉了手寫屬性名字符串改屬性名時(shí)不會(huì)漏改通知。相等判斷用EqualityComparerT.Default而不是因?yàn)榉盒屠飳?duì)值類型是裝箱比較屬性高頻更新時(shí)這點(diǎn)開銷會(huì)積少成多。返回bool是個(gè)很實(shí)用的小設(shè)計(jì)if (SetProperty(ref _name, value)) OnPropertyChanged(nameof(DisplayName));這樣派生屬性只在真正變化時(shí)通知避免無謂的綁定刷新。老項(xiàng)目里常見的寫法是 setter 里連續(xù)調(diào)三次OnPropertyChanged每次輸入都觸發(fā)一輪完整重算。集合屬性是另一個(gè)問題點(diǎn)。ObservableCollectionT不要每次賦值都new那等于讓ItemsControl重建整個(gè)視圖樹滾動(dòng)位置會(huì)跳回頂部。正確做法是初始化一次之后用Clear()加Add()更新。4.2 RelayCommand 與 AsyncCommandCanExecute 刷新時(shí)機(jī)的坑public sealed class RelayCommand : ICommand { private readonly Actionobject? _execute; private readonly Funcobject?, bool? _canExecute; public RelayCommand(Actionobject? execute, Funcobject?, bool? canExecute null) { _execute execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute canExecute; } public bool CanExecute(object? parameter) _canExecute?.Invoke(parameter) ?? true; public void Execute(object? parameter) _execute(parameter); public event EventHandler? CanExecuteChanged { add CommandManager.RequerySuggested value; remove CommandManager.RequerySuggested - value; } // 手動(dòng)觸發(fā)異步命令結(jié)束、集合變化后必須調(diào) public void RaiseCanExecuteChanged() CommandManager.InvalidateRequerySuggested(); }CommandManager.RequerySuggested是隱式刷新只在鍵盤、鼠標(biāo)等輸入事件之后觸發(fā)。這意味著如果你在后臺(tái)線程里改了某個(gè)標(biāo)志位按鈕的可用狀態(tài)可能要等到用戶點(diǎn)一下別的地方才更新。血淚經(jīng)驗(yàn)是異步命令執(zhí)行完畢、批量數(shù)據(jù)加載完成這類時(shí)刻必須顯式調(diào)一次RaiseCanExecuteChanged()否則用戶會(huì)看到「按鈕還是灰的但功能其實(shí)已經(jīng)好了」。異步命令額外要處理兩件事。一是防重入執(zhí)行中把CanExecute置為false避免用戶連點(diǎn)三次發(fā)出三個(gè)請(qǐng)求。二是異常兜底async void里拋出的異常會(huì)直接打到未處理異常上進(jìn)程就掛了??蚣芾锏腁syncCommand用try/catch包住執(zhí)行體把異常交給注入的錯(cuò)誤處理器再由它彈提示。public sealed class AsyncCommand : ICommand { private readonly Funcobject?, Task _execute; private readonly Funcobject?, bool? _canExecute; private bool _isRunning; // 防重入標(biāo)志 public AsyncCommand(Funcobject?, Task execute, Funcobject?, bool? canExecute null) { _execute execute; _canExecute canExecute; } public bool CanExecute(object? parameter) !_isRunning (_canExecute?.Invoke(parameter) ?? true); public async void Execute(object? parameter) { if (_isRunning) return; _isRunning true; RaiseCanExecuteChanged(); try { await _execute(parameter); } catch (Exception ex) { // 必須兜住async void 里的異常無處可去 ErrorHandler?.Invoke(ex); } finally { _isRunning false; RaiseCanExecuteChanged(); } } public event ActionException? ErrorHandler; public event EventHandler? CanExecuteChanged; public void RaiseCanExecuteChanged() CanExecuteChanged?.Invoke(this, EventArgs.Empty); }AsyncCommand我沒有復(fù)用CommandManager而是自己維護(hù)CanExecuteChanged。原因是異步場景下按鈕狀態(tài)變化跟輸入事件沒有必然關(guān)系走隱式刷新容易失準(zhǔn)自己控制雖然要多調(diào)幾次RaiseCanExecuteChanged但行為可預(yù)期。4.3 導(dǎo)航與對(duì)話框接口怎么切才不綁死 UI接口切分的目標(biāo)是讓 ViewModel 只描述「要什么」不描述「怎么顯示」。這張表是框架里的切法接口職責(zé)不該做的事INavigationService按 ViewModel 類型切換主區(qū)域內(nèi)容不引用具體Page、Window類型IDialogService確認(rèn)框、輸入框、等待提示不直接調(diào)MessageBoxINotificationService頂欄消息、Toast不持有具體控件的引用IThemeService讀取與切換皮膚不碰Application.Resources的索引public interface IDialogService { // 返回 Task調(diào)用方 await 之后拿結(jié)果避免回調(diào)地獄 Taskbool ConfirmAsync(string title, string message); Taskstring? PromptAsync(string title, string message, string? defaultValue null); }實(shí)現(xiàn)側(cè)常見的做法是用一個(gè)覆蓋全窗口的ContentControl加半透明遮罩把對(duì)話框內(nèi)容當(dāng)作普通控件渲染返回值靠TaskCompletionSourcebool在用戶點(diǎn)擊時(shí)SetResult。這樣對(duì)話框也吃同一套 Token深色皮膚下不會(huì)出現(xiàn)一個(gè)白底黑字的系統(tǒng)彈窗視覺上跳出來。這里要提醒一點(diǎn)TaskCompletionSource必須用TaskCreationOptions.RunContinuationsAsynchronously否則SetResult會(huì)在 UI 線程上同步跑完整個(gè)await后續(xù)邏輯遇到重活就卡界面。這個(gè)問題非常隱蔽表現(xiàn)為「點(diǎn)確認(rèn)之后界面頓一下」把選項(xiàng)加上就好。5. 避坑記錄樣式不生效、內(nèi)存上漲、DPI 模糊的排查順序這一章是這份框架里最值得先讀的部分。下面四條都是我在真實(shí)接入里遇到過的每一條按現(xiàn)象、原因、解決的順序?qū)懹龅酵悊栴}時(shí)可以照著順序查。5.1 現(xiàn)象改了 Token控件紋絲不動(dòng)現(xiàn)象把Color.Accent.Base從藍(lán)改成橙重新生成主按鈕還是藍(lán)的。清緩存、重啟 IDE 都試過仍然是藍(lán)。原因控件模板里引用的是{StaticResource Brush.Accent.Base}。StaticResource在 BAML 解析階段就把值取出來寫死了后續(xù)字典變化對(duì)它沒有任何影響。另一種可能是這個(gè)頁面的Window.Resources里定義了一個(gè)同名的Brush.Accent.Base局部作用域優(yōu)先全局的改動(dòng)被它遮住。解決在解決方案里搜StaticResource Brush.凡是顏色類的引用全部換成DynamicResource再逐頁檢查Window.Resources和UserControl.Resources里有沒有同名 Key。這兩步做完改動(dòng)立即生效。我的習(xí)慣是把這條寫進(jìn)代碼評(píng)審清單模板里出現(xiàn)StaticResource后面跟Brush.前綴的一律打回。5.2 現(xiàn)象切幾次皮膚內(nèi)存一路往上走現(xiàn)象在設(shè)置頁反復(fù)切換淺色和深色任務(wù)管理器里的內(nèi)存從 180MB 漲到 400MB 不回落切得越多漲得越多。原因換膚實(shí)現(xiàn)寫成了merged.Add(skin)每次切換都往MergedDictionaries里追加一個(gè)字典舊字典既沒被移除也沒被回收資源查找還得從后往前遍歷一長串。另一個(gè)隱性原因是畫筆沒凍結(jié)SolidColorBrush每次創(chuàng)建都是新的可凍結(jié)對(duì)象沒調(diào)Freeze()就參與變更通知無法被共享。解決換膚改成替換末位元素見 3.2 的寫法Token 里所有SolidColorBrush在創(chuàng)建后調(diào)一次Freeze()凍結(jié)后的畫筆可以被多個(gè)控件共享內(nèi)存占用會(huì)明顯下降。改完再測反復(fù)切換五十次內(nèi)存曲線基本走平。提示Freeze()只能用于可凍結(jié)對(duì)象而且凍結(jié)后不能再改屬性。如果某個(gè)畫筆需要在運(yùn)行時(shí)調(diào)色就別凍結(jié)它。5.3 現(xiàn)象4K 屏上字體發(fā)虛、1px 邊框消失現(xiàn)象開發(fā)機(jī) 100% 縮放一切正常換到 150% 縮放的筆記本上正文明顯發(fā)糊卡片之間的 1px 分隔線時(shí)有時(shí)無圓角處還有毛邊。原因三個(gè)疊加問題。位圖圖標(biāo)只準(zhǔn)備了一份系統(tǒng)拉伸導(dǎo)致模糊Border的BorderThickness用了1但沒開UseLayoutRounding和SnapsToDevicePixels在非整數(shù)縮放比下 1px 被攤到兩個(gè)物理像素上顏色被稀釋到看不見再就是窗口設(shè)了AllowsTransparencyTrue透明窗口在部分縮放下失去硬件渲染路徑。解決圖標(biāo)改用矢量路徑在外殼根元素上開UseLayoutRoundingTrue需要像素對(duì)齊的Border和Image加SnapsToDevicePixelsTrue無邊框窗口換回WindowChrome方案。三條一起改150% 下再對(duì)比截圖邊緣和文字都恢復(fù)銳利。5.4 現(xiàn)象設(shè)計(jì)器里正常運(yùn)行時(shí)拋 XamlParseException現(xiàn)象XAML 在設(shè)計(jì)器里預(yù)覽得好好的一運(yùn)行就拋XamlParseException提示找不到某個(gè)資源堆棧指向一個(gè)看起來沒問題的Setter。原因StaticResource的解析是編譯期決定的它只能向前查找——引用必須出現(xiàn)在定義之后或者定義在更早就合并的字典里。設(shè)計(jì)器有時(shí)會(huì)更寬松地加載于是出現(xiàn)「設(shè)計(jì)器能看、跑起來就崩」。另一種原因是跨程序集引用時(shí) pack URI 里的程序集名寫錯(cuò)編譯期不校驗(yàn)運(yùn)行時(shí)才爆。解決先在App.xaml里把 Token 字典排在最前面確保所有模板在后面再檢查所有跨程序集的Source程序集名、大小寫、component關(guān)鍵字都要對(duì)上。定位技巧是把App.xaml里的合并字典臨時(shí)注釋掉一半二分法很快能鎖定是哪個(gè)文件。5.5 常見問題速查表癥狀第一嫌疑快速驗(yàn)證換膚后個(gè)別控件不變色模板里用了StaticResource全工程搜StaticResource Brush.按鈕點(diǎn)不動(dòng)標(biāo)題欄命中測試被吃檢查IsHitTestVisibleInChrome最大化蓋住任務(wù)欄無邊框窗口的尺寸計(jì)算看MaxHeight是否按工作區(qū)算列表刷新后滾動(dòng)條跳頂集合被整體new檢查ObservableCollection賦值處命令按鈕一直灰隱式刷新未觸發(fā)手動(dòng)調(diào)一次RaiseCanExecuteChanged字體不是預(yù)期那個(gè)FontFamily的家族名寫錯(cuò)核對(duì)#后面是家族名而非文件名6. 進(jìn)階把換膚做成可以回歸驗(yàn)證的流程界面類的改動(dòng)最難驗(yàn)證因?yàn)樗缚雌饋頉]問題」和「確實(shí)沒問題」之間差得很遠(yuǎn)。這套框架里我最常用的一個(gè)技巧是把換膚做成可以對(duì)比的回歸流程。第一步把 Token 抽出來做一份中間格式??蚣艿腡okens目錄本身就是鍵值對(duì)用幾十行代碼掃一遍 XAML把Color.*、Font.Size.*、Radius.*導(dǎo)出成 JSON交給設(shè)計(jì)側(cè)對(duì)齊。之后設(shè)計(jì)師改配色改的是這份 JSON工程師用腳本回寫 XAML比在群里發(fā)色值截圖靠譜得多?;貙懩_本要注意保留原有的x:Key順序和縮進(jìn)否則每次生成都是幾百行 diff評(píng)審時(shí)沒人看得下去。第二步準(zhǔn)備一個(gè)「Token 全覽頁」。把所有 Token 渲染成色塊、字號(hào)樣例、圓角樣例配上鍵名放在調(diào)試菜單里。換膚以后直接翻這一頁哪個(gè)鍵沒被覆蓋一眼就能看出來。這個(gè)頁面我一般不到半小時(shí)就能拼完但省下來的排查時(shí)間遠(yuǎn)超投入。第三步截圖比對(duì)。把關(guān)鍵頁面在淺色和深色下各截一張存在版本庫里改了樣式之后重新截用逐像素差值定位變化區(qū)域。閾值不要設(shè)在零字體渲染有亞像素抖動(dòng)允許千分之三以內(nèi)的差異超過就是真改了。這套流程跑順之后改一個(gè) Token 影響哪些頁面提交前就能知道。還有一個(gè)小習(xí)慣值得說一下每次接入新的界面框架我都會(huì)先在空工程里跑一遍它的 Demo把所有頁面點(diǎn)一遍重點(diǎn)看深色皮膚下的對(duì)比度和禁用態(tài)。原因很簡單這些地方最容易藏問題而在自身工程里樣式問題會(huì)被業(yè)務(wù)邏輯掩蓋很難判斷到底是框架的問題還是你寫錯(cuò)了。從那以后我每次往項(xiàng)目里引 UI 框架都強(qiáng)制先走一遍這套空工程驗(yàn)證再動(dòng)業(yè)務(wù)代碼。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产精品国产| 国产古装妇女野外A片| 色婷婷大香蕉| 五月综合人妻| 国产FREESEXVIDEOS性中国| 99成人免费视频| 五月天天综合| 97婷婷五月激情六月丁香伊人| 99视频只有精品| 激情五月天免费视频| 丁香婷婷九月| 能看的AV网站| 激情WWW| 第四色五月婷婷| 欧美色综合天天久久综合精品| www.激情五月| 婷婷五月天国产| 色婷五月丁香久亚洲| 啪色综合| 丁香婷婷91在线观看视频| 婷婷五月天成人网| 色色色图| 欧美人妻一区二区| 99热欧美| 亚洲综合婷婷| 91婷婷在线| 五月天激情开心网| 五月天婷婷青青草| 五月丁查人人| 99热这里全都是精品| 毛片新网地| 婷婷丁香六月综合激情站| 99热精品10| 伊人网色婷婷五月天| 九九热最新| 天堂色婷婷| 九九久热| 丁香五月激情网| 丁香六月成人网| 美女婷婷六月色| 台湾无码A片一区二区| 玖玖@三月天天丁香婷婷| 免费看欧美成人A片无码| 粉嫩av蜜桃av蜜臀av| 桔色成人在线| 青青草轻轻操| 九九这里有精品| 99日本精品视频热| 少妇性按摩无码中文A片| 久操婷婷| 青草视频在线观看视频 | 成人网在线观看视频| 婷婷爱五月天| 少妇熟女视频一区二区三区| 狠狠色噜噜狠狠狠777奇米| 最近中文字幕2019视频1| 91精品综合久久久久久五月丁香| 婷婷大香蕉| 天天干天天插| 国产精品男人AV不卡| 久久久久久99日本| 97超碰在线免费观看| 超碰国产AV| 亚洲精品在线视频| 婷婷五月激情基地| 国产精品色婷婷AV综合色色| 色婷婷亚洲| 五月婷婷黄色| 一本久久婷婷| 狠狠色丁香| 99色在线视频观看| 密桃激情五月天综合网| 日韩久热| 婷婷五月花| 色色五月婷婷狠狠| 亚洲第一成人无码A片| 超碰操网| dingxiangtingtingliuyue| 99综合激情久久精品久久| 91精品综合久久久久久五月丁香| 久色网| 色99视频| 国产精品岛国片在线观看免费| 99热99成人| 亚洲免费观看高清完整版AV线| 性爱综合网| 国产亚洲99久久精品| 亚洲热手机在线观看| 婷婷亚洲五| 国产av网| 天天激情5月天亚洲| 国产Va视频| 激情小说之五月| 激情五月综合亚洲另类| 久婷婷视平| 人人97碰| 五月婷婷六月天| 人人干av| aa久久| 丁香六月婷婷色XXXX| 亚洲综合五月天婷婷| 午夜一区| 婷婷午夜综合| 久久久久丁香婷婷五月天| 婷婷九月丁香| 97在线干| 亚城区在线| 99热这里只有精品在线观看| 另类视屏| 看片视频在线免费日产在线看| 五月丁香激情综合网| WWW.HENHENL.| 五月天激情婷婷五月天久久| 亚洲超碰在线| 欧美色久| 开心五月综合激情网| 久久久国产精品黄毛片| 色婷婷内射| 色婷婷电影网| 五月色婷丁香| 伊人五月丁香| 大香蕉视频婷婷| 色欲av伊人久久大香线蕉影院| 久久欧洲综合网| 久久婷婷综合五月天| 丁香五月玖玖| 思思热久久久在线| 九九色婷婷五月天| 日日夜夜噜噜爽爽| 激情五月综合网丁| 日韩乱玛久久| 五月丁香色| 中文幕无线码中文字蜜桃| 99日逼视频| www开心激情网| 色色五月天婷婷| 啪啪夜久久| 五月天色婷婷激情| 久久的爱大香蕉| 国产26uuu视频| 99这里有精品| 丁香激情合作五月| 伊人久久大香线蕉精品| 思思久日精品视频| 日本英国美国欧美亚洲国产精亚洲日韩精品在线观看 | 色五月亚洲| 婷婷色影院| 亚洲六月婷婷| 97色在线| 91精品久久久久久久久久| 丁香五月婷婷亚洲人| 99国产精品久久久久久久久久久| 91综合在线视频| 俺去也综合| 懂色av蜜臀av粉嫩av永陈冠希| 99热在这里只有精品| 婷婷碰碰| 五月婷婷啪啪| 丁香丁婷五月激情| 先锋影音av色五月天资源站| 五月婷婷六月丁香在线视频| 影音先锋综合网| 久久色这里只有精品| AⅤ在线播放网| 五月天国产婷婷精品视频在线| 婷婷丁香综合色AV| 日韩成人AV在线| 超碰免费99| 综合啪啪| 亚洲第一视频 久久| 色啪久| 人人草人人爱手机视频看看| 秋霞AV美国| 欧美久久婷婷| www.五月激情红色| 97人人搞| 无码激情AAAAA片-区区| 九九色色| 色综合久久88色综合天天人守婷| 密臀av无码人妻精品| 99热免费精品| 精品99网站| 婷婷六月激情综合| 大香蕉伊人99| 日韩99色99| 99玖玖人人| 五月丁香六月婷| 开心久久xxx色| 国产精品A成V人在线播放| 久久奄也去色色网站| 伊人久久大香线蕉精品| www久久99| 这里只有精品视频在线观看免费| 97色操| 色色色综合色| 九九热99熟女| 五月丁香无码| 午夜色色色极品视频| 丰满少妇猛烈A片免费看观看| 狠色色狠网| 六月婷久久| 99精品偷自拍| 九九五月天| 日韩成人五月天| 五月天最新网| 久er7久热| 婷婷丁香综合色AV| 久久小说网| 99热这里只有精品1| 色色综合网站| 骚五月婷婷| 婷婷五月天社区| www.婷婷.com| 五月婷婷五月天天| 26uuu国产色| 丁香五月ⅤA久久久| 日日爽日日| 凹凸操Av| 色婷婷伦理| 久久精品婷婷五月丁香| 色婷婷色和| 丁香激情网| 婷婷丁香综合| 丁香五月婷婷色综合| 91视频五月丁香| 日本成人噜噜噜噜噜| 五月丁香激情婷婷| 4399欧美另类视频| 色99视| 欧美电影在线播放| 91丨九色丨东北熟女| 欧美激情VA永久在线播放| 99热这里只有精品98| 亚洲AV第二区国产精品| 九九热99精品| www.com色播五月天| 超碰日韩人妻在线| 91在线操逼视频| 五月丁香色综合| WWW,五月| 九色视频91疯狂| 天天操综合网站| 九九热这里都是精品6| 精品99在线看| www.五月婷婷| 亚洲性受XXXX五月丁香| 色噜噜婷婷| 成人资源在线| 人伦30P| 激情骚五月| 亚洲区在线| www.色色色com| 熟妇内谢69XXXXXA片| 五月婷婷激情综合| 婷婷五月影院| 亚洲成人在线在线| 欧在线一区| 人人肏逼视频在线一区二区| 婷综合六月| 久久婷婷五月综合网| 嫩草极品| 欧美婷婷精品激| 五月激情久久| 草草视频91| 性色婷婷| 大香网伊人久久综合| 狠狠干,狠狠操| 激情五月天网| 97碰91| 五月综合激情图片| 久九色| 婷婷五月激情四月综合| 99精品爱| 五月丁香婷草| 嫩草AV久久伊人妇女超级A| 久久久久人妻| 婷婷丁香www视频日本韩国| 超碰超碰在线| 婷婷五月成人| 丁香九月色| 婷婷五月天丁香久久| 免费观看2018www黄色操逼网站| 97日本在线| 九九偷拍网| 婷婷97碰碰| 色一区高清| www.91有码.com| 五月开心深爱激情网| 激情综合网五月婷婷| 婷婷欧美综合| 五月久久综合| 色婷婷香蕉| 激情五月天无码| 欧美久久婷婷| 热久精品| 五月天停婷基地| 五月丁香久久综合| 久久性爱视频这里只有精品 | 久久久日韩特色特黄AAAA| 婷婷 丁香 久久| 99 热国产在| 色婷婷影音| 色婷婷偷拍| 国产精品久久久久久久久久免费| 综合性爱网| 翔田千里aV中文字幕| 丁香九色不卡aaa| 久久久久亚洲AV无码网影音先锋| 丁香五月婷婷成人综合| 亚洲成人免费在线| 99碰在线视频| 五月天中文网| 99综合视频一体| 超碰99热在线观看| 五月婷婷六月丁香激情综合网| 婷婷六月丁| 97人人操人人干| 操日本色| 婷婷激情六月天视频| 99人妻碰碰碰久久久久禁片| 久久亭亭电影| 99热777| 色五月激情| 97丁香视频| 蜜臀av无码久久久久久久久| 99啪啪视频| 成人视频免费观看高清完整版在线观看| 日韩欧美颜射| 96精品久久久久久久久| 婷婷丁香成人五月天| 开心五月丁香婷婷| 香蕉久久国产AV一区二区| 大香蕉伊人99| 五月激情婷婷播播开心| 五月色婷丁香| 综合五月网| 国产小精品| 日本综合色色| 五月色网| 这里只有精品免费在线视频| 五月色婷婷中文字幕| 精品9久| 亚洲激情淫网| 狠狠干综合| www色色com| 国产亚洲精品久久一区二区三区| 日韩五月婷婷| 丁香五月六月综合激情| 4399在线观看免费高清黄色视频| 人人爱摸视频| 丁香五月情| 五月激情六月综合| 亚洲一区国产传媒| 亚洲天堂久久| VA色婷婷| www.五月天| 丁香五月性| 超碰av在线| 91人人网| 79精品视频在线观看,| www.婷婷亚洲基地| 来吧亚洲综合网| 丁香六月啪啪| 国产亚洲精品久久久久久郑州| 五月丁香六月婷婷啪啪综合| www.婷婷六月天| 无码九九| 日韩黄色中文字幕| 最新丁香六月婷婷| 色婷婷中文在线| 色综合久久88色综合天天99| 色五月天天在线观看资源站| 99精品国产在热久久| 在线综合婷婷| 丁香六月激情国产| www.五月婷婷| 丁香五月综合福利视频导航| 九月性爱网| 色综合久久88色综合天天99| 久久综合中文| 国产午夜成人AV在线播放| 天天干-天天日| 91大神在线免费看视频全集男男一起操| 79色色| 国产精品美女| 任你草| 天天干夜夜欢| 丁香五月在线自慰| 欧美S码亚洲码精品M码| 婷婷五月天综合在线| 狠狠第四色| 国产激情久久| 丁香五月婷婷激情蜜桃| 五月丁香啪啪婷婷| 苗黎美女四级成人版一级二级毛片| 思思热久久婷婷五月天| 六月久久婷婷| 秋霞少妇AV网站| 第五色色色婷婷| 9|无码久久久久久| 99青青草99| 久久久五月五丁香| 久久66精品| 99热插| 九九色色| pacopacomama 070722_670 素人奥様初撮りドキュメント 103 大久保純子 | 久播影院免费观看电视剧大全最新网| 玖玖综合网| 免费视频无码| w婷婷五月婷婷w| 另类图片激情五月天| 极品五月天| 婷婷久热| 色婷婷狠狠18| 六月色婷婷欧美| 97操| AⅤ网站在线看| 婷婷操超碰| 人人爽人人爽人人爽人人爽| 亚洲五月婷| 五月丁香另类网| 天天爱天天做天天操| 天天干天天射色综合| 久久五月丁香| 激情五月天色婷婷综合| 激情小说色五月| 欧美黄色AA片哗啦啦啦| 亚洲综合激情五月久久| 日日夜夜噜噜爽爽| 精品婷婷五月视| 99玖玖在线视频| www.99精品日操伊人乱碰在线| 婷婷操逼| 五月丁香婷婷综合久久| 大婷婷色呦呦噜噜色呦呦噜噜| 99热在这里只有免费精品| 在线观看996精品| 婷婷五月,综合伊人| 六月激情婷婷| 99热日本| 99碰超| 99激情视频| 欧美Va在线| 色婷婷婷av| 激情综合国产| av激情在线| 97人人干视频| tingtingcaobi| 久久精品99国产精品日本| 成人av播放| 26UUU精品一区二区| 五月丁香黄色| 99热这里只有精品最新网址| 丁香社区婷婷五月| 丁香五月天成人| 热99精品视频| 丁香激情五月天| 国产超碰在线| 国产精品色色| 夜夜夜叫天天天做| 色色五月天 亚洲| 婷婷伊人五月丁香天堂网| 99热66| 成人AV在线电影| 色九月婷婷丁香| 婷婷五月在线视频| 久久看婷婷| 91免费看片| 婷婷九月亚洲| 婷婷五月天久久久| 色五月av| 日本一级黄色片。| 激情丁香五月综合| 中文字幕第四色.999| 丁香五月伊人| 97性视频| 色综合婷婷| 国产激情综合| 国产,欧美,学生妹,视频| 风流少妇A片一区二区蜜桃| 欧美叉叉叉BBB网站| 久久精品A片777777| 日碰日| 久久这里只有精品视频15 | 丁香五月伊人| 色色欧美。| 婷婷丁香五月天之开心少妇| 久久狠婷婷| AV操逼网| 久久人妻爱爱| 开心激情网五月| 天天舔天天爽| www.91久久| 亚洲乱码日产精品BD| 婷婷中文字幕网站| 五月婷啪啪| 九九热精品| 五月丁香激情婷婷综合字幕| 成人性爱精品视频| 中文资源在线a | 开心五月激情婷婷| 色综合伊人网| 久热久| 婷婷欠久少妇| 五月丁香啪啪啪啪| 丁香五月欧美色综合| 99热地址| 中文字幕日产A片在线看| 亚洲AV成人精品网站在线播放| 亚洲成人网站在线| 五月天久久婷婷婷| 玖玖爱综合网| www超碰com| 成人在线精品| 欧美五月丁香| 精品国产乱码久久久久夜深人妻| A级毛片高清免费不卡播放谢谢谢谢| 中文字幕在线免费观看视频| aaa日韩| 五月丁香六月香香蕉| 国产黄大片在线观看画质优化| 色婷婷五月成人网| 热的无码综合视频| 成年人丁香五月| 婷婷五月综合免费在线| 99精品这里只有免费视频| 色色色色网| 国产精品99久久久久久久女警| 久久99精品久久久久久三级| 米奇影视五月天| 丁香六月啪啪| 日本人人干| 激情五月,深深爱五月| 午夜大香蕉| 极品九九九九九九| 五月丁香在线婷婷美女| 男女啪啪做爰高潮无遮挡| 色综合久久88色综合天天99| 无码字幕中文| 求可以看的AV网址| 天天插天天日| 色色婷婷五月| www.色五月.com| 久久艹网| www99热| 人妻丰满精品一区二区A片| 97在线/亚洲| 26uuu欧美日本| 欧美黄色一级录像| 2025天天爽天天摸| 曰韩少妇内射免费播放| 色五月婷婷丁香国产在线| 人人操AV| 99综合久久| 大香蕉欧美在线| 色丁香五月婷婷综合久久| 婷婷丁香激情五月| 激情综合网婷婷五夜| 五月丁香六月激情狠狠| 午夜成人片400| 精品婷婷五| 免费亚洲婷婷| 熟女激情网| 狠狠色综合网| 婷婷五月丁香在线观看| 欧美日本日韩| 久久五月婷天天干| 99ri精品在线观看| 综合色色色色色色| 成年视频免费观看| 欧美视频五区| 久草A片| 九九热黄色| 婷婷五月色| 日日色综合| 久久婷婷激情五月天一区二区| 婷婷激情六月| 婷婷在线午夜| AV在线不卡网站| 色偷偷色婷婷| 九九热视频99| 久久99视频| 天天色天天爱天天舔| 欧美成人精品A片免费一区99| 激情五月综亚网| 婷色天堂| 婷婷综合五月| 亚洲婷婷在线播放十月| 婷婷五月花| 激情婷婷五月基地| 99视频网址| 五月丁香啪啪| 天天摸天天高潮天天爽| 涩涩婷婷五月| 九九这里有精品| 久久久婷丁香五月| 日韩三及成人AV片| 激情五月天婷婷| 亚洲AAA| 激情婷婷五月天丁香| 日韩另类在线观看| 97五月天婷婷午夜| 91熟妇大香蕉| 欧美日韩99| 操逼123网| 影音先锋 一区| 亭亭五月色男人| 六月天六月婷| 超碰人人操人人干| 91干婷婷| 日韩成人精品中文字幕| www.狠狠干com| 亚洲一区国产传媒| 亚洲午夜在线视频| 亚洲精品视频在线播放| 欧美激情凹凸丁香网| 日本色99| 91久女| 九九青青草成人| 五月婷婷影视| 99久久99九九九99九他书对| 色婷婷av综合网| 久操婷婷| 九九热最新视频| 久久亚洲色导航| 婷婷六月色情| 日韩av手机在线观看| 久久色五月| 亭亭五月激情亚洲在线| 婷婷成人网五月天| 91色吧网| 五月丁香狠狠爱婷婷综合| 精品久久久人妻| 久久九九热视频| 五月天激情小说电影| 91视频久久久| 不卡成人免费| XX色综合| 日本欧美成人片AAAA| 久久看婷婷| 五月天激情www| 色视五月天婷婷| 五月香婷婷| 国产精品国产| 亚洲成人av在线观看| 精品夜夜澡人妻无码AV| www.色综合| 九九热精品视频| 热99re| 丁香五月成人论坛| 九九热这里只有精品556| 99久久五月天| 五月婷综合激情| 丁香五月综合网| 欧美色综合天天久久综合精品| 97干在线| 午夜婷婷| 91碰碰| 丁香六月激情四射| 六月婷婷色色色| 五月六月丁香激情| 精品五月天| 开心五月色婷婷综合开心网| 五月欧美色色五月| 婷婷开心综合人妻小说网址| 丁香五月天人体| 再次出发二| 婷婷丁香六月五月天| 丁香五月天啪啪| AV九九| 久久精彩综合视频| 丁香五月综合激情久久潮喷| 激情深爱婷婷网| 婷丁五月| 色婷婷欧美在线| 色播五月丁香综合| 丁香婷婷久久综合在线| 夜夜操,天天撸| 五月丁香在线综合| 色婷婷五月天视频网站| 久久这里只有精品热在99| 天天婷婷综合亚洲亚洲| 开心五月激情网| 操操自拍| av人人干| 九九九九精品精| 九九爱精品网站| 九九热99久久99| 丁香五月色网| 激情五月深爱五月观看| 亚洲天堂AAA| 丁香五月六月激情久久| 色婷婷激情| 五月丁香久久网| 五月激情在线| 天天干天天日蜜臀av| AV六月丁香| 国产avapp 网| 99热6这里之有精品| 天天干天天干天天干天天干天天| 操人妻视频91| 91综合国免费久入| 99国产精品白浆在线观看免费| 北条麻妃九九九国产精品视频| 婷婷新网址| 99视频久久| 婷婷丁香六月影视| 丁香五月婷婷香| 激情视频网址| av在线免费播放观看| 色9月| 99视频精品视频| 五月婷婷基地| 九九热在线观看视频| 九九九激情综合| 人人操 色| 影音先锋xfplay资源男人网| www.五月天激情| 色噜噜婷婷| 超碰婷婷五月| 99er日韩| 亚洲日日日| 任你爽视频| 92久操视频| 第四色色六月色综合| 亚洲色婷婷视频| 人妻操逼视频| 激情AV中文| 中文字幕丁香五月| www久久久久久久97| 中字幕视频在线永久在线观看免费| 九九人人看| 天天插轮理| 五月婷亚洲精品AV天堂| 久久月天堂| 五月丁香六月婷婷,婷| 五月天狠狠| 亚洲V国产V欧美V久久久久久| 成人在线网站| 狠狠色噜噜色狠狠狠综合久久成人波 | 婷婷月五天在线在线看| 婷婷综合在线| 操逼电影免费看| 夜夜人妻五月天| 婷婷激情六月综合| 人人操人人添人人摸97| 色婷五月丁香久亚洲| 99熟女| CAoub青青超碰| 99热精国产这里只有精品| 色色色热| 99久久九九| 丁香五月欧美色综合| 色色丁香婷婷五月天| 情欲综合网| 五月色婷婷综合| 超碰av天堂| 丁香五月天论坛| 丰滿爆乳一区二区三区| 激情合网婷婷| 色婷婷成人做爰A片免费看网站| 激情99热| 亚洲性视频| 久久综合婷| 99久久玖玖| 9九九久久精品无码专区| 中文字幕丁香五月| 欧洲色区| 五月婷婷天天色| 人妻少妇色综合| 成人精品在线| 五月天精品视频| 婷婷天堂站| 婷婷91| 欧美日韩999| 婷婷综合在线| 婷婷大香蕉| 丁香婷婷色五月激情综合| 91九九| 思思热99热| 99久久66| 国产成人精品一区二三区熟女在线| 欧洲婷婷五月天| 91综合在线| 久久婷出差欧美色两性综合网| 亚洲丁香花色| 蜜臀九九九九| www.99.色| 激情综合色播| 精品亚洲国产成AV人片传媒| 97操操操| 五月丁香在线视频观看| 在线观看国产高清视频免费网站| 狠狠五月丁香色婷| 超碰色碰碰| 五月天开心激情综合网| 超碰93在线观看| 激情五月综合网| 五月婷免费视频久久久| 九九九干精品| www.婷婷| 色色综合成人网| 黑人巨粗进入警花疼哭A片| 五月婷婷啪啪网| 99热色婷婷| 婷婷基地爱| 内射激情在线| 91综合色噜噜| 中文字幕成人| 天天日夜夜草进麻麻的子宫| 色级婷婷| 草草视频91| 天天射综合网天天插| 激情五月狠狠喔| 91干在线| 五月天婷婷久色| 国产三级在线播放| 色五月天激情| 思思久久思思| 九月综合| 日产精品一线二线三线芒果| 九九热这里只有精品6| 久久久婷| 日逼影音先锋男人资源站| 激情久久久久久久久久| 五月六月丁香婷婷在线观看| 99久久五月婷婷| 天天射综合网站| 欧美视频在线观看噜噜| 婷婷97碰碰| 欧美成人猛片AAAAAAA| 丰满人妻一区二区三区| 婷婷97狠狠干| 大香蕉人在线65| 青青草国产亚洲精品久久| 日韩啊啊啊| 色五月婷婷天天干| 丁香五月婷婷大香蕉| 婷婷成人五月天| WWW.17C亚洲精品| 激情婷婷丁香色五月综合| 久久婷婷人人| 色九九综合色| 看片视频在线免费日产在线看| 性色视频| 天天草天天爱| 99热这里都是精品| 综合另类激情| 色综合久| 色婷精品91| 婷婷五月天狠狠| 好好日激情五月天| 99色婷婷视频| 五月亭亭色| 日韩综合成人| 五月婷婷久久综合| 一区视频网站| 99久久极情精品一区| 综合网激情五月天| 99天堂网| 2020日日干| 精品AV无码超碰| 少妇人妻偷人精品无码视频新浪| 亚洲操人| 任你爽精品免费视频6| 丁香六月婷婷姐网| 婷婷深爱五月亚洲综合| 五月婷婷色播视频| 久久网日本| 婷婷爱五月| 久久亭亭电影| 97超级免费无码| 国产做爰视频免费播放| 丁香久久| 五月天婷婷基地| 激情图片五月天| 激情丁香社区| 亚洲无码播放| 激情床戏| 久久停停超碰| 玖玖无码中文| 色婷婷97| 91avse| www.henhenl| 五月天丁香成人| 久久色亭亭五月天| 日日噜噜夜夜狠狠久久丁香六月| 五月天色婷婷网| 手机免费福利视频| 婷婷五月色综合| 色性日本| 久久这里有精品视频在线免费观看| 天天噪夜夜爽| 五月天激情婷婷丁香| 亚洲精品色色色| 亚洲va欧美va国产综合久久久| 米奇影视资源婷婷狠狠色激情欧美五月丁香 | www 五月天 com| 丁香六月天婷婷色| 欧美英丁香开心快乐六月天网| ss99热| 婷婷深爱五月丁香网| 精品草原久久视频| 俺去也五月| 五月婷婷丁香六月| 操逼视频一区| 99在线观看| 婷婷久久综合| 色色色香蕉五月婷| 久久九九一區| 91九色中文字幕女在线观看| 久久99婷婷| 九九热再线九九视频免费在线观看| 久久综合热17c| 激情五月天网页| 99热.com| 99热天堂| 色五月婷婷五月天| 亚洲成人AV高清字幕| 婷婷综合玖玖五月| enecarbon-materials.comWu染请涟系Bao护@wip1688 | 久久婷婷五月天| 99成人| 91在线人| 成人五月天丁香| 丁香五色月婷婷网| 五月天涩涩| 亚洲黄色影视| 亚洲欧美在线观看| 天花AV无码| 久9热| 高清无码中文字幕aVDV| 99精品免费| 五月婷婷激情综合| 久久婷婷网址| 欧美六月| 色婷婷五月天小说网| 天天爱天天狠天天透| 九九热精品视频| 日韩AC在线免费观看| 日本一级特黄大片AAAAA级| 天天搞夜夜六| 亚洲热视频| 99热66| 日韩天堂久久| 梁铮版蜘蛛女在线观看| 777色色色| 亚洲五月天激情| 在线成人国产| 九九国产精视频| 久久六月天| 噼里啪啦在线观看免费完整版视频| 99热日本精品| 小视频在线亚洲| 欧洲色色| 久久久天堂国产精品女人| 久大香蕉| 欧美色色色色色色色| 九九这里有精品| www.爱婷婷.com| 9999热精品在线免费播放| 丁香六月综合| 精品欧美性爱超级爽| VA色婷婷| 久久怕怕视频| 婷婷在线中文字幕| 天天肏夜夜肏| 99久久这里只有精品| 操人妻AV| 婷婷激情五月天综合| 久久久久激情网| 97超级碰| 亚洲精品乱码久久久久久综合| 4438激情网| 一区操| 亚洲色色色色| 久久性爱视频| 九九热这里只有精品7| 五日激情综合| 久在线综合69| 丁香婷五月| 伊人久久艹| 91九色国产| 欧美狠狠色| 9l久久久视频| 俺去也在线www色官网| 91丨九色丨熟女高潮| 成人 在线 日韩| 日韩在线观看亚洲| 欧美男女婷婷| 丁香五月激情五月开心五月| 色欧美色色色| 天天色天天干天天插| 色色色热热热| 婷婷99| 五月激情啪啪| 亚洲综合视频在线| 99九九在线观看免费| 超碰精品国产首页| 丁香五月婷婷色情综合| 五月天大香蕉婷| 99色视频免费在线规看| 久久精品一区二区三区四区| 婷婷五月天xxx| 国产乱子轮XXX农村| 精品一二三区视频立| 99精品无码| 色综合色综合婷婷热| 六月婷婷综合| 五五月丁香花激情综合网| av大香蕉| 99热r| 日本色色色| 激情婷婷亚洲五月| 俺去也五月| 99精品网站| 五月激情综合婷婷| 深爱激情五月婷婷| 激情五月天99色| 色色99| 色婷婷综合久久久久| 婷婷午夜| 五月天激情偷拍| 99网| 情婷婷五月天| 亚洲人妻电影| 久久久久久激情| 99热乎| 精品影院| 涩婷婷五月天| 久久综合中文字幕| 国产无套精品一区二区| 99这里只有精品视频在线| 成人国产欧美大片一区| 人人舔天天| 伊人久久大香天蕉亚洲特级| 91色五月| 天天摸天天舔天天爽| 丁香五月婷婷色综合| 国产成人99久久亚洲综合精品| 玖玖婷婷婷丁香五月| 久久五月丁香| 狠狠狠狠狠狠狠狠狠狠狠色宗合图片| 激情五月天天| 神马欧美精| 天天骑日日爽| 一本到不卡高清DVD| 婷婷99狠狠| 偷偷狠狠久久婷婷五月天| 久久A极片| 中文av网| 激情综合五月激情17| 国产毛片操B| 黄网在线观看免费| 丁香五月婷婷性爱| 大鸡巴伊人网| 婷婷久月| 五月婷婷激情中心| 影音先锋一区| 一级片操逼视频| 亚洲网站999| 婷婷五月天国产手机在线视频观看| 色五月色开心开心五月| 亚洲视频二区| 26uuu欧美亚洲日韩| 狠狠se| 农村熟妇高潮精品A片| 深爱激情综合网| 激情宗合哪里能看| 97久操| 国内外色色色色色成人视频| 婷婷五月天视频亚洲| 伍月婷婷免费视频| 久久这里只有精品网| 五月丁香六月激情综合啪啪| 激情婷婷激情在线不卡| 操人无码| 99热首页| 色五月婷婷成人视频| 色yeye色综合| 色999亚洲人成色| www.夜夜操| 嫩草综合网| 欧美在线97| 涩丁香91| 丁香九月婷婷| 91干视频| 99热6色| 日本色婷婷五月天成人电影| 中文字幕综合| 婷婷日本在线| 1000部毛片A片免费观看| 香蕉婷婷色五月| 天天干狠狠艹| 五月丁香六月婷婷不卡免费无码 | 99视频只有这里精品| 成人精品一区二区三区四区五区| 99热欧美精品| 免费视频1区| 婷婷五月影院| 超碰99在线观看| www夜夜操| 99热视精品| 激情伊人六| 色五月婷婷婷婷婷婷婷婷婷婷| 99操免费视频| 日本情色一区二区| 碰99在线| 欧类av怡春院| 另类天堂| 亚洲激情综合| www久久久| 91se在线视频| xxxx久| 天天日夜夜| 五月婷婷在线视频| 天天天久久人人人合| 影音先锋人妻出差| 蜜臀九九九九| 婷婷深爱五月亚洲综合| 免费的日逼视频| 涩综合在线 | 五月天激情播播网| 99热在线观看| 成人在线网址| 五月婷网| 激情久久久久| 五月婷婷久久综合| 亚洲操逼网| 大香蕉AV在线| 伊人影音无码一区二区三区 | 天堂婷婷丁香六月网| 五月丁香六月欧美综合| 99这里只有免费的小视频在线观看| 五月天激情综合网俺也去| 狠狠香蕉| 五月丁香婷婷爱激情综合网| 六月丁香花婷婷| 欧美丁香婷婷天天操| 色色色99韩| 亚洲丁香五月美女| 婷婷之六月丁香| 99这里是精品| 色婷婷精品| 久婷婷色| 丁香六月综合激情| 中文字幕在线免费观看视频| 99免费视频| 色啪久| 日本三级毛片| 色综合久久天天综合网| 亚洲久热| 婷婷伊人激情婷婷| dingxiangtingtingliuyue| 玖玖热视频| 亚洲操逼片| 97干在线| 黄色av高清| 99久在线精品99re5热视频| 91碰| 欧美精品久久久久久视频观看| 亚洲色色精品| 激情五月天婷婷在线网址发给我| 99亚洲视频| 久久思思热| 69凹凸成人综合网| 五月丁香六月婷婷的女人| 8区视频在线| 天天色爽| 九九热视频精品| 色欲天天综合| 精品一二三区久久AAA片| 99久久婷婷精品视频| 大香蕉人在线65| 九色91视频| 超碰激情五月| 狠狠操狠狠爱| 久久婷婷五月综合| 日韩欧美四五区| 日本色婷婷| 色九月婷婷| 久久亭亭电影| 超碰在线91| 久99热| 久久久中文| 亚洲正能量欧美| 丁香六月久久| 狠狠狠狠操| 色婷视频| 五月丁香久久激情综合| 99超级碰碰| 激情五月亚洲综合网| 色香久久| 国产精品激情AV久久久青桔| 九九色院| 日本成人噜噜噜噜噜| 日韩成人AV在线播放| 无码少妇高潮喷水A片免费| 婷婷综合色网| 第四色婷婷色五月| 色色色色色色色色五月先| 伊人久久丁香婷婷六月五月综合| 丁香五月91| 九色视频九色九色91jiuseshipin| 日韩人妻在线观看| 亚洲人人操BD| 欧洲色色| 日韩精品一品二区三区的使用体验| 色国产五月| 色五月激情| 婷婷五月激情小说| 久久黄色网扯| 人妻激情综合| 久久五月热| 人人人人人人人人人草| 91视频一起草| 91亚洲视频| 五月激情偷拍婷婷| 五月丁香| 超碰在线免费9| 人人草人人视| 婷婷97狠狠成人网站| 在线视频另类| 日本婷色| 天天日日| 极品 少妇 内射| 天天操天天干天天日| www.99日本| 精品五月天| 好吊兆人妻| 五月丁香色五月| 色色无码| 另类图片天天影视在线观看| 俺去也婷婷| 69人人操人人爽| 五月丁香婷婷伊人| 亚洲欧美在线观看| 激情五月综合视频| 99热6这里只有精品| 国产精品视频免费看| 久久综合五月天| 中文成人在线| 五月丁香亚洲婷婷| 亚洲午夜国产成人电影VA国产欧…| 天天色综合色| 伊人综合网站| 性爱在线播放av| 四色永久成人网站| 密黄站| 中文字幕在线日亚洲9| 开心五月婷婷五月| 97天堂| 色色99| 伊人五月综合网| 91久热| 婷婷五月丁香六月| 《诡秘之主》在线观看| 亚洲色婷婷激情| AA丁香综合激情| 九九热这里有精品23| 色色无码| 嫩草综合网| www.色五月| 色六月视频| 97ai婷婷| 五月婷婷激情日本|