国产成人欧美一区二区三区vr_久久国产精品人人爽人人爽_国产精品永久免费播放_肉欲啪啪a∨无码精品一区二区_国产超短裙jk丝袜在线_亚洲AV片高清资源在线观看_国模无码一区二区三区久久_国产成年人未进视频_中文字幕无码精品夜_一区二区三区在线视频免费看_亚洲成AV人片在线观看网址_日本激情视频高清综合久久_亚洲午夜视频福利_国内大量揄拍人妻精品視_久久国产精品福利二区三区

ARTICLE DETAIL

資訊詳情

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

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

WPF界面框架分層實踐:主題Token、MVVM與換膚避坑 簡介面向 WPF 桌面應(yīng)用開發(fā)者的一套現(xiàn)代化界面框架源碼與示例適合希望擺脫默認(rèn)控件外觀、快速搭建統(tǒng)一視覺風(fēng)格的中級開發(fā)者參考也可作為團(tuán)隊 UI 規(guī)范與主題定制的基礎(chǔ)。壓縮包約 1.84MB共 336 個文件以 143 個 C# 源碼與 115 個 XAML 界面文件為主體另含 15 個 csproj 工程文件、圖標(biāo)與圖片素材、Visual Studio 項目模板及少量說明文檔覆蓋控件實現(xiàn)、窗口外殼、主題資源到可復(fù)用模板的完整鏈路。目前已有 6464 人學(xué)習(xí)下載。內(nèi)容圍繞現(xiàn)代化窗口、菜單、對話框與過渡動畫控件展開涉及主題外觀管理與系統(tǒng)版本適配等模塊可據(jù)此理解樣式模板、資源字典與 MVVM 在真實項目中的組織方式并直接改造為自己的應(yīng)用外殼。1. 一個漂亮的 WPF 界面框架漂亮之外到底解決什么問題上個月幫一個內(nèi)部工具做收尾功能全跑通了評審時被一句話打回來這套 WPF 界面看著像十年前的。真正動手改才發(fā)現(xiàn)難點不在畫得好看而在主色散落在二十多個 XAML 里、按鈕存在三套模板、每個窗口的標(biāo)題欄各寫各的。這份 WPF 界面框架源碼包就是把這堆散件整理成三層主題 Token、控件模板、窗口外殼再配一套 MVVM 骨架和若干示例頁。它主要解決兩件具體的事改一處顏色不用翻遍工程新頁面照著示例拼就能交付。適合正在用 WPF 做桌面端、要把界面從「能跑」推到「能驗收」的人不適合想找拖拽式設(shè)計器、指望完全不寫 XAML 的人。2. 拆目錄結(jié)構(gòu)主題 Token、控件模板、窗口外殼這三層怎么分拿到一個界面框架先別急著運行 Demo也別急著往自己的工程里復(fù)制。先看Themes目錄的層次因為它決定了后面所有覆蓋、換膚、定制動作能不能生效。這套框架的劃分是比較典型的做法Tokens放純值顏色、字號、圓角、間距、控件高度Controls放控件樣式與ControlTemplateSkins放皮膚覆蓋Shell放窗口外殼與標(biāo)題欄。分層的意義在于職責(zé)邊界清晰Token 里不該出現(xiàn)任何ControlTemplate控件模板里不該出現(xiàn)任何寫死的#2F6FED。我見過太多項目的資源字典是一個幾千行的Styles.xaml顏色、模板、動畫、轉(zhuǎn)換器全塞在一起。這種文件在項目第三個月就會變成黑匣子誰都不敢刪任何一行因為不知道刪了會影響哪個頁面。分層不是潔癖是為了讓你敢改。2.1 先看資源字典的合并順序它決定后面所有覆蓋能不能生效WPF 在MergedDictionaries里查找同一個 Key 時后加入的字典優(yōu)先級更高。這條規(guī)則很短但它是整套換膚機(jī)制的基石。很多人的皮膚切換做不出來原因就一個把皮膚字典加在了 Token 字典前面于是 Token 里的舊值一直勝出換膚看起來「沒反應(yīng)」。正確的合并順序是先 Token再 Controls最后 Skin。!-- App.xamlxmlns 省略實際工程里按模板生成的寫 -- 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是全局的窗口和控件會逐級向上查找一旦某一層出現(xiàn)了同名 Key上層的就永遠(yuǎn)取不到——調(diào)試時「樣式在別的頁面正常、就這個頁面不對」八成是這個頁面的Window.Resources里藏了一個同名項??绯绦蚣脮r路徑要改成 pack URI比如pack://application:,,,/YourApp;component/Themes/Tokens/Colors.Default.xaml程序集名寫錯的話運行時會拋IOException而不是編譯錯誤這也是常見的第一道問題。2.2 顏色、字號、圓角三組 Token為什么主色要用 DynamicResourceToken 層只做一件事把「設(shè)計決定」變成「命名常量」。這套框架里大致是三類鍵名前綴即語義分類示例 Key典型值說明顏色Color.Accent.Base#2F6FED主色另配 Hover、Pressed 兩檔顏色Color.Surface.Card#FFFFFF卡片、面板底色字號Font.Size.Body13正文另有 Caption 12、Title 18圓角Radius.Control6按鈕、輸入框統(tǒng)一圓角間距Space.Unit8所有間距取它的整數(shù)倍尺寸Metric.Control.Height32單行控件標(biāo)準(zhǔn)高度主色不要只給一個值Hover 和 Pressed 要手調(diào)出來別用Opacity疊。原因是透明疊加的結(jié)果依賴背景色同一個按鈕放在白色卡片和深色側(cè)欄上淺色疊加出來的效果完全不同深色背景上會發(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 單獨一層控件模板里用 Brush換膚時只換 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/ !-- 字號與度量數(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直接寫元素即可不用額外命名空間。現(xiàn)在說DynamicResource和StaticResource怎么選這是最常被問的一個問題。結(jié)論是會隨皮膚變化的 Key 用DynamicResource永不變的 Key 用StaticResource。StaticResource在 XAML 解析時就把值取出來定死換膚后不會重新求值所以把主色用StaticResource引到模板里切皮膚必然失敗DynamicResource每次取值走一次資源查找會帶來額外開銷在DataGrid單元格模板、ItemsControl項模板這種會實例化成千上萬次的地方能靜態(tài)就靜態(tài)。我的習(xí)慣是Token 里跟顏色相關(guān)的全用DynamicResource字號、圓角、間距這類換膚不動的用StaticResource。這個劃分一句話能記住后面維護(hù)的人也不會亂改。2.3 拆一個按鈕從 Token 到 ControlTemplate 的完整鏈路理解了層次再拆一個具體控件看看這套框架里一個主按鈕是怎么拼起來的。這段值得逐行讀因為它是后面所有控件的模板。!-- 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)先級更高 -- 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這里有幾個容易被忽略的細(xì)節(jié)每一個都可能變成后期幾分鐘甚至幾小時地去排查的問題。第一TemplateBinding是單向的、不支持轉(zhuǎn)換器且只能綁到模板化父級的屬性上。所以Padding能綁Background能綁但如果你想把Background轉(zhuǎn)成漸變就必須換成{Binding Background, RelativeSource{RelativeSource TemplatedParent}}再掛 Converter?;煊眠@兩者時不要抱有僥幸心理模板里一旦出現(xiàn)轉(zhuǎn)換需求就整體換成Binding。第二觸發(fā)器順序決定最終效果。IsMouseOver和IsPressed同時為真時后定義的IsPressed生效所以按下色必須寫在懸停色后面。反過來寫按下時看到的還是懸停色看起來就像「按下沒反饋」。第三IsEnabledFalse時如果只改OpacityCursorHand依然生效鼠標(biāo)移上去還是手型用戶會以為可以點。所以禁用態(tài)要順手把Cursor也改回來這類細(xì)節(jié)在驗收時最容易被挑出來。最后控件模板里不要出現(xiàn)字面色值這是硬性約束。只要模板里出現(xiàn)一個#2F6FED換膚那一刻它就會變成色塊不一致的元兇而且很難靠肉眼定位到具體是哪個模板。框架里這類違規(guī)用一次文本搜索就能找出來接入前先搜一遍#順手清理掉。3. 接入現(xiàn)有工程從復(fù)制目錄到跑出第一個頁面3.1 目錄落位與 csproj 里的資源聲明把整個工程復(fù)制進(jìn)來是最快的驗證方式但真正接入現(xiàn)有項目時建議只復(fù)制Themes和Infrastructure兩個目錄示例頁按需挑選著拿。目錄放在項目根下即可不要塞進(jìn)Properties或者obj旁邊obj目錄在清理時容易誤刪。csproj這塊有個高頻問題SDK 風(fēng)格工程的默認(rèn) glob 已經(jīng)把**/*.xaml編譯成Page你再手寫一遍Page IncludeThemes\**\*.xaml /就會報重復(fù)項NETSDK1022。所以大部分情況下什么都不用寫只在需要排除或者改變構(gòu)建方式時才動它。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)建項的選擇直接決定資源能不能取到這張表建議存下來構(gòu)建項編譯結(jié)果適用場景取用方式Page編譯為 BAML所有 XAML包括資源字典Source相對路徑Resource嵌入程序集字體、圖標(biāo)、小圖片pack://application:,,,/程序集;component/路徑Content原樣復(fù)制到輸出目錄示例數(shù)據(jù)、可替換配置相對輸出目錄的路徑None不處理文檔、說明無字體用Resource嵌入之后在 XAML 里通過FontFamily/Assets/Fonts/#字體內(nèi)部名引用注意斜杠后面那個#后面跟的是字體家族名不是文件名。寫錯了不會報錯只會靜默回退到系統(tǒng)默認(rèn)字體——這類靜默失敗最耗時間。3.2 App.xaml 合并字典與運行時換膚皮膚切換不要用「先清空再添加」的寫法。清空MergedDictionaries會在瞬間讓所有DynamicResource失效控件重繪時可能拋出找不到資源的異常而「只添加不移除」會讓字典越積越多切換五十次之后內(nèi)存和查找開銷都會肉眼可見地上漲。正確做法是把皮膚字典固定在MergedDictionaries的最后一位換膚就是替換這一項。public static class ThemeManager { // 皮膚字典固定放在 MergedDictionaries 的末位替換這一項即為換膚 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; } }替換完成后不需要手動刷新任何控件DynamicResource會自動重新求值。這里有個前提所有隨皮膚變化的引用必須是DynamicResource只要模板里漏了一個StaticResource換膚后那個控件就會保持舊色在一片新配色里顯得很突兀。還要注意換膚的時機(jī)。啟動時在App構(gòu)造函數(shù)里調(diào)用是最穩(wěn)的如果放在窗口Loaded之后用戶會看到一次明顯的閃爍。真想做到無閃爍就得在窗口顯示前把皮膚定好也就是把配置讀取提前到App初始化階段。3.3 無邊框窗口外殼與自定義標(biāo)題欄這套框架的外殼用的是WindowChrome而不是WindowStyleNone加AllowsTransparencyTrue。后者雖然也能做出無邊框效果但會讓窗口失去硬件加速路徑拖動和縮放時明顯發(fā)澀圓角邊緣還會有鋸齒。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否則點不到 -- 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三個參數(shù)決定了使用手感。CaptionHeight要和標(biāo)題欄那一行的高度嚴(yán)格對齊寫 40 就是 40寫小了頂部會剩一條既不能拖也不能點的死區(qū)ResizeBorderThickness在鼠標(biāo)場景 6 夠了觸屏設(shè)備建議 8 到 10否則邊緣拖不動GlassFrameThickness0去掉系統(tǒng)玻璃層避免深色皮膚下邊緣發(fā)亮。標(biāo)題欄里的按鈕必須加WindowChrome.IsHitTestVisibleInChromeTrue這一條不加按鈕會變成「看得見點不著」鼠標(biāo)事件被拖拽區(qū)吃掉了。這是無邊框窗口最常見的一個問題排查時容易往命令綁定上想繞一圈才發(fā)現(xiàn)是命中測試。另一個是最大化蓋住任務(wù)欄。無邊框窗口最大化時系統(tǒng)給的尺寸包含非工作區(qū)直接鋪滿會頂?shù)羧蝿?wù)欄。簡單的做法是在窗口構(gòu)造里設(shè)MaxHeight SystemParameters.MaximizedPrimaryScreenHeight多顯示器場景下這個值只在主屏正確需要監(jiān)聽WM_GETMINMAXINFO自己算工作區(qū)框架的Shell目錄里有對應(yīng)的輔助類接入時按屏幕數(shù)量確認(rèn)一下。3.4 驗收入口DPI、縮放、多屏的檢查清單界面框架接進(jìn)去功能點兩下都正常不代表能交付。下面這張表是我每次接入必過的一遍成本不到十分鐘能提前擋掉大部分返工。檢查項操作不通過的表現(xiàn)單屏 100%系統(tǒng)縮放調(diào)到 100%逐頁翻一遍1px 邊框消失或變粗單屏 150%縮放到 150%看文字與圖標(biāo)文字發(fā)虛、圖標(biāo)模糊多屏不同縮放兩屏分別設(shè) 100% 和 150%拖窗口來回拖到另一屏后整體變糊高對比度切換系統(tǒng)高對比度主題文字與背景同色看不見觸摸觸屏設(shè)備上點邊緣縮放邊緣拖不動最小尺寸拖到最小寬高標(biāo)題欄按鈕被擠出可視區(qū)DPI 那一欄解釋一下WPF 是邏輯像素體系縮放變化時如果圖片資源只準(zhǔn)備了一份系統(tǒng)會拉伸結(jié)果就是模糊。圖標(biāo)盡量用矢量路徑位圖則按 100%、150%、200% 各備一份靠Image的尺寸選擇邏輯去匹配。這條不做用戶在 150% 縮放的筆記本上第一眼就會覺得「這軟件有點舊」。4. MVVM 骨架命令、通知、導(dǎo)航與對話框怎么切界面層的活干完接著看骨架。這套框架的Infrastructure目錄里放的是一套很薄的基礎(chǔ)設(shè)施ViewModelBase、RelayCommand、AsyncCommand、導(dǎo)航服務(wù)、對話框服務(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省掉了手寫屬性名字符串改屬性名時不會漏改通知。相等判斷用EqualityComparerT.Default而不是因為泛型里對值類型是裝箱比較屬性高頻更新時這點開銷會積少成多。返回bool是個很實用的小設(shè)計if (SetProperty(ref _name, value)) OnPropertyChanged(nameof(DisplayName));這樣派生屬性只在真正變化時通知避免無謂的綁定刷新。老項目里常見的寫法是 setter 里連續(xù)調(diào)三次OnPropertyChanged每次輸入都觸發(fā)一輪完整重算。集合屬性是另一個問題點。ObservableCollectionT不要每次賦值都new那等于讓ItemsControl重建整個視圖樹滾動位置會跳回頂部。正確做法是初始化一次之后用Clear()加Add()更新。4.2 RelayCommand 與 AsyncCommandCanExecute 刷新時機(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; } // 手動觸發(fā)異步命令結(jié)束、集合變化后必須調(diào) public void RaiseCanExecuteChanged() CommandManager.InvalidateRequerySuggested(); }CommandManager.RequerySuggested是隱式刷新只在鍵盤、鼠標(biāo)等輸入事件之后觸發(fā)。這意味著如果你在后臺線程里改了某個標(biāo)志位按鈕的可用狀態(tài)可能要等到用戶點一下別的地方才更新。血淚經(jīng)驗是異步命令執(zhí)行完畢、批量數(shù)據(jù)加載完成這類時刻必須顯式調(diào)一次RaiseCanExecuteChanged()否則用戶會看到「按鈕還是灰的但功能其實已經(jīng)好了」。異步命令額外要處理兩件事。一是防重入執(zhí)行中把CanExecute置為false避免用戶連點三次發(fā)出三個請求。二是異常兜底async void里拋出的異常會直接打到未處理異常上進(jìn)程就掛了??蚣芾锏腁syncCommand用try/catch包住執(zhí)行體把異常交給注入的錯誤處理器再由它彈提示。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)航與對話框接口怎么切才不綁死 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); }實現(xiàn)側(cè)常見的做法是用一個覆蓋全窗口的ContentControl加半透明遮罩把對話框內(nèi)容當(dāng)作普通控件渲染返回值靠TaskCompletionSourcebool在用戶點擊時SetResult。這樣對話框也吃同一套 Token深色皮膚下不會出現(xiàn)一個白底黑字的系統(tǒng)彈窗視覺上跳出來。這里要提醒一點TaskCompletionSource必須用TaskCreationOptions.RunContinuationsAsynchronously否則SetResult會在 UI 線程上同步跑完整個await后續(xù)邏輯遇到重活就卡界面。這個問題非常隱蔽表現(xiàn)為「點確認(rèn)之后界面頓一下」把選項加上就好。5. 避坑記錄樣式不生效、內(nèi)存上漲、DPI 模糊的排查順序這一章是這份框架里最值得先讀的部分。下面四條都是我在真實接入里遇到過的每一條按現(xiàn)象、原因、解決的順序?qū)懹龅酵悊栴}時可以照著順序查。5.1 現(xiàn)象改了 Token控件紋絲不動現(xiàn)象把Color.Accent.Base從藍(lán)改成橙重新生成主按鈕還是藍(lán)的。清緩存、重啟 IDE 都試過仍然是藍(lán)。原因控件模板里引用的是{StaticResource Brush.Accent.Base}。StaticResource在 BAML 解析階段就把值取出來寫死了后續(xù)字典變化對它沒有任何影響。另一種可能是這個頁面的Window.Resources里定義了一個同名的Brush.Accent.Base局部作用域優(yōu)先全局的改動被它遮住。解決在解決方案里搜StaticResource Brush.凡是顏色類的引用全部換成DynamicResource再逐頁檢查Window.Resources和UserControl.Resources里有沒有同名 Key。這兩步做完改動立即生效。我的習(xí)慣是把這條寫進(jìn)代碼評審清單模板里出現(xiàn)StaticResource后面跟Brush.前綴的一律打回。5.2 現(xiàn)象切幾次皮膚內(nèi)存一路往上走現(xiàn)象在設(shè)置頁反復(fù)切換淺色和深色任務(wù)管理器里的內(nèi)存從 180MB 漲到 400MB 不回落切得越多漲得越多。原因換膚實現(xiàn)寫成了merged.Add(skin)每次切換都往MergedDictionaries里追加一個字典舊字典既沒被移除也沒被回收資源查找還得從后往前遍歷一長串。另一個隱性原因是畫筆沒凍結(jié)SolidColorBrush每次創(chuàng)建都是新的可凍結(jié)對象沒調(diào)Freeze()就參與變更通知無法被共享。解決換膚改成替換末位元素見 3.2 的寫法Token 里所有SolidColorBrush在創(chuàng)建后調(diào)一次Freeze()凍結(jié)后的畫筆可以被多個控件共享內(nèi)存占用會明顯下降。改完再測反復(fù)切換五十次內(nèi)存曲線基本走平。提示Freeze()只能用于可凍結(jié)對象而且凍結(jié)后不能再改屬性。如果某個畫筆需要在運行時調(diào)色就別凍結(jié)它。5.3 現(xiàn)象4K 屏上字體發(fā)虛、1px 邊框消失現(xiàn)象開發(fā)機(jī) 100% 縮放一切正常換到 150% 縮放的筆記本上正文明顯發(fā)糊卡片之間的 1px 分隔線時有時無圓角處還有毛邊。原因三個疊加問題。位圖圖標(biāo)只準(zhǔn)備了一份系統(tǒng)拉伸導(dǎo)致模糊Border的BorderThickness用了1但沒開UseLayoutRounding和SnapsToDevicePixels在非整數(shù)縮放比下 1px 被攤到兩個物理像素上顏色被稀釋到看不見再就是窗口設(shè)了AllowsTransparencyTrue透明窗口在部分縮放下失去硬件渲染路徑。解決圖標(biāo)改用矢量路徑在外殼根元素上開UseLayoutRoundingTrue需要像素對齊的Border和Image加SnapsToDevicePixelsTrue無邊框窗口換回WindowChrome方案。三條一起改150% 下再對比截圖邊緣和文字都恢復(fù)銳利。5.4 現(xiàn)象設(shè)計器里正常運行時拋 XamlParseException現(xiàn)象XAML 在設(shè)計器里預(yù)覽得好好的一運行就拋XamlParseException提示找不到某個資源堆棧指向一個看起來沒問題的Setter。原因StaticResource的解析是編譯期決定的它只能向前查找——引用必須出現(xiàn)在定義之后或者定義在更早就合并的字典里。設(shè)計器有時會更寬松地加載于是出現(xiàn)「設(shè)計器能看、跑起來就崩」。另一種原因是跨程序集引用時 pack URI 里的程序集名寫錯編譯期不校驗運行時才爆。解決先在App.xaml里把 Token 字典排在最前面確保所有模板在后面再檢查所有跨程序集的Source程序集名、大小寫、component關(guān)鍵字都要對上。定位技巧是把App.xaml里的合并字典臨時注釋掉一半二分法很快能鎖定是哪個文件。5.5 常見問題速查表癥狀第一嫌疑快速驗證換膚后個別控件不變色模板里用了StaticResource全工程搜StaticResource Brush.按鈕點不動標(biāo)題欄命中測試被吃檢查IsHitTestVisibleInChrome最大化蓋住任務(wù)欄無邊框窗口的尺寸計算看MaxHeight是否按工作區(qū)算列表刷新后滾動條跳頂集合被整體new檢查ObservableCollection賦值處命令按鈕一直灰隱式刷新未觸發(fā)手動調(diào)一次RaiseCanExecuteChanged字體不是預(yù)期那個FontFamily的家族名寫錯核對#后面是家族名而非文件名6. 進(jìn)階把換膚做成可以回歸驗證的流程界面類的改動最難驗證因為它「看起來沒問題」和「確實沒問題」之間差得很遠(yuǎn)。這套框架里我最常用的一個技巧是把換膚做成可以對比的回歸流程。第一步把 Token 抽出來做一份中間格式??蚣艿腡okens目錄本身就是鍵值對用幾十行代碼掃一遍 XAML把Color.*、Font.Size.*、Radius.*導(dǎo)出成 JSON交給設(shè)計側(cè)對齊。之后設(shè)計師改配色改的是這份 JSON工程師用腳本回寫 XAML比在群里發(fā)色值截圖靠譜得多。回寫腳本要注意保留原有的x:Key順序和縮進(jìn)否則每次生成都是幾百行 diff評審時沒人看得下去。第二步準(zhǔn)備一個「Token 全覽頁」。把所有 Token 渲染成色塊、字號樣例、圓角樣例配上鍵名放在調(diào)試菜單里。換膚以后直接翻這一頁哪個鍵沒被覆蓋一眼就能看出來。這個頁面我一般不到半小時就能拼完但省下來的排查時間遠(yuǎn)超投入。第三步截圖比對。把關(guān)鍵頁面在淺色和深色下各截一張存在版本庫里改了樣式之后重新截用逐像素差值定位變化區(qū)域。閾值不要設(shè)在零字體渲染有亞像素抖動允許千分之三以內(nèi)的差異超過就是真改了。這套流程跑順之后改一個 Token 影響哪些頁面提交前就能知道。還有一個小習(xí)慣值得說一下每次接入新的界面框架我都會先在空工程里跑一遍它的 Demo把所有頁面點一遍重點看深色皮膚下的對比度和禁用態(tài)。原因很簡單這些地方最容易藏問題而在自身工程里樣式問題會被業(yè)務(wù)邏輯掩蓋很難判斷到底是框架的問題還是你寫錯了。從那以后我每次往項目里引 UI 框架都強制先走一遍這套空工程驗證再動業(yè)務(wù)代碼。希望幫到你。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
天欧美在线| 少妇厨房愉情理伦片bd在线观看| 91亚洲综合| 又粗又长又爽在线观看| 欧美暴力猛交| 欧美特大AA级黄片| 欧美 中文字幕 一区| 91美女视频电影| 中文字幕日韩专区精品系列| 69超碰综合| 久久精品成人一区二区三区蜜臀| 岛国爱情动作片在国产AV无码专区亚洲AV漫画| 久久中文字幕一区不卡| AV丝袜东京热| 明星性猛交ⅹxxx乱大交| 国产97视频免费观看| 九九九久久久久| 在线视频免费观看午夜| 男人天堂2019亚洲| 国产精品乱码久久久| 老司机射| 黄页网站成人免费| 国产精品色片一区二区| 91久久久久| www.久久最新地址| 欧美超碰人妻97| 久久青青草原免费视频| 亚洲天堂久| 欧美日本一区二区a人| 中文字幕午夜精品久久久| 九月激情婷婷| 免费男人的天堂| 国产人妖视频一区在线观看| 91老熟女老女人国产老太| 国产精品精品系列在线观看| 天天色怡春院| 国产女人和拘做爰视频| 97在线观看视频| 97福利视频| 天天综合91| 欧美一区二区成人一卡| 日本色色色视频| 国产精品农村妇女| 欧美日韩国产男人| 国产精品熟女乱伦| 玖玖爱在线视频免费观看| 极品久久久久久久久久久久久久| 在线人人人人人人精品超| 极品少妇久久久久| 天美一二三在线观看Av| 国产三区免费在线观看| 色九久| 成人精品视频一区二区| 亚洲成A∨人影院在线欢看| 亚洲天堂另类| 97视频620| 曰韩成人免费视频| 蜜臀无码视频在线观看| 久操视频在线| 操人妻逼91| 自慰白浆在线观看| 国产宅男宅女在线观看| 国产 日韩,欧美 自拍| 大香蕉欧美国产日韩高潮| 五月天激情四射| 一区操逼| 日韩高清黄片| 蜜乳AV免费观看| 国产熟女高潮一区二区三区| 亚洲男人的天堂网| 亚洲激情色片 | 91操熟女| 啊啊啊啊无码| 国偷自 一区| 97国伦国色| 亚洲精品视频在线播放| 欧美精品99久久久**| 色淫网站优优视频| 亚欧美色图| 国产人伦精品一区二区三区| 人妻久热在线| 超碰免费在线| 欧美精品999| 亚洲国产精品有声| 亚洲精品国产精品乱码不99| 国产精品一区二区黄片| 中国乱伦一区二区| 欧美日韩操逼动图| 国产一在线观看| 免费操逼91| 激情文学亚洲| 日韩人人精品| 色69大色97香蕉| 九九亚洲色在线观看| 蜜桃中文字日产乱幕4区| 97在线精品| 人妻系列无码专区中文有码| 亚洲?V无码专区在线电影| 女性91网站| 亚洲图片 欧美电影| 天天干夜夜肏| 亭亭在线资源| 综合亚洲欧美| 久热这里只有精品9| k频道色撸撸| 欧美亚洲国产日本在线,久久精品国产| 久热伊人99re| 亚洲一区二区三区麻豆传媒| 校园春色综合色| 97视频网站在线观看| 亚洲人妻一区二区三区| 九九久久九九久久| 91jk色拍| 美女黄码视频午夜| 人妻无码一区二区三区久久99| 色九九九综合| 天美麻豆黄色录像| 欧洲亚洲人妻无码久久三区四区| 欧美 色 亚洲| 永久电影三级在线观看| 极品综合| 国产 丝袜 欧美中文 另类| 九九色图| 国产a级精品| 999综合色| 亚洲日本天堂| 亚洲综合九九| 日韩av不卡在线观看| 欧美日本国产日韩激情视频| 凹凸视频特色日本特黄| 天天影视色香色欲| 激情内射| 大香蕉久久| 成年人黄色视频免费| jk白丝没脱就开始啪啪| 天天做天天爽| 蜜桃丰满熟妇av无码区不卡| 婷婷国产精品一区二区| 开心五月婷婷| 日少妇亚洲版| 福利天堂| 国产精品乱码久久久| 男人天堂2017| 凸凹视频在线观看| 九久久九精品视频| 91青青在线视频| 72av视频| 国产成年女人免费视频播放a| 一本一道vs波多野结衣| 国色天香av| 啊操爽品善一区二区三区| 欧美色图在线视频少妇| 日韩有码 一区二区三区| 久久毛卡| 九九九久千久久激情蜜桃在线看| 青青欧美| 亚洲三区视频| 97国产精品国| 亚洲欧洲自拍| 亚洲欧洲综合视频在线| 亚av顶级裸体一区二区三区四区五区| 91bbb| 国产成人www免费人成看片| 91久精品| 欧美碰碰综合色| 日韩 欧美 另类 人妻| 加勒比在线视频| 天天情欲宗合网| 大肥女高潮bbwbbwhd视频| 天堂中文资源在线bt| 久久女人视频| 外国91| 亚洲色 国产 欧美 日韩| 激情五月综合网| 北京美女一区二区| 波多野结衣之双飞调教在线播放| 久久99综合| 亚洲色入欧美| 都市久久精品激情亚洲| 一区二区三区男女操逼黄色小电影| 老女人91| 91爆操视频| 天美一二三在线观看Av| 免费视频一二三区| www.色婷婷| 51一区二区三区| 日本午夜操逼| 91 亚洲情侣偷拍 久久| 丰满美女一级毛片在线播放| 丰满少妇一区二区三区四区观看| 青青草久草| 乱色视频中文字幕| 日日爽熟女| JIZZJIZZ国产精品喷水| 懂色av中文字幕一区二区三区天美 | 粉嫩国产精品久久粉嫩| 啊啊啊慢点| 日本岛国黄色网址| 上床啊啊啊| 日本熟妇人妻中出视频| 中文字幕无码不卡啪啪| 不卡啪啪视频| 外国免费性情大片| 18精品一区| 无码天堂| 9999亚洲精品| 不卡啪啪视频| 亚洲日韩人妻中文字幕一区| 亚洲日本男人天堂网| 色色毛片| 欧美视频激情久久久久久| 免费中文综合精品| 熟女一区二区三区| 日韩国产成人自拍视频| 超碰诱惑| 丝袜狠狠草尤物人妻av91| 人人操人人色网| 日韩少妇丰满亚洲| · —级AA伦aa坐爱午夜极速ⅴA一区天天噪天天噪天天噪 | 欧美疯狂做爰xxxx| 91丝袜视频在线观看| 久久男人的天堂国产| 亚洲欧美色图片| 成人久久无码www| 国产精品久久久久无码A√| 欲色啪| www99热| 中文字幕第9页萱萱影音先锋| 91撸色网 玖玖网 欧美| 精品v日韩欧美国产| 97se亚洲| 91撸色网 玖玖网 欧美| 日韩黄色一区二区三区| 久久超碰国产一区二区三区| 亚洲欧美综合网站| 亚洲色图欧美色图制服丝袜| 亚洲天堂7777| 日夜伊人网| 欧美熟妇人体| 夜夜草网站| 97 国产精品| 白丝被操91| 高潮综合网| 天天天天天天天天天天干美女| 99精品无码| 天天色悠悠激情| 欧美性生活男人的天堂| 91熟女少妇| 亚洲综合网电影91| 国产精品香蕉热久久新品| 久久丝袜| 97欧美色| 东北女人的毛片| 久久久国产亚洲精品系列| 九九五月天| 91女网站| 熟女视频久久| 豆花视频操逼网址 | 国产成人久久久精品免费AV| 成全动漫视频观看免费下载| 麻豆天美在线| 色亚州人久干视频在线观看免费版| 九九黄色网| 成人无码在线视频网站| 久久线上视频免费看| 97色97好| 一区二区三区网站日日骚| 日韩av一级黄片| 午夜亚洲WWW湿好大| 综合亚州欧美| 国产日韩中文字幕欧美| 精品999日本| 欧美精品人妻视频| 大胆91| 男女激情黄色网址| 秋霞成人一级在线观看| 日韩无码一级黄色av片| 天天干人人乐| 日本欧美不卡| 男人天堂毛片| 肥佬影院91| 国产精品69久久久久久久| 美女AV一区二区| 国产乱婷婷精品二区三区| 国产无马av| 欧美亚洲中文字幕| 天天躁日日躁XXXXYY| 亚洲 欧美 偷拍 唯美| 日韩成人私密一级精品av| 操东北女人| 超碰免费人妻在线| 男人午夜天堂| 久久久久亚洲Av无码专区老牛影视| 久久久久久无码人妻中文字幕| 国产情色第一第二页在线观看| 国产精品制服丝袜中文字幕日韩一区二区三区 | 国内一级精品| 国产精品农村妇女| 亚洲图片另类| 亚洲婷婷丁香在线| 日韩免费福利在线观看| 日韩av免费一级电影| 日本孕妇一区二区视频操逼免费看 | 九九英色视频| 鸥美插入视频| 亚洲欧美91√| 中国韩国明星一极片一区乱码毛片人妻熟女一区二区三区 | 人人操人人搞人人草| 日韩簧片免费看| 在线播放成人高清免费视频| 国产欧美精选激情视频| 日本一本道A级黄色毛片试看60分钟| 18禁美女裸体无遮挡啪啪| 国产一在线观看| 老熟妇一区二区三区…| 久久婷婷五月天| 玖玖97综合 | 亚洲综合色男人网| 日韩AV色图| 中文字幕人妻色偷偷久久皮| 激情小说亚洲视频| 日日躁天天躁狠狠躁| 91爱| 少妇啪啪自拍| 九九色逼| 伊人青青草久久| 日本精品久久久久久久| 久久精品国产亚洲av水密被窝| 97精品一区二区三区免费| 精品国产三级av韩国在线| 美女操逼A A| 久久美女国产| 狠狠爱综合网| 偷拍在线观看视频| 久久69| 国产探花精品在线| 91爱综合| 青青草原成人| 强奸乱伦AV一天堂网| 亚洲成熟国产精品美女| 九九热免费国产视频婷婷伊人| 亚熟在线| 青青久久艹| 8x福利精品第一福利视频导航| 天天精品| 最新精品久久蜜桃| 亚洲成成熟女人综合一区二区| 国产强奸乱伦欧美| 日本午夜久久电影| 96国产污污污丝袜| 久久久久亚洲Av无码专区老牛影视 | 亚洲黄色网址| 老熟妇乱轮| 深田咏美亚洲精品福利社| 91啪9色| 久99在线免费观看视频| 欧美日韩一区二区三区四区蜜桃| 欧美人妻精品| 国产夫妻性生活视频| 台湾一区国产高清在线| 婷婷五月综合激情| 欧亚揄拍偷拍精品视频| 国产成人午夜视频网址| 午夜福利久久久噜久噜久久综合| 日本 情色 1区2区3区| 日韩一级欧美一级国产一级台湾| 亚洲精品美女久久久久久久久| 色婷婷在线视频精品导航| 天天肏夜夜肏| 秋霞影音一区二区三区| 亚洲男人的天堂在线看| 热99这里有精品综合久久| 国产女人91精品嗷嗷嗷嗷| 99青青草国产视频| 91一区二区三区蜜桃| 99色视频| 国产999精品久久久| 乱伦系列一区二区| 国产久久久久影院老熟女| 欧差乱伦二三| 久久最新免费视频23| 91熟女丨老女人| 欧美婷婷五月天| 后入式五六区| 国产自偷自拍一区| 一二三区视频在线观看| 丁香五月天堂| 91日韩国产欧美亚洲另类精盘州至城都| 欧美人妻精品一区二区| 日韩精品电影| 国产欧美岛国精品一区| 色综合久久夜色精品国产天堂| 久久这里只精品免费福利| 久久久久久久久久久久久9999| 99热这里只有精品18| 婷婷五月天影院| 中文 人妻 制服| 啊…啊…操我用力操我| 欧美色就是色| 一区二区三区无卡视频在线观看| 一起草欧美| 国产成人天堂| 人妻乱仑一区二区三区| 丰满少妇精品一区二区| 午夜天堂精品久久久久91| 久久人妻熟女一区二区| 日本精品人妻少妇一区二区| 免费一级a毛片久久久久久鸭绿欲| 成人日韩中文字幕| 国产精品蜜乳AV| 啊啊啊轻点在线观看| 丁香婷婷大香蕉| 欧亚日韩中文在线| 91天天综合网,天天综合网| 精品久久久久久AV无码| 天天爽入口| 亚洲综合激情五月久久| 久96热在线观看视频| 在线黄色污污网站| 欧美,日韩,亚洲视频| 久久久久女教师免费一区| 久久久久免费少妇| 强奸乱伦免费网站| 亚洲色图欧美色图综合| 欧洲中文字幕| 在线国产探花| 欧美综合国产精品久久丁香| 天天操天天日天天干| 色色婷| CCYY草草影院地址入口| 亚洲色图欧美色图制服诱惑| 正在播放:深夜激情大战,自带黑丝袜全力输出骚穴 | 中文一区二区| 夜夜嗨AV一区天天| 九九久久一区二区伦理| 亚洲色电影在线| 欧美激情一区二区| 99热这里是精品| 日本色色视频网站| 久热热| 久久亚码| 亚洲综合在线高清| 91操碰| 狠狠操官网| 猛猛干| 中文字幕乱偷人妻久久艾草网| www.色婷婷.com| 午夜一区二区三区国产| 欧美乱伦专区| 另类小说欧美激情校园春色| 欧美在线视频播放| 日本三级日本三级三级人妇四虎| 99色色网| 国产懂色精品国产av| 国产精品内射婷婷一级二| 一二区在线观看视频| 91久久久视| 久操国产在线| 亚洲色综网| 天天舔九色婷婷| 992这里有精品| 蜜乳AV一区二区三区四| 三级激情网站| 亚洲无码com| 神马麻豆福利院| 中文字幕欧美日本乱码一线二线 | 午夜理论片在线观看免费| 成人小说另类在线| 国产福利合集| 久午视频| 天天干夜夜鈤| 伊人欧美大香蕉视频| 欧美一区二区三区黄色影视| 色噜噜人妻丝袜AV资源| 欧美精品久久96人妻无码| 这里只有精品视频| 婷婷综合网| 久久人人爽人人爽人人片Ⅴ| 黄片aaaaa一区| 日本成人A片免费看| 日韩熟女操逼| 国产精品女生av| 伊人五月天婷婷| 2023天天操夜夜操| 久久久性| 超91综合网| 亚洲欧美激情小说| 99精品免费| 思思热一热婷婷热一热| 亚洲精品人妻在线| 久久网亚洲| 大香蕉伊人久久| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 色麻豆AV| 91色久| 欧美 亚洲 在线| 日韩亚洲美州欧洲综三区一品在线| 亚洲高清自拍| 殴洲老熟女| 亚洲啪啪视频一区二区| 九九九九九九九九九国产精品| 亚欧精品久久久久久久久久久| 午夜人人操| 亚洲国产中文字幕| 亚洲午夜免费狠狠干| 国产无吗在线播放| 91在线丝袜| 欧美亚洲激情小说| 日本色色色色色视频| 91综合网在线| 97热视频在线观看| 精品国产乱码久久久久久久久1 | 日韩av在线免费网站| 91天堂| 884t在线| 欧美 亚洲 综合 制服| AV天堂国产| 1024精品在线| 欧美亚洲成人在线一区二区三区| 免费观看欧美日韩操逼视频| 久久五月天婷婷丁香中文字幕| 亚洲区小说| 久久久久久久久九九久孕交| 丁香色五月 97干| av爱爱爱| 躁躁躁日日躁2020| 蜜桃狠狠色伊人亚洲综合| 亚洲天堂综合AV| 久久精品中文字幕无码l| 91成人18| 91中文字幕在线观看| 久久天天躁日日躁狠狠躁| 91碰碰碰| 午夜福利视频在线一区| 国产精品久久久久久久久久梁医生| 人人操人人精品影片| 91久久18禁| 色妺妺在线视频| 黄片在线免费在线观看| 亚洲精品国产专区在线观看| 色呦呦国产精品免费看| 好爽免费视频| 美女黄色91| 国产一| 加勒比AV网| 91超碰人人| 99久久久久| 探花一区在线| 国产区91柔拿会所技师| 一本大道不卡一二三区| WWW操逼| 污色区网站| 欧美懂色综合网| 久区视频| 国产精品白丝www| 日韩精品人妻中文字幕不卡乱码| 熟女久久久| 老熟妇一区二区三区啪啪| 又摸又舔在线观看网站| 欧美中文字幕一区 | 欧美色就是色| 天堂v无码免费视频| 试看60秒 爽| 亚洲国产综合图区中文字幕| 加勒比海色香蕉婷婷| 91色插| 好爽视频在线观看视频| 97超碰超碰| 亲子敌伦对白在线播放| 欧美超碰97| 91国产操逼视频| 国模无码人体一区二区三| 国产欧美在线观看免费观看| 国产91会所女技师在线观看| 美国一区二区三区视频| 国产精品一区二区三区,亚洲综合 性开放中文AV高清无码免费看 | 欧美性夜| 亚洲欧美综合| 1级黄色夫妻对换性交免费看| 久久成人国产精品| 人人妻人人狠人人| 亚洲成人综合在线| 77777亚洲蜜臀精品久久综合蜜臀| 91xingse| 日韩av色图| 综合色久欲| 大香久久| 中文字幕高清精品一区| 久久99人妖视频国产| 另类视频在线| 日韩精品人妻系列无码天堂| 女人的天堂大香蕉网| 蜜桃香蕉久草精品在线| 精品九九| 秋霞无码av鲁丝片一区| 丁香久久| 9久精品视频在线观看| 日日AAvv| 草草草视频在线免费看| 日本一区二区成人在线| av优播| 大香蕉男人的天堂| 久操视频这里只有精品| 免费看片黄| 人人色人人操在线| 伊人成人情色综合| 一级AAA片一区二区三区| 色在线视频导航| 黄色性爱网网| 九X超碰| 天天欧美97| 看免费的黄片| 嗯嗯啊在线视频| 日日妻色网| 97天天日| 亚洲另类电影| 九九国产热| 亚洲人妻久久| 99久在线精品99re8热| 操b网站亚洲无码| 91人人操| 日韩性爱视频免费在线| 欧美亚洲涩涩| 欧美成人免费在线观看| 99这里有精品| 夜夜国自区| 国产毛片久久久久久久| 色 婷97| 亚洲在线91| 人人透人人操| 亚洲久草AV色图| 综合在线导航一区| 尤物av网站免费在线播放| 人人操人人摸人| 97 国产一区| 操逼操2| 欧美日韩国产在线| 我要色综合网站| 国产家庭乱伦网址| 亚洲综合大片| 亚洲导航深夜福利| 国产青视频| 中文字幕第9页萱萱影音先锋| 欧美午夜精品久久久久久超碰| 久热精品在线| 亚洲精品美女久久久久久久久| 天天草AV| 免费在线观看国内色片网站网址| 久久草视频污视频| 欧美日韩操逼动图| 欧美性视频二区三区| 亚洲第2页| 一区二三区四区视频大全套| 天天搞在线综合网| 亚洲诱惑天堂| 人人爱人人操人人性| 果冻传媒A片一二三区 | 97伦乱| 亚州操逼网| 欧美色图片色哟哟| 婷婷色五月激情| 国产精品久久久久久久久久久久久久| 五月婷色| 欧美天天| 色偷偷色偷偷欧美日韩| 久久成人国产| 加勒比无码毛片| 五月天激情综合网| 尤物视频视频官网| 又黄又粗又硬又长又大| 国产操逼逼网| 2017天天操天天日| 久久久精品国产亚洲伊人| www.av家庭乱伦| 青青操在线亚洲视频观看欧美在线| 久久精品日韩| 玖玖无码超碰| 青青草在线成人视频| 青青免费在线视频一区 | 樱花蜜乳av| 国产AV天美传媒一区二区三区 | 婷婷色综合欧美日韩| 怡红院视频在线| 成人性爱av| 日韩专区久久久| 人妻久久久久久久久久久久久久久| 午夜性生活av免费在线看| 亚洲欧美精品久| 99精品热| 国产在线观看91精品一区| 欧美日韩美女精品久草一区二区三区| 亚洲黄色影视| 日韩熟女操逼| 91天天综合在线| 日本九九久久99播| 日韩性爱高清免费视频| 偷拍 欧美 日韩| 久久精品操| 青青草伊人久久| 动漫爆乳3D奶水一区在线观看| 日本不卡一区| 热热色青青草| 日韩人妻无码精品系列| 婷婷色色五月天| 中文字幕久热视频在线| 9Ⅰ超碰| 人妻少妇久久中文| 亚洲中文字幕妇伦久久| 操逼日韩无码| 久久社区一区二区三区| 玖玖爱影院| 91大香蕉伊人| 国产性爱欧美性爱在线| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 无遮挡男女激烈动态图| 91大香蕉伊人| 老熟妇一区二区三区啪啪| 俺去久久| 欧美 日韩第一性色| 久久人人舔人人爽舔人人av片| 午夜视频久久久| 成人日韩中文字幕| 日韩人妻精品久久久久| 日韩精品碰碰| 欧美91在线| 91欧美情色| 亚洲AV在线资源| 四虎AV无码| 一二三四免费视频| 日韩性爱网址| 午夜福利免费福利视频| 国产成人亚洲精品无码最新在线| 干妹子| 日韩图区| 人人摸人人舔一区二区| 国产精品久久久久久久久久久久久久久久久久| 日本污ww视频网站| 色噜噜人妻丝袜a∨先锋影| 啪啪啪东京| 男女做爰猛烈动高潮A片免费应用| 超碰99热中文字幕| 麻豆一区在线| 粉嫩不卡一区二区性爱| 欧美熟女丝袜| 国产a片操逼| 嗯啊不要啊在线 | 黄在线| 色墦五月丁香| 国精综合一二三区影视| AV天天综合| 国产一级久久久| 性爱网站一区二区| 国产视频一区二区在线| 亚洲骚男同com| 五十路人妻在线| 日本高清熟女久久一区| 伊人在线大香蕉视频久久| 色哟哟精品1精品2| 91宗合网| 日韩黄色片子| 国产午夜无码片在线观看影视| 国产乱伦一二三区| 日韩乱码Av| www.男人天堂| 亚洲av青草久久一区二区| 成人av性爱电影在线观看| 强奸乱伦麻豆| 九九热九九热| 欧洲性人爱视频| 久久夜夜| 99久久精品国产高潮| 9999伦理视频| 青青草五月份天| 午夜.DJ高清在线观看免费7 | 天天看精品动漫视频一区| 福利视频一区二区微拍| 久久久com| 99日免费视频中文字幕| 人人操人人肉久久精品| 亚洲成人性爱在线观看| 高清不卡国产| 99999精品| 99热综合| 久伊人网78| 囯产乱伦一区二区三女| av东京热男人的天堂| 高清无码久操视频| 亚洲日韩肥臀视频在线观看| 91高清欧美| 激情AV| 清纯唯美综合| 91精品黄在线观看| 狠狠躁伊人中文字幕| 国产在线视视频有精品| 国产av色网| 超碰69| 亚洲精品骚逼| 福利天堂| 4tube欧美女厕所| 999久久芭蕾| 欧美97视频| 亚洲午夜福利在线影院| 91丝袜激情在线| 欧美性爱伊人| 91丝袜视频在线观看| 97亚洲资源| 精品人体无圣光凹凸| 夜夜操二区| 亚洲乱码精品一区二区| 美女天天干| 东京热视频网| 色大香蕉97N| 白嫩国模丰满一二三区| 九九久精品| 人妻精品综合中文字幕在线| 国产精品白丝在线播放| 久久九精品| 丁香五月综合| 亚洲αv一区二区三区| 91制服丝袜| 日韩懂色网| 一道本久久棕合爱| 日韩欧美成人综合在线| 日韩91网| 久久久久久久久国产| 熟女丝袜视频| 97人人模人人爽人人| 男人女人18禁片免费看网站| 免费男人的天堂| 爱啪精品一区| 中亚av| 最新国产精品久久精品| 国产精品毛片?v一区二区三区 | 国产中文大片资源中文字幕| 97超碰大| 美女91网址| 婷婷激情五月综合| 黑丝日韩av丝袜av| 91久久久久久久久久久| 日韩国产中文字幕| 国产成人无码久久精品| 天天色黄色影院天天操| 国产AAAAAABBBBB| 久久午夜色播影院免费高清| 夜夜夜夜久久久久| 五月婷婷青青草娱乐伊人| 亚洲欧美日韩电影网站一区| 精品无人区麻豆乱码久久久| 久操视频免费在线观看| 欧美成人都市人妻| 久久久久骚| 欧美大香蕉卡久久| 国产熟女一区二区丰满| 久久国产视频专区一二三| 91最新综合| 亚洲成人日韩小说| 8050午夜少妇无码| 亚洲欧美综合网站| 亚洲欧美激情在线视频| 欧美九九九| 亚洲丝袜二区| 电家庭影院午夜69久久夜色精品国产69乱 | 国产一区在线观看无码AV | 久久粉色| 国产又黄又粗又猛大片| 国产在线能看的你懂的| 不卡日本一区二区| 懂色中文一区二区三区 | 国产区性爱在线视频秋霞豆| 九九碰九九爱97超碰| 秋霞操逼片| 97人人操人人摸人人爱| 人人色人人操在线| 涩爱AV在线| 熟女熟妇伦久久影院毛片一区二区 | 日韩亚洲中文有码视频| 久久久久婷婷| 欧美中字二区| 97日韩| 能看的AV| wuyechaopeng| 国产毛片久久久久久久| 在线小说视频一区| 操B视频日韩无码| 国产在线精品偷| 亚洲有码第一页| 亚洲av性爱电影| 这里只有精品视频在线| 在线情色电影 91大| 伊人五月天婷婷| 久久亚洲不卡| 亚洲美女精品九九视频| 欧美性爱视频免费一区一A| caopeng97人妻| 94色色电影网| 熟女人妻av在线资源,黄色的资源| 超碰97久久国| 国产操逼逼网| 精品九九九九九九九九九| 综合激情二| 肉丝网站91| 波多野结衣一级视频| 日本97久久久精品| 国产女人高潮嗷嗷嗷叫小说| 久久精品一区| 亚洲天堂7777| 淫穴高潮色图| 蜜桃臀av在线观看| 亚洲全色网| 男人干美女| 久久久麻豆精品| 蜜臀Av一区二区三区| 亚洲午夜免费狠狠干| 自拍内地三级在线观看| 欧美亚洲高清不卡| 中文字幕av乱伦| 自偷自拍的亚洲视频| 欧美成人一级麻豆| 国产精品视频在线观看| 国产精品com| 2018天天干在线视频| 午夜久久无码1000合集| 国产九月婷婷| 男人的天堂2018东京热啪啪啪| 国产午夜在线观看视频| 97国产伦理| 亚洲日本男人天堂网| 亚洲成?V人片在线观看福利| 日产操逼| 欧美色图电影| 亚洲图片 激情小说| 色爱国产| 黑人精品成人一区二区三区| 日本最新1区2区3区| 激情综合网五月婷婷五月天| 777超碰| 日韩黄色小说| 夜夜操天天肏| 天天操天天舔| 综合欧美亚洲| 男人的天堂欧美| 亚洲精美粉嫩嫩泬在线观看 | 熟妇人妻一区二区三区| 麻豆一区二区三区在线看| 国产亚洲日本精品在线| 中文字幕日韩国产传媒欧美精品| 三男一女不戴套的A片| 午夜天堂精品久久| A V少妇特黄三级| 精品综合久久久久久97| 亚洲 暴爽 AV人人爽日日碰| 日韩无码嘿咻黑热久| 欧美一区二区三区互相| 偷拍盗拍亚洲色图图片| 91色射| 夜夜嗨一区| 婷婷久久久精品| 国产中午字一暮区| 欧美精品欧美精品系列| 欧美图片色五月天| 综合欧美亚洲| 亚洲成a人v欧美综合天堂下载| 91欧美网| 人妻偷拍一区二区三区| 性爱免费视频成人| 婷婷视频网| 精品视频日日夜夜| 撸撸成人在线视频| 欧美淫乱视频| 亚洲图片欧美色图| 亚洲精品天堂久久A∨51成人漫| 亚洲成熟国产精品美女| 偷看洗澡一二三区美女| 欧美极品女人的天堂| 久久天天躁日日躁狠狠躁 | 狼狼色丁香久久婷婷综合五月| 亚洲系列第一页| 五月天色五月| 久久m| 女人综合网| 乱伦系列一区二区| 精品久久久久瑟瑟| 人妻大香蕉| 美国人人操人人操| 混色激情av| 欧美后入式| 最新啪啪视频| 精品97久久综合| 亚洲综合影院| 夜夜爽爽爽| 清纯唯美综合亚洲| 综合影视国产无码| 欧美天堂日韩三级国产传媒| 美女t无毒不卡不卡| 色在线亚洲视频www| 亚洲欧美爆| 超碰日韩人妻| 国产精品情侣啪啪| 欧美高清第一页| 神马精品视频| 97日韩| 久久综合日韩亚洲欧美| 国产三级片在线观看| 嗯啊不要啊在线| 超碰97人妻在线| 亚洲无套久久嗯嗯| 九九久久玖玖| 日本97久久久精品| 一级性爱aaaa| 日本欧美不卡| 精品视频一区二区| 婷婷九月丁香| 日韩国产九九精品一区二区三区毛片| 四虎永久在线精品免费网址| 午夜精品探花| www.久久最新地址| 九九九九九九综合| 欧美另类色| 福利伊人玖玖国产| 好爽视频在线观看视频 | 日韩激情视频| 欧美激情中文字幕另类小说| 伊人久久亚洲色欲综合网站| 国产精品青草综合久久| 天天谢天天干| www.操| 78m成人视线| 人妻日日干| 精品人妻一区二区三区鲁大师| 高清国产成人无码| 婷婷色综合| 国产精品一区二区在钱播放| 超碰天天操你比| 日韩有码 一区二区三区| 亚洲AO在线| 东京热男人的天堂精品| 性感美女啊啊啊在线| 99热这里| 尤物黄色在线观看网站| 后入国产| 伊人玖玖网| 日日狠狠久久偷偷色综合免费| 一区二区三区美女超清| 啊啊在线| 欧美后入视频| 免費人妻夜夜爽天天爽爽一区| 亚洲精品国产专区在线观看| 三级色影综合网| 日本精品一区二区三| 青青草日本无码| JIZZJIZZ国产精品喷水| 欧美综合网| 男人的天堂视频精品乱在线| 九九九九九用不成了| 人妻熟女字幕一区二区| 亚洲欧美国产其他二区| 国产一区二区在线播放量| 国产精品视频在线观看| 久久9精品网站| 亚洲情色一区二区三区| 欧亚第一综合网| 9九九九九视频在线观看| 久99久视频| 国产精选三级在线观看| 强奸乱伦Av网| 国模艳艳啪啪一区| 波多野结衣先锋影音| 日韩在线地址一| 日韩国产精品人妻无码久久久| 久久这里只| 97精品在线视频| 国产精品扒开腿做爽爽爽视频| 久肏视频字幕| 东北熟女91| 日韩15p| 青娱乐淫乱1314| 97人人夜夜精品视频| 久久国产乱子伦精品免费女人| 国产精品美女久久久久久网站| 国产精品爆乳懂色蜜乳| 人人操 欧美| 人人摸人人干人人拍97| 欧美日韩性爱操大逼| 五月丁香成人网| 亚洲有码 欧美精品| 亚洲综合113页| 中出人妻中文字幕91在线| 婷婷精品久久av影视| 操东北女人| 手机在线播放国产福利| 超碰在线国产| 欲射影视| 伊人天天久久动态图| 狼狼色丁香久久婷婷综合五月| 免费黄色片子| 久久久久9| 在线免费观看高清无码视频 | 人妻无码视频一区二区三区久久| 久久婷婷苹果| 在线播放免费av福利片| 亚洲五月丁香花狠狠干一区二区三区 | 欧美熟妇乱码在线一区| 欧美性视频二区三区| 激情小说图片亚洲首页| 操逼网免费无码视频| 中文字幕-区二区三区四区视频中国 | 自拍视频大全亚洲专媒视频/一区二区三区| 日韩精品.久久精品.AV女优.天美传媒| 欧美在线干| 欧美一区二区福利在线| 亚洲欧洲偷拍一区| 天天影视综合色| 老熟妇一区二区三区…| 麻豆久久久久久久久丝袜 | 亚洲最大91网| 91色欧美| 久热这里| 亚州欧美另类| 亚洲天堂,男人| 欧美色综合网| 97天天摸天天碰| 亚洲视频精选| 欧美另类色图片| 99无码狠狠久久| 久久精品72| se01国产在线视频| 999九九九九国产动| 99久久久er直播网址| 啊啊啊骚| 亚洲 中文 女同| 草草影院日本第一页| 亚洲日产专区婷婷| 成人性爱全视频观看| 一区二区三区一亚洲中文字幕、综合区灬 | 色婷久久| 欧美啪啪色吧在线| 大香蕉伊在线久草麻豆天堂故事| 人人做,人人操,人人摸| 色香在线| 九九热视频在线观看| 手机看片91人妻| 亚洲高清少妇| 亚殴在线| 国产熟女乱论| 999久久久| 国产吹潮女在线观看| 亚州色图第三区| 深夜激情无码| 日韩中文字墓| 超碰精品97| 操淫穴亚洲五月丁香| 亚洲成人av色网| 最好看的中文字幕在线2018| 亚洲欧美色图片| 人人摸人人舔一区二区| 91欧美偷拍| 嗯啊不要在线| 五月丁香六月婷综合成人综合| 亚洲无码精品AV久久久| 欧美色图99|