精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

WPF控件編程

開發(fā) 后端
在自定義控件的實現(xiàn)中,軟件開發(fā)人員需要通過FrameworkTemplate.FindName()函數(shù)從當前控件所使用模板的實例尋找具有特定名稱的組成。完成該工作的最常見方法就是在靜態(tài)構(gòu)造函數(shù)中重寫依賴項屬性DefaultStyleKey的默認值.

  WPF提供了一系列預(yù)定義組件以供UI開發(fā)人員使用。但軟件開發(fā)人員仍常常需要自行編寫滿足特定要求的控件。本文就將以Spinner控件為例,講解如何以派生方式完成自定義控件的編寫。

  一.動手前的思考

  在著手開始編寫控件之前,我們需要思考Spinner需要以怎樣一種方式實現(xiàn)?MSDN建議使用三種控件實現(xiàn)方式:從UserControl類派生,從Control類派生以及從FrameworkElement類派生。

  要正確地從這三種方式中作出選擇,軟件開發(fā)人員首先需要了解這些實現(xiàn)方法的特點。從UserControl類派生和WPF應(yīng)用程序開發(fā)模型非常類似:控件僅僅由現(xiàn)有控件組成,并通過XAML描述。其支持樣式和觸發(fā)器。通過這種方式定義的自定義控件并不希望軟件開發(fā)人員通過模板指定其外觀。

  從Control類派生則是大多數(shù)控件開發(fā)所使用的方式。與從UserControl類派生這一方法不同,其外觀并不是由關(guān)聯(lián)的XAML文件指定的,而常常由主題文件所指定。從該類派生的特點有:1) 可以通過ControlTemplate自定義控件的外觀。2) 控件可以支持不同的主題。

  而從FrameworkElement類派生則需要徹底拋棄使用控件元素組合的開發(fā)方式(無論是在Template中還是UserControl定義中)。生成基于FrameworkElement的組件有兩種標準方法:直接呈現(xiàn)和自定義元素組合。

  直接呈現(xiàn)是指重寫FrameworkElement的OnRender方法,并提供顯式定義組件視覺效果的DrawingContext操作,如Image類和Border類就是通過這種方法定義的。例如精簡后的Border類的OnRender()函數(shù)如下所示:

  1. protectedoverridevoidOnRender(DrawingContext dc)  
  2. {  
  3. ……  
  4. dc.DrawRoundedRectangle(…);  
  5. ……  

   另一種則是使用Visual類實例組合對象外觀。如Track就是使用組合對象外觀的實例。Track類提供了Thumb屬性,并在其內(nèi)部實現(xiàn),如ArrangeOverride()函數(shù)中,都考慮了對該組成的使用。

  從FrameworkElement中派生的優(yōu)點有:1) 可以完成對控件外觀的精確控制,而不僅僅是簡單的元素組合。2) 通過定義自己的繪制邏輯定義控件的外觀。

  很顯然,Spinner控件需要使用從Control類派生的方法,以提供對模板的支持。當然,這里并非是指Spinner控件直接從Control類派生,而是選擇Control類的一個派生類作為Spinner的基類。這實際上與WPF中的控件類型組織特點有關(guān)。WPF中,代表各個控件的類型的繼承層次按照控件特征以非常細致的方式劃分,并在每個繼承層次中僅添加對一個到兩個特征的支持。就以Button類為例。該類型與Control類之間還存在著兩層派生:ContentControl類以及ButtonBase類。這兩個類型不僅僅分別提供了Content屬性以及命令相關(guān)的屬性,更重要的是,其內(nèi)部提供了支持這些屬性的默認實現(xiàn)。在這種情況下,軟件開發(fā)人員僅僅在默認實現(xiàn)不再滿足條件時才需要更改這些默認實現(xiàn)所提供的邏輯,從而大大減少了開發(fā)新控件所需要的時間。

  正是由于這個原因,我們需要在編寫一個控件之前仔細選擇其所需要使用的基類。選擇一個合適基類的標準就是該類型提供了最多的可重用功能,卻沒有提供過多的冗余功能。而基類的尋找也按照尋找相似控件,沿相似控件的繼承層次由高到低逐個篩選兩步。

  在尋找相似控件的時候,軟件開發(fā)人員需要簡單地揣摩一下該控件的使用方法,以尋找具有相似功能的控件。一般情況下,Spinner需要擁有一個***值,一個最小值,并擁有一個當前值。軟件開發(fā)人員可以通過Spinner上的按鈕調(diào)整當前值的大小,也可以通過輸入框直接輸入當前值的大小。這和滾動條控件非常相像,只不過滾動條的直接輸入是通過Thumb完成的。然后我們需要反過來想想,是否ScrollBar提供了過多的Spinner所不需要或不支持的功能。顯然ScrollBar所提供的ViewportSize、Orientation等都不是Spinner所需要的屬性,因此其并不適合作為Spinner的基類。接下來我們可以依次考慮ScrollBar的各個基類,直到選中了一個較為適合的基類為止。就Spinner而言,RangeBase類就是一個較為合適的基類。

  這里我們將遇到一個岔路口,那就是是否可以通過僅僅更改現(xiàn)有控件的模板這一方式滿足用戶的需求。如果可以,那么使用自定義模板則是更好的選擇。

  在確定需要從某個類派生之后,軟件開發(fā)人員就應(yīng)該檢查該類所提供的各個依賴項屬性所具有的默認值是否是一個合理的默認值。例如RangeBase類指定了Value屬性的默認值為0,最小值為0而***值為1。而對于Spinner而言,由于其常常需要操作整數(shù),因此這些默認值都是不適合的。軟件開發(fā)人員需要在類型的靜態(tài)構(gòu)造函數(shù)中對這些默認值進行重寫:

  RangeBase.ValueProperty.OverrideMetadata(typeof(Spinner), newFrameworkPropertyMetadata(10.0, OnValuePropertyChanged));

  RangeBase.MaximumProperty.OverrideMetadata(typeof(Spinner), newFrameworkPropertyMetadata(20.0));

  RangeBase.LargeChangeProperty.OverrideMetadata(typeof(Spinner), newFrameworkPropertyMetadata(1.0));

  RangeBase.SmallChangeProperty.OverrideMetadata(typeof(Spinner), newFrameworkPropertyMetadata(1.0));

  需要注意的是,OverrideMetadata()函數(shù)中所提供的屬性默認值需要與屬性的類型匹配。例如在為Maximum屬性指定默認值時使用整型數(shù)值20,那么對OverrideMetadata()函數(shù)的調(diào)用將導(dǎo)致程序崩潰。

  在更改屬性的默認值時,軟件開發(fā)人員需要考慮控件所應(yīng)實際具有的意義。就以ComboBox和ListBox為例。在什么情況下應(yīng)使用ComboBox,而什么情況下應(yīng)使用ListBox呢?回答該問題的決定性因素就是這兩個控件所具有的特征,進而導(dǎo)致的用戶體驗的區(qū)別。ComboBox可以通過下拉列表顯示所有的可選項,并通過編輯框組成顯示當前項。這種對數(shù)據(jù)的顯示方式較ListBox占用了更小的空間,并突出顯示了當前選中項。而相對于ComboBox,ListBox則在全面展示數(shù)據(jù),尤其是關(guān)聯(lián)型數(shù)據(jù)上較有優(yōu)勢。

  同樣的,Spinner也有自己存在的意義。Spinner的中文名稱被稱為微調(diào)控件。從名稱上就可以看出,對Spinner的操作更多的是微小的調(diào)整。同時,Spinner所提供的輸入框常常允許用戶直接輸入需要的數(shù)值,從而達到對數(shù)值精確的控制。也就是說,相對于ScrollBar等組成,其更注重于對值的精確指定。這也便是我在Spinner中添加精度控制屬性的一個原因。當然,該部分內(nèi)容我會在后面繼續(xù)介紹。

  在真正開始編寫控件之前,我們還需要考慮的事情就是用戶的使用方法。一般的用戶輸入都是通過鼠標和鍵盤來完成的,因此我們就將用戶使用方法歸結(jié)為鼠標和鍵盤兩類。

  先來看看鼠標。鼠標需要考慮的主要分為擊鍵和滾輪兩種操作。在鼠標左鍵點擊增加及減少按鈕時,數(shù)值需要隨鼠標的擊鍵而更改,并提供適當?shù)耐庥^反饋。在鼠標左鍵點擊輸入框時,光標需要移動到相應(yīng)位置。而在鼠標右鍵點擊輸入框時,對文本進行操作的菜單需要被彈出。在鼠標滾輪滾動時,Value的值需要同時進行更改。

  接下來是鍵盤。一般情況下,鍵盤操作常常與非字符輸入鍵相關(guān)聯(lián)。例如用戶通過Tab等操作導(dǎo)航到控件之后,擁有輸入框組成的控件將自動把其內(nèi)容全部選中。而用戶敲擊Enter鍵則表示他同意當前數(shù)值。輸入焦點應(yīng)轉(zhuǎn)移到下一個控件以便用戶繼續(xù)操作。同時對于范圍類型控件而言,Up和Down表示小范圍數(shù)值變化,而PageUp和PageDown則表示大范圍數(shù)值變化。對于Spinner來說,微調(diào)是其主要功能,因此令小范圍數(shù)值變化和大范圍數(shù)值變化的值相等也是合情合理的。

  ***,在開始編寫控件之前,我們需要借鑒一下WPF中的基于同一基類的類似控件的實現(xiàn)。有關(guān)如何得到WPF源代碼的方式,請查看“從Dispatcher.PushFrame()說起”一文。通過觀察這些控件的實現(xiàn),我們可以更好地了解基類所提供的擴展點以及這些擴展點的使用方法。

  二.開始實現(xiàn)

  在本節(jié)中,我們就將開始著手實現(xiàn)Spinner。右鍵點擊項目文件,并在彈出菜單中選擇“Add”->“New Item”。在彈出的對話框中選擇“Custom Control(WPF)”并在名稱輸入框中輸入“Spinner.cs”,如圖所示:

  在點擊Add按鈕決定添加控件以后,Visual Studio將為我們添加兩個文件:Spinner.cs以及表示默認主題的Generic.xaml。

  2.1 模板支持

  通常情況下,我都會在主題文件中放置控件的一個簡單模板實現(xiàn)。例如一開始,我在Generic.xaml中為Spinner定義了如下外觀:

  1. <Style TargetType="{x:Type local:Spinner}"> 
  2. <Setter Property="Control.Template"> 
  3. <Setter.Value> 
  4. <ControlTemplate TargetType="{x:Type local:Spinner}"> 
  5. <Border Background="{TemplateBinding Background}"BorderThickness="0.5"  
  6. BorderBrush="{TemplateBinding BorderBrush}"> 
  7. <Grid> 
  8. <Grid.RowDefinitions> 
  9. <RowDefinition Height="*"/> 
  10. <RowDefinition Height="*"/> 
  11. </Grid.RowDefinitions> 
  12. <Grid.ColumnDefinitions> 
  13. <ColumnDefinition/> 
  14. <ColumnDefinition Width="20"/> 
  15. </Grid.ColumnDefinitions> 
  16. <TextBox x:Name="PART_Input"Grid.Column="0"Grid.Row="0" 
  17. Grid.RowSpan="2"Margin="0.5"BorderThickness="0" 
  18. Background="{TemplateBinding Background}"/> 
  19. <RepeatButton x:Name="PART_Decrease"Grid.Column="1"Grid.Row="0" 
  20. Margin="0.5"/> 
  21. <RepeatButton x:Name="PART_Increase"Grid.Column="1"Grid.Row="1" 
  22. Margin="0.5"/> 
  23. </Grid> 
  24. </Border> 
  25. </ControlTemplate> 
  26. </Setter.Value> 
  27. </Setter> 
  28. </Style> 

   雖然這并不是最終的控件外觀,但是通過該控件模板,我們可以隨時測試Spinner控件所包含的邏輯。

  在該控件模板定義中,我們?yōu)閹讉€組成提供了特殊的名稱,如PART_Input。在模板定義中,以PART_開頭的名稱表示該名稱所對應(yīng)的組件是在控件內(nèi)部使用的模板定義中必不可少的一部分。為該控件所提供的其它模板同樣需要為這些名稱提供相應(yīng)的組成。

  在自定義控件的實現(xiàn)中,軟件開發(fā)人員需要通過FrameworkTemplate.FindName()函數(shù)從當前控件所使用模板的實例尋找具有特定名稱的組成。使用該函數(shù)的前提條件則是控件的模板已經(jīng)被施行。因此,調(diào)用該函數(shù)的最適合位置就是重載函數(shù)OnApplyTemplate()函數(shù)。如下面代碼所示:

 

  1. publicoverridevoidOnApplyTemplate()  
  2. {  
  3. mInputTextBox = null;  
  4. mDecreaseButton = null;  
  5. mIncreaseButton = null;  
  6. base.OnApplyTemplate();  
  7. if(Template != null)  
  8. {  
  9. mInputTextBox = Template.FindName("PART_Input"this) asTextBox;  
  10. mDecreaseButton = Template.FindName("PART_Decrease"this) asRepeatButton;  
  11. mIncreaseButton = Template.FindName("PART_Increase"this) asRepeatButton;  
  12. }  

 

  為了能讓模板設(shè)計人員能夠知道這些必須在模板定義中出現(xiàn)的名稱以及這些名稱所對應(yīng)的控件類型,WPF提供了TemplatePart特性。該特性提供了兩個屬性Name及Type。Name用來標記模板定義中需要添加的組成名稱,而Type則用來指明該名稱所需要具有的類型。如下面代碼所示:

 

  1. [TemplatePart(Name="PART_Input"Type=typeof(TextBox)),  
  2. TemplatePart(Name="PART_Decrease"Type=typeof(RepeatButton)),  
  3. TemplatePart(Name="PART_Increase"Type=typeof(RepeatButton))] 

 

  在使用了該特性的情況下,模板設(shè)計人員可以直接通過該特性聲明得知模板中所應(yīng)具有的相應(yīng)元素以及其類型。

  2.2 功能實現(xiàn)

  現(xiàn)在我們就需要考慮如何實現(xiàn)控件所對應(yīng)的功能。控件與模板之間進行互動的方法主要分為兩種:綁定和偵聽模板組成所發(fā)出的事件。在實現(xiàn)自定義控件時,我們需要盡量使用綁定。但是對于特殊的處理邏輯,我們常常不能通過綁定完成相應(yīng)功能。在這種情況下,軟件開發(fā)人員就需要通過偵聽模板組成所發(fā)出的事件這一方式。

  現(xiàn)在就來想想Spinner所需要使用的操作方式:對按鈕控件的輸入可能更改當前值,同時在輸入框中執(zhí)行輸入并回車同樣可以確認當前值。對按鈕的點擊可以觸發(fā)Click事件,更可以觸發(fā)按鈕控件所關(guān)聯(lián)的命令,而在輸入框中敲擊回車鍵則只會觸發(fā)Keydown事件。因此在每次施行模板之后,我們需要為特定組成添加這些處理邏輯:

 

  1. privatevoidAttach()  
  2. {  
  3. if(mDecreaseButton != null)  
  4. mDecreaseButton.Command = mDecreaseCommand;  
  5. ……  
  6. if(mInputTextBox != null)  
  7. {  
  8. mInputTextBox.Text = Value.ToString();  
  9. mInputTextBox.InputBindings.Add(newKeyBinding(mIncreaseCommand,  
  10. newKeyGesture(Key.Down)));  
  11. ……  
  12. mInputTextBox.PreviewKeyDown += PreviewTextBoxKeyDown;  
  13. mInputTextBox.LostKeyboardFocus += TextBoxLostKeyboardFocus;  
  14. }  

 

  與之對應(yīng)的是,在每次施行模板之前,我們則需要取消這些處理邏輯:

  1. privatevoidDetach()  
  2. {  
  3. if(mInputTextBox != null)  
  4. {  
  5. mInputTextBox.PreviewKeyDown -= PreviewTextBoxKeyDown;  
  6. mInputTextBox.LostKeyboardFocus -= TextBoxLostKeyboardFocus;  
  7. }  

 

  這是因為添加的消息處理函數(shù)會對消息源生成一個引用。而取消該消息的偵聽則會釋放該引用。

  這里,我們來看一下Attach()函數(shù)中所展示的互動方式。

  首先是命令。在這里我們使用mDecreaseCommand為按鈕指定命令。為什么使用命令,而不是路由事件?這取決于是否該用戶行為是否需要被用戶知曉。相對于路由事件,路由命令會在遇到相應(yīng)的執(zhí)行邏輯后不繼續(xù)執(zhí)行路由,從而對用戶不可見。

  為了支持這些命令,軟件開發(fā)人員需要為Spinner設(shè)置CommandBinding以及InputBinding。CommandBinding為命令指定執(zhí)行邏輯,而InputBinding則為命令指定觸發(fā)命令的執(zhí)行條件。這部分邏輯通常在Spinner的構(gòu)造函數(shù)中完成:

 

  1. publicSpinner()  
  2. {  
  3. CommandBindings.Add(newCommandBinding(mIncreaseCommand,  
  4. OnIncreaseCommand, CanExecuteIncreaseCommand));  
  5. ……  
  6. InputBindings.Add(newKeyBinding(mIncreaseCommand, newKeyGesture(Key.Down)));  
  7. ……  

 

  接下來要考慮的則是使用命令之外的另一種處理邏輯,事件。在事件PreviewKeyDown中,我們需要判斷用戶按下的是否是回車鍵。如果是,那么用戶的當前輸入將會被驗證,并根據(jù)用戶輸入的正確性決定對Value值的刷新。這里存在著幾個需要寫到的問題。首先就是為什么用Preview-事件。TextBox會在處理用戶輸入時將KeyDown事件的handled設(shè)置為true,因此軟件開發(fā)人員不能直接使用KeyDown事件,而是使用PreviewKeyDown事件。另一個則是InputBinding有效的時機。InputBinding是由KeyDown事件所驅(qū)動的。在KeyDown事件被TextBox處理之前,TextBox實例內(nèi)設(shè)置的InputBinding將被處理;而在TextBox中,KeyDown事件的handled屬性會在處理過程中被設(shè)置為true,從而使TextBox的各個祖先元素失去了處理InputBinding的機會。這也便是Attach()函數(shù)為TextBox類型成員mInputTextBox添加額外的InputBinding的原因:

 

  1. privatevoidAttach()  
  2. {  
  3. ……  
  4. if(mInputTextBox != null)  
  5. {  
  6. ……  
  7. mInputTextBox.InputBindings.Add(newKeyBinding(……));  
  8. ……  
  9. }  

 

  接下來,考慮到微調(diào)控件的每次調(diào)整可能并不是整數(shù),因此我們還需要為Spinner提供一種控制顯示精度的方法。這便是添加Precision屬性的原因。該屬性會通過double.ToString()函數(shù)控制當前值的格式化執(zhí)行方式,以顯示特定的精度:

 

  1. privatestringGetValueString()  
  2. {  
  3. intprecision = Precision <0? 0: Precision;  
  4. stringformat = string.Format("F{0}", precision);  
  5. returnValue.ToString(format);  

 

  2.3 更改主題

  在實現(xiàn)了所有功能之后,我們就應(yīng)該開始準備為控件指定主題。

  首先要提及的就是如何為控件指定默認樣式。為控件指定默認樣式的方法主要是通過設(shè)置DefaultStyleKey屬性完成的。完成該工作的最常見方法就是在靜態(tài)構(gòu)造函數(shù)中重寫依賴項屬性DefaultStyleKey的默認值:

  1. FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(Spinner), newFrameworkPropertyMetadata(typeof(Spinner))); 

  接下來,我們就需要在默認主題文件Generic.xaml中添加Spinner的外觀定義。該外觀定義的部分代碼如下:

  1. <ControlTemplate x:Key="RepeatButtonTemplate"TargetType="{x:Type ButtonBase}"> 
  2. <Border x:Name="Chrome"BorderThickness="0, 0, 1, 1"Background="Transparent"> 
  3. <ContentPresenter …/> 
  4. </Border> 
  5. …  
  6. </ControlTemplate> 
  7. <Style TargetType="{x:Type local:Spinner}"> 
  8. …  
  9. <ControlTemplate TargetType="{x:Type local:Spinner}"> 
  10. <Border …> 
  11. …  
  12. <TextBox x:Name="PART_Input"Grid.Column="0"Grid.Row="0"Grid.RowSpan="2" 
  13. Background="{TemplateBinding Background}"/> 
  14. <RepeatButton x:Name="PART_Decrease"Grid.Column="1"Grid.Row="0" 
  15. Template="{StaticResource RepeatButtonTemplate}"> 
  16. <Path x:Name="UpTriangle"StrokeThickness="1"Data="M 3,0 L 0,4 6,4 Z"/> 
  17. </RepeatButton> 
  18. …  
  19. </Border> 
  20. <ControlTemplate.Triggers> 
  21. <DataTrigger Binding="{Binding IsMouseOver, ElementName=PART_Decrease}"> 
  22. <Setter TargetName="UpTriangle"Property="Stroke"Value="Blue"/> 
  23. <Setter TargetName="UpTriangle"Property="Fill"Value="Blue"/> 
  24. </DataTrigger> 
  25. …  
  26. </ControlTemplate.Triggers> 
  27. </ControlTemplate> 
  28. …  
  29. </Style> 

   如果軟件開發(fā)人員希望為不同的Windows主題提供不同的外觀,那么他可以通過為特定主題提供特定外觀或是偵聽WM_THEMECHANGED事件完成。在需要為特定主題提供特定外觀時,軟件開發(fā)人員需要在項目的Themes文件夾下添加對應(yīng)的主題文件,如Windows經(jīng)典主題對應(yīng)的就是ThemesClassic.xaml。而如果對主題更改的支持是通過偵聽WM_THEMECHANGED事件完成的,那么對控件模板的更換則需要通過代碼顯式完成。

  同時,軟件開發(fā)人員還可以通過ThemeInfo特性指定主題文件所存在的位置。該特性擁有兩個和主題相關(guān)的屬性:GenericDictionaryLocation以及ThemeDictionaryLocation。這兩個屬性分別指定了與主題相關(guān)的通用資源所在的位置以及特定于主題的資源所在的位置。它們都接受類型為ResourceDictionaryLocation的枚舉值。該枚舉值中,None表示不使用主題,SourceAssembly表示主題存在于當前程序集中,而ExternalAssembly則表示主題字典存在于受主題影響的外部程序集中。

  對于本例的示例控件Spinner而言,對ThemeInfo主題的使用如下:

  1.   [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] 

  源碼地址:http://download.csdn.net/detail/silverfox715/4050356

  轉(zhuǎn)載請注明原文地址:http://www.cnblogs.com/loveis715/archive/2012/02/08/2340795.html

原文鏈接:http://www.cnblogs.com/technology/archive/2011/04/19/2020910.html

【編輯推薦】

 

 

 

  1. 深入淺出WPF
  2. 教你制作一個簡單的WPF圖片瀏覽器
  3. WPF中兩種不同的視頻流的使用
  4. 新版本W(wǎng)PF功能 彰顯賞心悅目的圖形
  5. C++實現(xiàn)WPF動畫具體操作方法詳解
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2009-12-24 13:46:03

WPF控件

2009-12-28 09:13:50

WPF容器控件

2009-12-28 15:18:29

WPF控件模型

2009-12-24 16:20:43

WPF Tooltip

2009-12-24 15:43:17

WPF控件相對位置

2009-12-23 18:16:35

WPF布局控件

2009-12-28 09:24:58

WPF線程

2009-12-28 10:40:13

WPF調(diào)用Winfor

2009-12-25 17:58:12

WPF進度條

2009-12-23 17:49:28

WPF觸發(fā)器

2010-04-16 09:06:18

WPF 4

2025-02-03 00:35:00

框架程序Windows

2009-12-28 17:40:10

WPF TextBox

2025-07-21 02:25:00

WPFUI控件庫

2010-04-08 09:28:28

WPFWinForm

2009-08-03 18:00:00

ASP.NET服務(wù)器控

2009-08-03 13:43:02

C#日歷控件

2009-12-29 14:58:31

WPF優(yōu)點

2009-12-24 14:08:25

WPF數(shù)據(jù)模板

2009-12-23 10:07:57

學(xué)習(xí)WPF
點贊
收藏

51CTO技術(shù)棧公眾號

欧美女v视频| 欧美成人aaa片一区国产精品| 美女福利一区二区三区| 久久久久国产精品麻豆| 国产精品中文字幕在线观看| 日本老熟俱乐部h0930| 日韩成人一级| 欧美精三区欧美精三区| www.成年人视频| 黄色片视频在线观看| 国产一区二区三区在线观看精品| 97在线看免费观看视频在线观看| 在线免费看黄视频| 国产一区二区三区黄网站| 精品国产精品自拍| 国产奶头好大揉着好爽视频| 天天干天天爽天天操| 蜜臀av一区二区在线免费观看| 欧美精品18videos性欧美| 色综合99久久久无码国产精品| 成人污版视频| 欧洲色大大久久| 日本欧美视频在线观看| 国产成人l区| 国产亚洲一区二区三区四区 | 日韩在线精品一区| 中文成人无字幕乱码精品区| 免费一区二区三区四区| 岛国av一区二区| 久久香蕉视频网站| 亚洲成人三级| 欧美国产精品劲爆| 欧美午夜视频在线| 欧洲av在线播放| 国产在线不卡一区| 国产精品亚洲欧美导航| 69亚洲精品久久久蜜桃小说| 国内揄拍国内精品久久| 精品国产一区二区三区久久狼黑人| 蜜臀av一区二区三区有限公司| 亚洲一区二区三区日本久久九| 欧美日韩国产小视频| www.日日操| 色一区二区三区| 亚洲成av人片www| 妞干网视频在线观看| 精品视频在线一区二区| 国产精品日韩成人| 亚洲国产日韩欧美| 91最新在线| 国产精品视频线看| 亚洲韩国在线| 日本高清在线观看wwwww色| 日本一区二区三级电影在线观看| 欧美日产一区二区三区在线观看| 欧美偷拍视频| 久久久91精品国产一区二区三区| 欧美在线日韩精品| 免费在线黄色网址| 国产欧美一区二区精品婷婷| 任我爽在线视频精品一| 电影av一区| 国产精品伦理在线| 日本一区二区三区四区五区六区| 超碰免费公开在线| 亚洲免费观看高清| 2018中文字幕第一页| jizz一区二区三区| 欧美日韩在线免费| 男人天堂成人在线| 91成人短视频在线观看| 欧美一区二区久久久| 人妻 丝袜美腿 中文字幕| heyzo欧美激情| 日韩精品在线看| 97超碰在线免费观看| 欧美亚洲国产激情| 欧美理论片在线观看| 精品一区免费观看| 免费视频一区二区三区在线观看| 国产成人中文字幕| 一级片一区二区三区| 国产精品456露脸| 狠狠综合久久av| 福利视频在线播放| 一区二区三区影院| 国产三区在线视频| 日韩欧美激情| 亚洲二区在线播放视频| 亚洲精品国产熟女久久久| 性欧美欧美巨大69| 午夜精品一区二区三区在线 | 丝袜国产日韩另类美女| 国产一区视频在线| 嫩草影院一区二区| 国产精品日产欧美久久久久| www.国产在线播放| 激情亚洲小说| 亚洲国产欧美久久| 欧美性生给视频| 亚洲乱码久久| 国产欧美精品一区二区三区-老狼| 超碰福利在线观看| 国产日韩欧美制服另类| 国产一区二区三区小说| 国产麻豆一区| 日韩激情片免费| 丁香花五月激情| 日韩精品乱码免费| 成人欧美一区二区三区视频| 成年在线电影| 精品女厕一区二区三区| 99日在线视频| 九九久久婷婷| 久久久人成影片一区二区三区| 激情视频网站在线观看| 成人一道本在线| 中文字幕一区二区三区精彩视频 | 91精品免费视频| 欧美女优在线观看| 天天做天天摸天天爽国产一区| www.夜夜爽| 国产99久久精品一区二区300| 久久久久久九九九| 国产乱码精品一区二三区蜜臂 | 日本午夜精品电影| av福利导福航大全在线| 91精品国模一区二区三区| 国产肥白大熟妇bbbb视频| 亚洲高清久久| 99国产高清| www.在线视频| 在线播放一区二区三区| 91成人在线免费视频| 99日韩精品| 国产欧美在线一区二区| 伊人影院在线视频| 欧美一级片免费看| caoporn91| 加勒比av一区二区| 不卡中文字幕在线| 日本免费成人| 日韩在线视频播放| 亚洲视频在线观看免费视频| 久久一日本道色综合| 久久久久久久中文| 欧美美女在线直播| 91av国产在线| 无码精品人妻一区二区三区影院| 亚洲午夜av在线| 国产精品久久久久久亚洲色 | 亚洲av综合色区无码一二三区| 国产精品国产三级国产| 91亚洲免费视频| 日韩精品久久| 91精品久久久久久久久久久 | 97国产真实伦对白精彩视频8| 亚洲国产精品欧美久久| 亚洲va欧美va人人爽午夜| a级片在线观看视频| 亚洲精品系列| 蜜桃导航-精品导航| 久久久久久久| 中文字幕一区日韩电影| 一卡二卡在线视频| 一区二区三区欧美视频| 亚洲成年人av| 久久不射2019中文字幕| 四虎一区二区| 91精品麻豆| 久久久久久中文| 你懂的好爽在线观看| 欧美视频在线观看一区| 国产美女福利视频| 成人小视频在线| 99蜜桃臀久久久欧美精品网站| 精品视频免费在线观看| 成人性生交大片免费看小说| 福利成人导航| 亚洲人精品午夜在线观看| 96亚洲精品久久久蜜桃| 亚洲一区二区精品视频| a级大片在线观看| 捆绑变态av一区二区三区| 日韩精品久久一区二区| 亚洲国产网址| 国产日韩欧美在线观看| 大香伊人久久| 综合国产在线观看| 丰满人妻av一区二区三区| 91黄色激情网站| 国产精品丝袜一区二区| 久久久一区二区三区| 欧美一级小视频| 国产亚洲精品久久久久婷婷瑜伽| 亚洲精品久久区二区三区蜜桃臀| 午夜视频在线观看精品中文 | 精品一级视频| 国产91色在线|免| 91精品久久久久久粉嫩| 亚洲欧美中文日韩v在线观看| 精品国产无码一区二区| 日本高清无吗v一区| 麻豆影视在线播放| 国产日韩精品一区二区浪潮av | 久久久久影视| 91久久久久久久久| 精品国产免费人成网站| 久久久噜久噜久久综合| 日本不卡不卡| 国产午夜精品免费一区二区三区| 亚洲产国偷v产偷v自拍涩爱| 欧美日韩一区二区三区免费看 | 亚洲精品国产精品国自| heyzo一本久久综合| 国产性生活一级片| 秋霞影院一区二区| www.中文字幕在线| 激情综合自拍| 麻豆映画在线观看| 日韩欧美在线中字| 日本免费高清一区二区| 日韩av午夜| 国产综合精品一区二区三区| 久久免费福利| 成人性教育视频在线观看| 欧美亚洲黄色| 国产精品免费视频xxxx| 综合毛片免费视频| 91精品国产91久久| 成人av影院在线观看| 欧美成人h版在线观看| 日本在线观看www| 中文字幕在线国产精品| 在线看的av网站| 中文字幕欧美日韩va免费视频| 日本福利在线观看| 日韩国产欧美精品在线| 亚洲日本香蕉视频| 亚洲精品国偷自产在线99热| 蜜臀av中文字幕| 亚洲成人精品视频| 亚洲美女性生活| 精品三级在线观看| 成人乱码一区二区三区 | 亚洲视频福利| a级免费在线观看| 激情综合在线| 69堂免费视频| 久久精品综合| 午夜视频在线瓜伦| 美国十次了思思久久精品导航| 深夜黄色小视频| 久久精品国产一区二区三| 中文字幕 91| 黑人精品欧美一区二区蜜桃| 日韩精品视频网址| 成人av在线资源| 真人bbbbbbbbb毛片| 久久九九全国免费| 老司机精品免费视频| 中文字幕在线不卡视频| www.av成人| 亚洲成a人v欧美综合天堂下载| 一级免费在线观看| 91福利小视频| 国产精品一区二区黑人巨大| 欧美一区二区三区四区视频| 亚洲黄色在线播放| 国产视频久久久| 9色在线观看| 欧美激情在线有限公司| 色在线视频观看| 91精品久久久久久久久久| 伊人久久大香线蕉av超碰| 精品蜜桃传媒| 日韩毛片视频| www.九色.com| 奇米影视在线99精品| 尤物网站在线看| 菠萝蜜视频在线观看一区| 黄色正能量网站| 国产精品免费久久| 欧美黄色免费在线观看| 一本大道久久精品懂色aⅴ| 亚洲一区中文字幕在线| 亚洲成人1234| 91在线直播| 2020久久国产精品| 电影91久久久| 欧美 日韩 国产在线| 91精品二区| 国产日韩一区二区在线观看| 国产一区999| 亚洲码无人客一区二区三区| 亚洲欧美日韩国产成人精品影院| 午夜毛片在线观看| 91麻豆精品国产综合久久久久久| 香蕉视频网站在线| 欧美精品做受xxx性少妇| 免费福利视频一区二区三区| 51国偷自产一区二区三区的来源| 精品国产乱码久久久久久果冻传媒| 特级西西人体www高清大胆| 肉色丝袜一区二区| 国产高清成人久久| 亚洲日本电影在线| 国产一级片免费在线观看| 精品国产麻豆免费人成网站| se在线电影| 欧美综合在线第二页| 一区视频网站| av不卡在线免费观看| 日韩中文字幕不卡| 欧美肉大捧一进一出免费视频| 亚洲视频在线一区二区| 国产在线一级片| 精品视频在线播放免| 色婷婷视频在线观看| 成人免费福利在线| 欧美日韩国产高清电影| 黄色动漫网站入口| 成人黄页在线观看| 久久久久久福利| 欧美精品123区| 午夜视频在线观看免费视频| 国产精品成久久久久三级| 欧美18免费视频| 欧美大片在线播放| 成人精品国产一区二区4080| 青娱乐国产在线| 欧美一区二区精美| av黄在线观看| 亚洲自拍偷拍一区| 欧美在线亚洲综合一区| 国产欧美一区二| 一区视频在线播放| 国产精品九九九九| 久久天天躁狠狠躁夜夜躁2014| 欧美综合影院| 一区二区三区四区五区精品| 麻豆视频观看网址久久| 国产精品酒店视频| 欧美日韩一区视频| 日本高清视频在线播放| 91啪国产在线| 综合激情婷婷| 日本美女视频网站| 亚洲成国产人片在线观看| 网站黄在线观看| 77777亚洲午夜久久多人| 一本久久青青| 激情五月亚洲色图| 国产精品精品国产色婷婷| 国产乱色精品成人免费视频| 久久国产精品网站| 国产精品黄网站| 欧美爱爱视频免费看| 国产喂奶挤奶一区二区三区 | 欧美大片顶级少妇| 高清毛片在线观看| 日本成人黄色| 狠狠色综合日日| 欧美黑人精品一区二区不卡| 亚洲成人免费在线视频| 最近高清中文在线字幕在线观看1| 欧美另类高清视频在线| 久久国产精品第一页| 欧美卡一卡二卡三| 亚洲激情在线观看视频免费| 日韩电影av| 中文字幕一区综合| 成人国产精品免费观看动漫| 欧美性猛交bbbbb精品| 中文字幕亚洲一区二区三区| 亚洲一区二区三区中文字幕在线观看 | 国产成人av免费观看| 一区二区三区欧美激情| 四虎影院在线域名免费观看| 国产精品久在线观看| 欧美国产激情| 亚洲第一成人网站| 7777精品伊人久久久大香线蕉最新版| 欧美巨大xxxx做受沙滩| 欧美系列一区| 国产成人啪午夜精品网站男同| 国产高潮久久久| 久久中文字幕视频| 青青久久av| 日本r级电影在线观看| 日韩欧美亚洲成人| 中文字幕伦理免费在线视频 | 欧美影院精品一区| 黑人玩欧美人三根一起进| 日韩精品久久久| 国产98色在线|日韩| 中文字幕在线观看免费| 97国产精品视频| 综合久久精品| 欧美激情视频二区|