日韩精品一区二区三区在线视频放-无码中文字幕V?一区二区-成年片免费观看视频-国内少妇人妻丰满av-国产精品中文字幕免费观看-亚洲成人久久一区二区三区-国内少妇偷人精品视频无缓冲-一区二区国产精品日本一区二区三区在线网

ARTICLE DETAIL

資訊詳情

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

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

WPF界面框架分層實踐:主題Token、MVVM與換膚避坑 簡介面向 WPF 桌面應(yīng)用開發(fā)者的一套現(xiàn)代化界面框架源碼與示例適合希望擺脫默認控件外觀、快速搭建統(tǒng)一視覺風(fēng)格的中級開發(fā)者參考也可作為團隊 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ī)則很短但它是整套換膚機制的基石。很多人的皮膚切換做不出來原因就一個把皮膚字典加在了 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上層的就永遠取不到——調(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。這個劃分一句話能記住后面維護的人也不會亂改。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這里有幾個容易被忽略的細節(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也改回來這類細節(jié)在驗收時最容易被挑出來。最后控件模板里不要出現(xiàn)字面色值這是硬性約束。只要模板里出現(xiàn)一個#2F6FED換膚那一刻它就會變成色塊不一致的元兇而且很難靠肉眼定位到具體是哪個模板??蚣芾镞@類違規(guī)用一次文本搜索就能找出來接入前先搜一遍#順手清理掉。3. 接入現(xiàn)有工程從復(fù)制目錄到跑出第一個頁面3.1 目錄落位與 csproj 里的資源聲明把整個工程復(fù)制進來是最快的驗證方式但真正接入現(xiàn)有項目時建議只復(fù)制Themes和Infrastructure兩個目錄示例頁按需挑選著拿。目錄放在項目根下即可不要塞進Properties或者obj旁邊obj目錄在清理時容易誤刪。csproj這塊有個高頻問題SDK 風(fēng)格工程的默認 glob 已經(jīng)把**/*.xaml編譯成Page你再手寫一遍Page IncludeThemes\**\*.xaml /就會報重復(fù)項NETSDK1022。所以大部分情況下什么都不用寫只在需要排除或者改變構(gòu)建方式時才動它。ItemGroup !-- 默認 glob 已包含 **/*.xaml這里只做排除草稿目錄不參與編譯 -- Page RemoveThemes\_draft\**\*.xaml / !-- 字體、圖標(biāo)這類二進制資源用 Resource隨程序集嵌入pack URI 才取得到 -- Resource IncludeAssets\Fonts\*.ttf / Resource IncludeAssets\Icons\*.png / !-- 示例數(shù)據(jù)用 Content 復(fù)制到輸出目錄別用 Resource 塞進程序集 -- 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)默認字體——這類靜默失敗最耗時間。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換膚后那個控件就會保持舊色在一片新配色里顯得很突兀。還要注意換膚的時機。啟動時在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)題欄那一行的高度嚴格對齊寫 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ù)量確認一下。3.4 驗收入口DPI、縮放、多屏的檢查清單界面框架接進去功能點兩下都正常不代表能交付。下面這張表是我每次接入必過的一遍成本不到十分鐘能提前擋掉大部分返工。檢查項操作不通過的表現(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 刷新時機的坑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里拋出的異常會直接打到未處理異常上進程就掛了。框架里的AsyncCommand用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而是自己維護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確認框、輸入框、等待提示不直接調(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)為「點確認之后界面頓一下」把選項加上就好。5. 避坑記錄樣式不生效、內(nèi)存上漲、DPI 模糊的排查順序這一章是這份框架里最值得先讀的部分。下面四條都是我在真實接入里遇到過的每一條按現(xiàn)象、原因、解決的順序?qū)懹龅酵悊栴}時可以照著順序查。5.1 現(xiàn)象改了 Token控件紋絲不動現(xiàn)象把Color.Accent.Base從藍改成橙重新生成主按鈕還是藍的。清緩存、重啟 IDE 都試過仍然是藍。原因控件模板里引用的是{StaticResource Brush.Accent.Base}。StaticResource在 BAML 解析階段就把值取出來寫死了后續(xù)字典變化對它沒有任何影響。另一種可能是這個頁面的Window.Resources里定義了一個同名的Brush.Accent.Base局部作用域優(yōu)先全局的改動被它遮住。解決在解決方案里搜StaticResource Brush.凡是顏色類的引用全部換成DynamicResource再逐頁檢查Window.Resources和UserControl.Resources里有沒有同名 Key。這兩步做完改動立即生效。我的習(xí)慣是把這條寫進代碼評審清單模板里出現(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ā)機 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. 進階把換膚做成可以回歸驗證的流程界面類的改動最難驗證因為它「看起來沒問題」和「確實沒問題」之間差得很遠。這套框架里我最常用的一個技巧是把換膚做成可以對比的回歸流程。第一步把 Token 抽出來做一份中間格式。框架的Tokens目錄本身就是鍵值對用幾十行代碼掃一遍 XAML把Color.*、Font.Size.*、Radius.*導(dǎo)出成 JSON交給設(shè)計側(cè)對齊。之后設(shè)計師改配色改的是這份 JSON工程師用腳本回寫 XAML比在群里發(fā)色值截圖靠譜得多。回寫腳本要注意保留原有的x:Key順序和縮進否則每次生成都是幾百行 diff評審時沒人看得下去。第二步準(zhǔn)備一個「Token 全覽頁」。把所有 Token 渲染成色塊、字號樣例、圓角樣例配上鍵名放在調(diào)試菜單里。換膚以后直接翻這一頁哪個鍵沒被覆蓋一眼就能看出來。這個頁面我一般不到半小時就能拼完但省下來的排查時間遠超投入。第三步截圖比對。把關(guān)鍵頁面在淺色和深色下各截一張存在版本庫里改了樣式之后重新截用逐像素差值定位變化區(qū)域。閾值不要設(shè)在零字體渲染有亞像素抖動允許千分之三以內(nèi)的差異超過就是真改了。這套流程跑順之后改一個 Token 影響哪些頁面提交前就能知道。還有一個小習(xí)慣值得說一下每次接入新的界面框架我都會先在空工程里跑一遍它的 Demo把所有頁面點一遍重點看深色皮膚下的對比度和禁用態(tài)。原因很簡單這些地方最容易藏問題而在自身工程里樣式問題會被業(yè)務(wù)邏輯掩蓋很難判斷到底是框架的問題還是你寫錯了。從那以后我每次往項目里引 UI 框架都強制先走一遍這套空工程驗證再動業(yè)務(wù)代碼。希望幫到你。本文還有配套的精品資源點擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国偷自 一区| 欧美,日韩综合久久| 再深点灬舒服灬太大了好硬好爽| www被窝色com| 国产亚洲中文不卡二区| 欧美午夜视频| 综合影视国产无码| 综合夜夜| 日韩一区二区精品视频| 天天肏夜夜肏| 荡小穴在线观看| 九九热国产| 日韩熟妇二区| 精品国产Av无码久久久伦古装| 色九月| 97超级久久| 日亚韩精品视频二区三| 欧美日韩1234| 男人 天堂 日 亚洲| 99热| 一本久久精品中文字| 亚洲一区二区三区中文字幕| 男人的天堂日韩| 欧美日韩一区二区三区四区蜜桃| 99re在线视频国产| 综合自拍| 91操熟女| 日韩欧美水蜜桃人妻| 另类 日韩 熟女| 久久久96精品| 91N欧美| 女优大全 - 91n| 人妻熟女一区在| 欧亚日本情色| 99少妇| 日韩情色一区二区| 日韩99999色| 精品欧美老熟女一二区| 欧美少妇性乱| 天天爽人人综合免费7799| 精品丰满熟妇人妻一区| 国产欧美伊人| 簧片免费看视频| 99热伊人| 久久亚洲人妻| 色五月婷婷五月天| www.久久制服糖| 超碰碰激情97+久| 日韩黄色一区二区三区| 色综合av综合久久| 熟女高潮精品一区二区| 色呦呦、国产精品| 98色网| 狠狠操夜夜| 91亚洲网站| 亚洲成人妻日韩在线| 九月婷婷综合| 美女极品一区二区三区| 91欧美色| 97超碰免费生活| 亚洲 日韩 欧美 国产综合体| 欧美黄色大片在线观看| 少妇熟女一区二区三区| 九九九九精| 欧美在线l亚洲| 东京热激情视频一二三区| 免费一级a毛片久久久久久鸭绿欲 国产精品亚洲天堂网址 | 九九九九免费视频| 91撸色网 玖玖网 欧美| 五月天激情网图片| 国产亚洲禁久一区二区| 日韩黄色一区二区三区| 自拍偷拍草一草| 中文字幕激情小说| 超碰色美女| 啊啊啊好舒服好爽啊啊啊视频| 超碰在线人妻| 亚洲欧洲综合视频在线| 一区二区三区欧美激情| 伊人网综合在线视频| 亚洲人成网站7777| 麻豆视频国产一区二区| 夜色91| 超碰9 7女人| 黑人中出21连凳花野真衣| 大香交伊人网| 丁香五月天堂| 国产精品成人在线| 探花一区在线| 欧美,日韩,亚洲视频| 国产91影院| 久草成人| 偷拍视频青青草在线视频| 色悠久久久av| 久久精品人妻一区二区| 97超碰免费人人性爱| 婷婷伊人一区| 亚洲揄拍网| 久热69九色熟妇97| 久操B网| 韩国轻伦国内自拍一区| 日本熟人妻中文字幕在线|...久久国产精品-国产精品_日本一区二区三区中文字幕 | 九九久精品| 天综合网欧美| 欧洲自拍色图gif在线| 日韩少妇丰满亚洲| 午夜精品人妻二区三区| 国产精品禁久久久精品| 日韩欧美三级| 亚洲色91| 人人操人人摸人人看人人插| 人妻无一区二区三区| 你懂的在线观看区国产| 三级日韩一区二区三区| 国产成人免费观看在线视频| 五月丁香激情综合| 国产黄a三级三级三级av在线看| 国产刺激视频| 亚洲A色| 91亚州欧美| 97超视频在线观看| 白嫩妹子国产骚| 久久久久久免费电影| 一二三区视频在线观看| 中文字幕丰满子伦无码专区在线视频最新| 天天躁日日躁狠狠躁| 久久精品国产精品一区| 色狠狠色| 99蜜桃臀亚洲成人在线观看| 91精品在线播放| 成人怡红院| 国产精品久久久久久亚洲色欲| 爱妃国产亚洲视频中文字幕| 围产精品一区二区三区视频播放| 又大又白奶子| 国产美女口爆吞精| 鸥美中出| 国产91av在线播放| 久草婷婷| 精品人妻一二三四区视频| 久草毛片| 日语五十路和六十路亚洲国产精品| 久久精品国产亚洲AV高清演员表| 欧美日韩操逼嗦吊| 超碰 av 女人天堂| 国产精品久久久亚洲第一牛牛_在线观看 | 97国产天堂岛| 亚洲综合在线91| 久久久久国产精品久久久| 69少妇一区二区| 色青青久久影视| 射丝袜高跟鞋99| 九九超碰综合网| 神马久久午夜| 五月天精品| 亚洲精品欧洲精品| 欧美激情1区| 性爱免费视频成人| 无码欧美有限公司| 青青草AV色| 日本成人A片网站| 亚洲激情av| 麻豆 亚洲 97| 国产亚洲色停停久久99精品91| 亚洲色图亚洲无码强奸乱伦| 一本色道久久综合熟妇| 免费a级毛片av无码久久精品中文字幕| 亚洲αv一区二区三区| 激情综合97| 9999久久久久| 人人操人人摸人人看人人插| 午夜天天碰综合视频| 久久噜噜噜精品国产亚洲综合| 亲子敌伦对白在线播放| 免费观看的av| 精品人妻视频一区二区在线播放 | 99在线观看视频在线高清| 天天爽夜夜爽夜夜爽精| 亚洲色图超碰在线| 日日不卡av| 视频黄色国产一级| 亚洲淫乱骚妇AV| 搡老女人老91妇女老熟女| 日韩女模中文造逼| 玖玖大干人妻| 日韩AV熟女乱伦| 亚洲熟妇综合久久久久久| 人妻无一区二区三区| 一二三区在线| 亚洲无 码A片在线观看麻豆| 国产999精品久久久久久| 久久嫩草| 国产欧美精品日韩区二区麻豆天美| 99精品丰满人妻无码| 无码区蜜乳| 亚洲一区二区三区麻豆传媒| 日韩欧美性爱电影在线观看| 欧美天天谢综合网| 在线播放免费av福利片| 欧美性Fer办公室秘书| av网页一区二区三区| 97超碰久久色| 人人爱人人操人人性| 999 久久久| 国产免a费看黄片在线| 久久男人网| 亚洲字幕一区二区| 97就爱干| 亚欧性爱在线无码| 777超碰| 久久怡红院| 亚洲网站一区二区在线| 色网在线| 精品超碰中文在线| 欧美Ⅴ性爱| 草久久久| 成人免费在线网站| 久久久久熟女| 999久久久九| 中文字幕精品一区二| 久久九七| 综合久久欧美| 青青草久草| 欧美视频第二页| 欧美αv.com| 蜜桃狠狠色伊人亚洲综合 | 精品超碰国产| 欧州一区二区三区四区| 精品999日本| 成人网站 免费观看| 91模特在线观看| 国产欧美精品日韩区二区麻豆天美| 百度百度日本操逼| 日本五区不卡| 九色 人妻 大香蕉| 久久九九视频九九视频| 亚洲综合九九| 久久后入制服| 嗯阿好爽好紧| 超碰人人色| 久久久国产av美女私房| 国产乱码久久久| 91九久| 99精品视频在线观看免费| 国内毛片四区| 樱花草社区www中国| 欧美性爱视频免费一区一A| 天美传媒AV在线| 亚洲综合小视频小说在线观看| 天天色综亚洲91污| 激情黄色片在线观看| 亚洲欧美啪啪| 亚洲一区二区专区-国产丝袜精品丝袜-成人AV | 亚洲欧美变态| 老司机午夜福利视频一区二区| 九月丁香| 性爱边摸边日免费AV| 久久精品国产亚洲粉嫩| 97超碰免费生活| 不卡九肏| 青青草在线视频人人想人人上| www欧美性爱| 强奸乱伦AV一天堂网| 欧美小说区视频区| 亚洲凸凹超碰成人| 综合亚洲情色| 亚洲色图超碰在线| 伊人五月天| 又粗又长又爽在线观看| 伊人丁香五月婷婷| 囯产精品久久久久久久久久梁医生 | 青青草久草| 久草久日| 老司机免费视频在线91| 亚洲精品蜜桃久久久一区二区三区| 亚洲二区精品在线观看 | 国产精品人妻无码久久久互動交流| 亚洲精品久久一区二区三区蜜桃臀| 97蜜桃综合| 亚洲日本加勒比在线| 天天插天天操| 韩国三级理论在线| 男人a天堂手机在线版| 探花视频免费观看国产专区| 麻豆天美一区二区| 97超碰欧美| 亚洲天堂男| 精品无人区麻豆乱码1区2区图片| 国产人妻精品一区二区三区秋霞 | 97人人中文网| 欧美性区| 啊啊啊不要啊啊受不了了视频在线| 欧美|91色综合| 日本3级一区二区免费| 一本一道vs波多野结衣| 欧美性爱伊人| 我要看免费韩日黄片| 人人操人人操草草| 五月天激情视频| 成人av免费观看| 亚洲五月天激情| 色播丁香| 精品久久在线区一区| 欧洲免费一区二| 九九热免费在线国产视频伊人五月| 1区2区3区在线视频| 97香焦色区| 亚洲欧美爆| 97 国产一区| 亚洲和欧美裸体美女双飞视频| 伊人久久大香蕉线AV五月天| 成人精品视频| 亚洲情色欧美| 秋霞影音一区二区三区| 亚洲婷婷五月天| 亚洲熟女国产综合另类| 粉嫩AV一区夜夜嗨| 久久久免费高清中文视频| 秘书高跟黑色丝袜国产91在线| 蜜臀久久久99久久久久 | 欧美少妇色图| 国产传媒午夜理伦精品| 99热99色| 男人的天堂激情| 久久精品夜色国产亚洲AV| 色色青青久久| 你懂的在线观看区国产| 一级久久性爱视频| 91亚洲青青草原精品1区| 久久骚少妇| 亚洲AV色图一区| 男人的天堂久久久| 亚洲av综合色| 国内黄色精品| 亚洲在钱| 精品九九| 伊人婷婷五月天| 美日韩一卡二卡三卡免费人妻精品| 天天天天做夜夜夜夜做| 夜夜欢天天干| 色嗨嗨在线| 国产一区96在线| 操死我了啊啊啊| av网站免费看| 丁香九月激情啪| 精品国产72| 蜜臀AV一区二区三区| 91被操| 91精品91久久久中77777| 性色av一区二区| 欧美成97爱| 亚洲精品一二区| 大香蕉在线视频15| 天天做天天爱| 日韩一级欧美一级在线观看| 日韩图区| 自怕偷自怕亚洲精品| 操人91| 激情五月天校园春色网| 蜜乳成人AV| 神马久久久久眼| 国产精品午夜福利| 欧美三级中文字幕hd| 情色五月天久久久| 亚洲综合九九| 男人兔费天堂| 婷婷丁香激情| 中文字暮97| 东北女人高潮视频| 日韩黄色成人性爱| 啊啊啊轻点在线观看| 亚洲小电影免费涩涩成人在线高清| 男人天堂婷婷五月天校园春色| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 精品97精品97| 狠狠色伊人亚洲综合网站色| 久久99国产综合精品女同| 欧美性性性| 99久久婷婷国产综合| 男人的亚洲天堂| 精品毛片av一区二区| 红桃视频高潮| A级片日韩欧美国产欧美视频精选观看 | www.av在线观看| 五月天欧美色图| 东北丰满熟女国产一区| 尤物视频网 刘玥| 中文字幕中文字幕一区二区| 欧亚揄拍偷拍精品视频| 十八禁成人网站在线观看| 欧美在线55555| 一级黄色视频网| 欲香欲色天天天综合和网| 日韩欧美操逼xxx| 亚洲男人的天堂AV| 在线观看AV片| 中国熟妇| 97久精品| 国产成人自拍视频视频| 久久宗合亚洲| 亚洲五月丁香花狠狠干一区二区三区 | k频道色撸撸| 欧美成人性爱视频免费观看 | 色www精品视频在线观看| 欧美日韩另类在线播放| 一区二区国产视频在线观看| 午夜久久无码1000合集| 欧亚 另类 久| 久久9精品视频| 国产女同视频在线播放| 啊啊啊啊在线播放| 久久99国产综合精品女同| 精品日韩人妻视频| 五月天人妻综合| 人妻熟女午夜精品在线| 国产精品不卡一区二区三区av| 国产成自自拍在线观看| 粉嫩在线一区二区懂色| 99久久99久久免费精品蜜臀| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 手机在线A片| 日韩欧美三级| 亚洲精品 超碰| 中文字幕aⅴ在线视频| 丝袜美腿丝袜| 久久久性爱视频| 久久精品国产72国产精品福利| 啊啊啊好大好深| 久久精品天美| 婷婷久久网| 老熟女91视频| 国产丝袜美女诱惑| 91人妻最真实刺激绿帽| 欧美激情在线观看视频| 黄总AV色图| 免费看污网站| 多乙久久久久久| 97亚洲综合| 欧美亚洲综合999| 波多野结衣一级视频| 亚洲精品一区二区精品| 亚洲色图A| 人妻人人澡人人爽人人| 五月婷视频| 一区二区三区黄片免费观看| 啊啊啊啊啊在线| 物业黑人 AV一区| 中文字幕 一区二区 亚洲无码| 在免费jIzzjIzz在线视频| 亚洲第一页第二页激情| 国产精品久久久午夜夜伦鲁鲁| 国产精品亚洲四五区在线观看| 亚洲精品三| 免费公开人人操| 欧美一区二区三区不卡高清视频| 久区视频| 亚洲国产蜜臀系列在线观看| 丝袜综合| 大香蕉综合| 91蜜臀熟女| 婷婷天堂站| 亚洲国产奇米影视久久| 大二网站亚洲| 中文字幕精品免费一区二区| av中亚| 欧美瑟综合| 91色s| 超碰无码五月97| 大香蕉宅男伊人| 中文字幕一二三区| 夜夜高潮夜夜爽高清视频一 | 伊人女女资源在线观看| 欧美一级黄片视频在线| 黑人精品XXX一区一二区| 97超碰色色| 9久久精品| 国产999精品久久久| 久久久久人| 国产AV人人夜夜澡人人爽麻豆| 啊好爽快点-国产一区二区三区撒尿在线-成人AV | 国产精品视频内谢女人| 在线亚洲欧美| 日本久久女同性恋视频| 欧美精品久久96人妻无码| 热99这里有精品综合久久 | 亚洲nv男人的天堂网| 天天爽天天操| 欧美成人9797| 欧美亚男人的天堂| 日本啊啊啊啊啊视频| 人人澡综合涩| 日日噜噜夜夜久久亚洲一区二区| 丝袜亚洲91| 久久久精品一区二区| 亚欧美综合| 中韩中文字幕在线观看| 日日爱99| 日韩黄色av中文字幕| 十八禁av无码免费网站APP| 一级黄色视频网| 在免费jIzzjIzz在线视频| 爆操无码| 天天91~综合入口| 日日干日日操五月天伦理视频| 妇女视频网站| 久久人人爽av亚洲精品天堂桃色| 人人妻人人色一区二区三区| 97日韩| 91成人高清在线观看| 国产亚洲精品av一区| 免费看欧美美女黄色大片| 97色在线| 国产精品电影推荐| 中韩中文字幕在线观看| 肏逼视频日本| 国产1769在线| 久久9亚洲| 无码男人天堂| 天天澡天天狠天天天做| 久干9操| 蜜臀国产AV中文字幕| 99国产精品久久久久久久成人热 | 黑丝91视频| 色踪合AV| 97免费在线视频| 3028国产精品| 精品91摸| 91精品国| 日本狂喷奶水在线播放212| av一区二区三区 中文| 成人熟女视频一区二区三区| 国产超碰欧美| 51国产午夜精品视频| 日韩黄色电影网站| 久久精品夜色国产亚洲AV| 18+91网站| 宅男影院久久久,99| 色婷婷在线视频| 日日噜噜夜夜久久亚洲一区二区| 91丝袜在线观看| 加勒比久久综合网高清| 久久9亚洲| 另类小说欧美激情校园春色| 亚洲精品无码久久AV| 久久本道| 九九九九精品精| 黄色性爱网网| 成人五月天色网| 中文字幕欧美丝袜07资源| 日本熟妇人妻中出视频| 欧美日动态视频| 日韩性爱小视频| 天天日天天插| 亚洲自拍小说| 精品一区二区人妖| 91 丝袜在线观看| 中文字幕日韩电影人妻| 亚洲成人一二三区| 五月天亚洲色图| 日本三级中国三级99人妇网站| 亚州男人的天堂| 三级精品三级在线观看| 久久久亚洲精品电影免费看| 超碰诱惑| 日韩另类色图| 久久久人妻| 开心五月深爱五月| 人人澡人人干| 成人日韩欧美| 伊人超碰97| 丁香六月激情| 91熟女在线| 蜜桃久久一区二区三区| 激情欧美97| 日韩久久三区| 蜜臀在线视频| 99.色网| 精品人妻一区二区三区四区石在线| 亚洲另类综合欧美| 亚洲欧美色图| 色爱综合网欧美| 影音先锋日本乱伦| 在线视频五十市| 亚洲图片日本AⅤ欧美在线| 久久神马影院| 欧美亚洲另类在线蜜桃| 国产日韩中文字幕欧美| 狠狠色婷婷7777久| 日本大香蕉综合网| 婷婷情色综合网| 丁香婷婷五月| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师 | 蜜色网色哟哟| 国产久久成人| 欧美黑人日韩少妇色情| AV九九| 97超碰久久| 欧美综合色站| 亚洲成人福利电影免费| 麻豆一区二区三区在线看| 这里有精品| 日本东京热久久久电影| 欧美亚洲厕所精品偷拍91| 国产一级作爱毛片| 国产精品久久蜜乳av| 日本美女性生活久久久久久久| 中国熟女老妇仑乱一区二区三区| 色超碰综合| 欧美一区二区亚洲天堂| 超清中文乱码字幕| 亚洲欧美日韩电影网站一区| 日本福利二区视频| 国产操逼网站亚洲一级黄色| 夜夜操中文字幕| www.激情| 精品久久久久久中文字幕三区| 综合性视频99| 人妻夜夜爽天天爽麻豆三区网站 | 920日本午夜免费| 思思视频免费看网站| 久久精品一区二区三区蜜桃臀| 六月婷婷综合| 久久av一级av少妇av高潮| AV天堂因数| 久久999久| 欧洲色| 岛国黄| 亚洲人成在线放东京热| 亚洲综合伊人| 人人综合| 麻豆60秒| 国产AV超爽| 无码免费在线观看黄色片| 99在线精品观看视频中文| 色好看av| av天天在线观看| 能直接看AV的网站| 国产精品爱欲| 懂色aV一区二区天美传媒| 久久精品高清无码一区| 97爱欧美| 亚洲春色激情小说| 91粉嫩萝控精品福利网站_精品影音先锋国 | 欧美嗯啊……在线观看视频免费| 免费看欧美美女黄色大片 | 日本性感人妻91| 91中出视频| 亚洲综合色在线| 欧美日本天堂| 日本丝袜美腿人妻九九| 人人乐大香蕉| 开心五月深爱五月| 亚洲第一在线视频| 可以免费观看的日韩av毛片| 久久久久久99AV无码免费网站| 600国产精品视频| 天天情欲宗合网| 91网站18在线| 麻豆黄四叶草网站| 伊人五月天青青草婷婷| 中文字幕 人妻不满 在线视频| 欧美v亚洲v日韩v最新在线二区 | 黑人精品XXX一区一二区| 97欧美日韩| 日日躁夜夜躁狠狠躁超爽| 亚洲AV色图一区| 97久久国产亚洲精品超碰热| 在线观看午夜婷婷久久久久清性观看| 日韩在线97| 午夜欧美神马久久久久| 国产传媒1234区| 人妻出轨一区二区三区| 少妇毛片久久| 色九月综合| 1区2区3区中文字幕日韩| 久久国产视频专区一二三 | 色99视频| 日韩乱码Av| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 伦在线97| 欧美一区二区三区成人性生活| 精品国产乱码久久久兰草影视| 天天看特黄的免费网站| ai欧美亚洲小说| 久日综合网| 人人九九精| 亚洲男人天堂网站| 亚洲欧美不卡线| 中文字幕av亚洲精品| 成 人 A V免费视频在线观看| 黑人精品XXX一区一二区| 一级岛国大片| 国产综合网站在线播放| 国产伦乱91| 激情五月激情综合网| 91久久精品国产| 欧美熟女妇同| 丰满欧美放荡少妇在线| 日韩精品午夜操呦呦不卡影院| 青青草好吊色| 色y情视频免费看| 91快色色色色色| 婷婷亚洲天堂| 人人色人人射人人妻| 欧美亚洲AN| 久久天堂网| 超碰97人妻在线| 曰韩操B| 久9视频| 四虎 精品 WWW| 四虎在线播放| 九九九九九精品| 超碰无码加勒比| 成人在线视频网| 有码人妻系列| 久9综合在线| 久久久久亚洲Av无码专区老牛影视| 无码直播久久久| 操逼视频免费日韩无码| 天天干2019| 狠狠爱夜夜干| 91综合色| 国内精品久久久久影院亚洲| 嗯啊啊啊轻点视频| 久久九九热| 日韩欧美亚欧在线视频| 日本亚洲熟女视频| 亚洲熟女乱色| 国产精品另类一区大香蕉| a片在线播放| 五月色网| 新视频sss国产| 91成人18| 国产精品自产拍在线观看社区| 韩国轻伦国内自拍一区| 91精品国| 日本操大逼| 婷婷国产精品九区| 国产精品乱码久久久久久久久| 亚洲无线码欧洲精品区别| 婷婷五月在线视频| 国产后入清纯| 中文字幕一区二区免费在线| 一二三四日本视频高清| 91色人| 95自拍视频在线观看| 97久久久久久久精| 成人区人妻精品一| 国产亚洲精品av一区| 艾草av| 亚洲图片欧美色| 色婷久久| 人妻少妇久久| 免费观看的黄色的网站| 男生女生啊啊啊啊| 精品国产Av无码久久久亚洲| 大香樵伊人网| 中国和日本人色哪个不下载能放| 91天堂色男人的天堂| 色欲人妻一区二区在线| A级片一区| 日本有码久久| 天天影视亚洲| 日韩精品一二三四| 日逼97| 九九色色| 青草精品视频日本久久久久网站在线| 国产精选三级在线观看| 大屁股熟女一区二区三区| 国产操逼视频在线观看| 操B久久| CCYY草草影院地址入口| 女同性恋一区二区三区精品视频| 91老熟女视频| 欧美精品人妻视频| 99色网| 日韩女优在线| 国产91亚洲精品一区二区三区| 97视频观看| 88xx成人精品视频| 男人天堂日日夜夜| 在线综合 亚洲 欧美中文字幕| 亚洲色性情三级| 人人操我人人干| 97爱b| 欧美专区日本专区| 成人情色综合网| 五月综合久久| av网站免费看| 最新av在线| 郑州宾馆老熟女露脸啪啪| 国产精品在线一区二区| 亚洲AV成人无码久久精品播放| 亚洲精品97p| 天天弄天天操| 狠狠久久手机视频精品| 99精品伊人| 粉嫩av在线一区二区| 精品人妻高清麻豆av| 亚洲激情网| 放黄片放3级黄片没穿衣服| 精品无吗久久| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 看一级黄色视频| 亚洲天天操| 日韩午夜国产| 国产精品岛国片在线观看| 欧美性爱一区二区三区| 熟女在线视频| 国产精品一二三在线看| 亚洲图片欧美偷拍| 欧亚不卡| 国模精品娜娜一二三区| 天天澡天天爽日日AV| 天天摸夜夜操视频| 噜噜吧,噜噜色,噜噜| 火箭成精品视频884必出精品| 亚洲综合在线高清| 日韩精品在线观看网站| 亚洲天天操| 蜜桃一区二区三区| 一二三区在线| 国产AV精久久| 精品人妻一区二区三区在线视频不卡| 自拍欧美| 屌色在线97视频| 人人艹亚洲| 久草这里只有精品| 久久精品夜色国产亚洲AV| 99久久综合网| WWW啪啪的com| 少妇熟女一区二区三区| 欧美人妻中出| 成人贴图日韩欧美| 婷婷中文网| 91在线精品一区二区三区| 97超碰影音| 日韩精品熟妇| 发朗少妇买婬全视频中文| 久久久久亚洲av综合波多野制衣| 亚洲欧美碰碰| 色色青青久久| 北京美女一区二区| 天堂av2019| 久久久九九网站| 爽极品影院| 免费观看日本操逼视频| 999热日韩精品| 欧美日韩天堂| 综合网久久| 日韩美一区| 激情五月综合网| 黑人精品成人一区二区三区| 国产亚洲欧美每日在线| 国产农村妇女精品| 亚洲男人在线观看天堂| 97jingpin| 国产二区三区粉嫩在线| 97 亚洲 日韩 欧美 在线| 天天干,夜夜爽| 久久99亚洲精品久久99果| 一起草日韩| 老司机天天操| 精品久久无码午夜福利| 97欧美超碰| 精品久9| 香蕉精品二区二区| yazhououmeizongya| 色婷婷一区二区三区久久午夜| 久久鲁夜| 99RE在线视频精品,这里只有精品| 亚洲精品一区二区三区新线路| 91美女丝袜诱惑视频| 成人综合久久精品色婷婷| 国产精品无码在线| 97国产高清视频在线观看| 福利操逼| 国产精品麻豆视频网站| 国产一区自拍欧美日韩| 人人贴人人摸| 日韩欧美成人午夜福利| 欧美探花网| 午夜操逼不卡| 口爆吞精在线观看| 可以免费观看的日韩av毛片| 日韩欧美tv一区二区在线观看| 天天摸夜夜添无码小视频| 激情五月综合开心五月| 欧美日韩黄片精品在线| 女同女同恋久久级三级| 为用户提供免费看黄网址在线观看| 大屁股人妻女教师撅着屁股| 99久久久久久亚洲精品不卡| 日婷婷| 午夜AV人气不卡| av在线免费一区二区| 成年人一级黄色毛片大全在线观看| 亚洲天堂7777| 色综合久| 欧美 亚洲 制服 精品| 欧美精品丝袜久久久中文字幕| 蜜臀久久在线视频| 99热8| 91日产桃蜜| 国产精品久久| 国产乱伦亚洲| 国产又操| 97资源超碰| 国产不卡中文字幕免费avi| 日韩少妇在线视频| 亚洲天堂久久| 成年无码动漫av片无尽在线| 日本1区2区不卡视频| 乱伦日本色图AⅤ| 密桃99999| 久久只有精品一区二区三区| 亚洲自拍欧美色综合| 色97国产69香蕉| 成人久久久| 操逼天美3区| 日本曲间由美性生活片| 日日骚 av| 亚洲色欧| 日韩有码 一区二区三区| 国产精品无码久久久久2028| 色9999日韩国产| 一区二区三区男女操逼黄色小电影| 加勒比AV天堂| 校园激情狠狠四射| 蜜乳视频网站| 婷婷久久五月| 久久超碰97中文字幕| 国内外毛片在线观看| 欧美国产精品久久九九| 亚洲欧洲日韩国产自在线| 99这里有精品视频| 污污污8888| 骚女天天综合网| www.91逼逼.com| 亚洲av在线免费观看| 狠狠躁天天躁日日躁| 超碰碰97资源站| 十八禁av无码免费网站APP| 丁香五月色情| h色99999| 青娱乐999| 人人爱操| 呦女网站| 豆花视频操逼网址| 26uuu欧美| 亚洲中亚日激情视频| 51国产午夜精品视频| 亚洲色综合| 色臀aV| 日韩精品一区二区高清 | 亚洲欧洲国产综合av| 欧美日韩少妇色情| 欧美综合亚洲综合| 26uuu国产免费观看| 330Dv国产女人终合视频极品人与兽| 久久久久女教师免费一区| 日韩激情啪啪啪| 人人手机欧洲亚洲国产人妻| 久久黄黄黄| 青青久久手机线视频| 久久综合久久综合人久久夜精品| 日韩欧美中文字幕搭讪巨乳美人妻视频| AA级电影三区| 91人人爽人人爽| 午夜美女诱惑电源网| 嫩草一区二区在线观看| 狠插 制服 自拍| 亚洲91在线| 亚洲色五月| 91蜜桃传媒精品久久久一区二区| 九月丁香婷婷色| 久久久久久久久九九久孕交| 试看60秒 爽| 久久天堂婷婷网| 男人天堂毛片| 国产福利精品最新在线| 国模91| 久久久久久精品免费看A级| 无码久| 成人a大片在线观看| 99re只有精品| 91成人高清在线观看| 怡红院怡春院| 免费A片三p视频| 综合国产97| 日韩成人无码| 亚洲色欲一区二区三区| 人人人干干人人干| 大香蕉伊人一区在线观看| 一区二区高清视频| 116美女午夜| 91久久久亚洲| 吉田爱美AV在线| 久久久国产av美女私房| 国产黄色动态精品| 人人摸.人人色| 亚洲AV不卡在线观看尤物| 大黄片做爱的大的| 超碰久久精品| 国产女性无套 免费观看| 2019男人的天堂| 99热这里是精品| 欧美性夜| 内射中出日韩在线观看视频| 超碰在线人妻中文字幕| 玖玖资源中文字幕制服丝袜| 亚洲欧洲日韩天堂av| 中文字幕人乱码中文字的预防方法| 人人操人人搞人人草| 玖玖超碰熟| 天天操综合网| 免费AV中文网在线观看| 1区2区3区中文字幕日韩| 狠日操| 91白虎| 99999精品视频| 人人操人人干网页| 深夜激情 | 91天美传媒精品| 亚洲欧洲精品视频发布| 成人草草视频| 五月天黄色av| 国产网红精品| 99热婷婷一区二区三| 精品久久在线区一区| 中文字幕乱在线伦视频中文字幕乱码在线 | 99999亚洲| 日韩99神马视频播放| 天堂中文日本在线观看| 传媒在线观看一区二区三区| 女人妻一区| 家庭乱伦网站国产| 91熟女网| 亚洲色香| 久久性爱视频| 日小BB小视频| 97综合激情| 国产天天看| 国产精品成人在线| 午夜a成v人电影| 97伊人超碰| 欧美精品偷拍| 97色碰| 神马久久久久久伦理片| 欧美一级二级三级| 日本欧美色| 女优视频第10页| 亚洲av综合色区无码一| 97超碰日韩| 日韩精品影视| 欧美三级免费伊人| 丁香五月综合| 日韩在线一区高清在线| 精品97久久| 2017天天透天天通天天擦| 五月黑AⅤ| 99热这里只有精品地址| 中国AV美女| 啊啊啊啊操死我| 在线色资源| 做爱福利视频一区二区| 天堂蜜桃无码视频一区二区| 粉嫩av在线一区二区| 日韩偷拍一区二区三区 | 一区二区亚州激情久婷婷欧美| 江都AV在线| 丁香六月综合激情| 岛园激情| 亚洲男人的天堂V| 久久曰曰| 午夜寂寞欧美| 九月激情婷婷| 国产又黄又爽| 欧美碰碰综合色| 中文字幕无码不卡啪啪| 欧美色图 人妻| 欧美性暴力猛交XXXX| 亚洲色图久久成人| 丁香五月偷拍| 国产无马av| 免费看欧美美女黄色大片 | 日韩精品碰碰| 国产精品露脸在线观看| 亚洲国产精品无码AV久久| 欧美色图20P| 欧洲亚洲人妻无码久久三区四区| 午夜综合在线| 亚州熟妇精品| baiduhicn.com。| 欧美性爱一区| 伊人丝袜美腿高跟在线观看高清| 国产精品小视频一区二区三区| 伊人成人中文字幕久久网| 9999久久久久| www.久久爱| 亚洲激情AV| 婷婷色网| 大香蕉亚洲中文| 亚洲天堂综合AV| 一区二区你上我| 亚州色交| 一区二区三区网站日日骚| 亚洲国产欧美日韩人妻日中文| 中文字幕在线观看丝袜| 日本高清久久| 少妇一线天久久久久久| 激情AV| 加勒比AV天堂| 狠综合网| 精品二999| 亚州欧美综合| 日本高清视频在线观看黄已三辽| 超碰97欧美日韩| 久草久日| 97久操| 亚洲加勒比| PMv在线观看| 综合国产影视三级| www.大香| 最新日韩黄片| 日韩三级一区| 中文字幕一区二区三区蜜臀| 亚洲A色| 亚拍在线| 久久超碰天天| 亚洲激情片| 国产强奸乱伦xd| 欧美亚洲日本视频久久久| 久久艹逼视频| 骚货| 色www精品视频在线观看| 国产亚热在线久久| 麻豆亚洲AV成人无码久久精品| 国产精品白领在线观看 | 97精品97久久| 欧美日韩不卡传媒| 少妇久久| 亚洲最大成人a毛毛片| 国产久久久久久久久一区二区| 亚洲色鬼| 久久久99999久网站| 亚州欧美另类| 国产婷婷综合在线观看| 亚洲图片欧洲图片aⅴ| 东京热激情视频一二三区| 午夜福利区| 国产精品乱码久久久久久久久| 国产视频人人网| 国产午夜激片Av毛片不卡| 一区二区偷拍拍视频| 97精品97| 97狠狠| 欧美丝袜制服久久| 美女露胸露屁股| 99国产精品自在自在|