亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C#:WinForm之Command

2019-11-14 13:38:24
字體:
來源:轉載
供稿:網友

  本文主要介紹WinForm項目中如何像WPF一樣優雅的使用Command來實現業務操作。想必大家已經疲于雙擊控件生成事件處理方法來實現業務操作,如多控件(按鈕、菜單、工具條、狀態欄等命令控件)來做同一個動作,還要控制它們啟用(Enabled)狀態等等,使代碼結構冗長且可讀性差。下面具體介紹和實現WinForm中對Command的應用。

  1. 命令(Command)

    顧 名思義,定義一個命令,繼承至System.Windows.Input.ICommand接口,實現 Execute(object) ,CanExecute(object)方法和 CanExecuteChanged事件。由 CanExecute 確定是否調用 Execute 執行該命令。

     1     /// <summary> 2     /// 定義一個執行的命令。 3     /// </summary> 4     public abstract class Command : ICommand 5     { 6         /// <summary> 7         /// The can executable 8         /// </summary> 9         PRivate bool canExecutable = true;10 11         /// <summary>12         /// 當出現影響是否應執行該命令的更改時發生。13         /// </summary>14         public event EventHandler CanExecuteChanged;15 16         /// <summary>17         /// 定義用于確定此命令是否可以在其當前狀態下執行的方法。18         /// </summary>19         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>20         /// <returns>如果可以執行此命令,則為 true;否則為 false。</returns>21         public abstract bool CanExecute(object parameter);22 23         /// <summary>24         /// 定義在調用此命令時調用的方法。25         /// </summary>26         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>27         public abstract void Execute(object parameter);28 29 30         /// <summary>31         /// 提升命令狀態更改。32         /// </summary>33         /// <param name="parameter">The parameter.</param>34         internal protected void RaiseCommandState(object parameter)35         {36             var able = CanExecute(parameter);37             if (able != canExecutable)38             {39                 canExecutable = able;40                 OnCanExecuteChanged(EventArgs.Empty);41             }42         }43 44         /// <summary>45         /// 觸發當命令狀態更改事件。46         /// </summary>47         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>48         protected virtual void OnCanExecuteChanged(EventArgs e)49         {50             if (CanExecuteChanged != null)51             {52                 CanExecuteChanged(this, e);53             }54         }55     }
    Command 代碼
  2. 命令參數(CommandParameter)

    提供給命令執行時的參數,該對象主要由參數源(Source)和參數源的屬性(Parameter)構成。參數源可繼承至System.ComponentModels.INotifyPropertyChanged接口,實現屬性值更改通知。此 Parameter 必須為屬性(也可以是靜態屬性)。

      1     /// <summary>  2     /// 表示命令參數。  3     /// </summary>  4     public sealed class CommandParameter  5     {  6         private readonly Type sourceType;  7         private readonly object source;  8         private readonly string propertyMember;  9  10         private readonly bool booleanOppose = false; 11         private Command command; 12  13         /// <summary> 14         /// 獲取一個值,該值表示命令參數源。 15         /// </summary> 16         /// <value>The source.</value> 17         public object Source 18         { 19             get { return source; } 20         } 21  22         /// <summary> 23         /// 獲取一個值,該值表示命令參數的類型若當前非靜態類型綁定則為 Source 類型。 24         /// </summary> 25         /// <value>The type of the source.</value> 26         public Type SourceType 27         { 28             get 29             { 30                 return sourceType; 31             } 32         } 33  34         /// <summary> 35         /// 獲取一個值,該值表示命令執行參數。 36         /// </summary> 37         /// <value>The parameter.</value> 38         public object Parameter { get { return ResolvePropertyValue(); } } 39  40         /// <summary> 41         /// 獲取一個值,該值表示參數所屬的命令。 42         /// </summary> 43         /// <value>The command.</value> 44         public Command Command 45         { 46             get 47             { 48                 return command; 49             } 50             internal set 51             { 52                 if (value != command) 53                 { 54                     command = value; 55                     command.RaiseCommandState(Parameter); 56                 } 57             } 58         } 59  60         /// <summary> 61         /// 初始化 RelateCommandParameter 新實例。 62         /// </summary> 63         /// <param name="source">綁定源。</param> 64         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 65         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 66         public CommandParameter(object source, string propertyMember, bool booleanOppose = false) 67         { 68             this.source = source; 69             this.sourceType = source.GetType(); 70             this.propertyMember = propertyMember; 71             this.booleanOppose = booleanOppose; 72             BindNotifyObject(source); 73         } 74  75         /// <summary> 76         /// 初始化 RelateCommandParameter 新實例。 77         /// </summary> 78         /// <param name="source">綁定源。</param> 79         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 80         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 81         public CommandParameter(object source, Expression<Func<string>> propertyMember, bool booleanOppose = false) 82             : this(source, ResolvePropertyName(propertyMember), booleanOppose) 83         { 84  85         } 86  87         /// <summary> 88         /// 初始化一個可指定靜態成員的 RelateCommandParameter 新實例。 89         /// </summary> 90         /// <param name="staticSourceType">靜態類類型。</param> 91         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 92         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 93         public CommandParameter(Type staticSourceType, string propertyMember, bool booleanOppose = false) 94         { 95             this.sourceType = staticSourceType; 96             this.propertyMember = propertyMember; 97             this.booleanOppose = booleanOppose; 98         } 99 100         private void BindNotifyObject(object source)101         {102             if (typeof(INotifyPropertyChanged).IsAssignableFrom(source.GetType()))103             {104                 ((INotifyPropertyChanged)source).PropertyChanged += SourcePropertyChanged;105             }106         }107 108         private void SourcePropertyChanged(object sender, PropertyChangedEventArgs e)109         {110             if (e.PropertyName == propertyMember)111             {112                 if (Command != null)113                 {114                     Command.RaiseCommandState(Parameter);115                 }116             }117         }118 119         private object ResolvePropertyValue()120         {121             var flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic;122             if (source == null)123             {124                 flags |= System.Reflection.BindingFlags.Static;125             }126             else127             {128                 flags |= System.Reflection.BindingFlags.Instance;129             }130 131             var pro = sourceType.GetProperty(propertyMember, flags);132             if (pro == null)133             {134                 throw new MemberaccessException(string.Format("Not found {2} member /"{0}/" in /"{1}/"", propertyMember, sourceType, source == null ? "static" : "instance"));135             }136             if (Type.GetTypeCode(pro.PropertyType) == TypeCode.Boolean)137             {138                 if (booleanOppose)139                 {140                     return !((Boolean)pro.GetValue(source));141                 }142             }143             return pro.GetValue(source);144         }145 146         private static string ResolvePropertyName(Expression<Func<string>> propertyMember)147         {148             if (propertyMember != null)149             {150                 return ((MemberExpression)propertyMember.Body).Member.Name;151             }152             else153             {154                 throw new ArgumentNullException("propertyMember");155             }156         }157     }
    CommandParameter 代碼
  3. 命令綁定(CommandBinding)

    命令和命令參數組合構建成一個綁定對象。

     1     /// <summary> 2     /// 定義命令綁定對象。 3     /// </summary> 4     public sealed class CommandBinding 5     { 6         /// <summary> 7         /// 獲取一個值,該值表示命令綁定的對象。 8         /// </summary> 9         /// <value>The command.</value>10         public Command Command { get; private set; }11 12         /// <summary>13         /// 獲取一個值,該值表示命令執行參數。14         /// </summary>15         /// <value>The command parameter.</value>16         public CommandParameter CommandParameter { get; private set; }17 18         /// <summary>19         /// 初始化 <see cref="CommandBinding"/> 新實例。20         /// </summary>21         /// <param name="command">要綁定的命令。</param>22         public CommandBinding(Command command)23             : this(command, null)24         {25 26         }27 28         /// <summary>29         /// 初始化 <see cref="CommandBinding"/> 新實例。30         /// </summary>31         /// <param name="command">要綁定的命令。</param>32         /// <param name="commandParameter">要綁定的命令參數。</param>33         public CommandBinding(Command command, CommandParameter commandParameter)34         {35             this.Command = command;36             this.CommandParameter = commandParameter;37             if (this.CommandParameter != null)38             {39                 this.CommandParameter.Command = this.Command;40             }41         }42 43         /// <summary>44         /// 初始化 <see cref="CommandBinding"/> 新實例。45         /// </summary>46         /// <param name="command">要綁定的命令。</param>47         /// <param name="source">要綁定的命令參數的實例。</param>48         /// <param name="propertyMember">要綁定的命令參數的屬性名稱。</param>49         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param>50         public CommandBinding(Command command, object source, string propertyMember, bool booleanOppose = false)51             : this(command, CreateCommandParameter(source, propertyMember, booleanOppose))52         {53 54         }55 56         /// <summary>57         /// 初始化 <see cref="CommandBinding"/> 新實例。58         /// </summary>59         /// <param name="command">要綁定的命令。</param>60         /// <param name="staticSourceType">靜態類類型。</param>61         /// <param name="propertyMember">綁定成員(屬性名稱)。</param>62         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param>63         public CommandBinding(Command command, Type staticSourceType, string propertyMember, bool booleanOppose = false)64             : this(command, new CommandParameter(staticSourceType, propertyMember, booleanOppose))65         {66         }67 68         private static CommandParameter CreateCommandParameter(object source, string propertyMember, bool booleanOppose = false)69         {70             return new CommandParameter(source, propertyMember, booleanOppose);71         } 72     }
    CommandBinding 代碼
  4. 命令目標(CommandTarget)

    此為最終執行命令的目標,構建此對象實例時指定一個綁定(CommandBinding),監視WinForm命令控件(如Control、ToolStripItem)等包含 Click 事件和 Enabled 屬性的對象。

      1     /// <summary>  2     /// 表示命令綁定的執行目標。  3     /// </summary>  4     public sealed class CommandTarget : IDisposable  5     {  6         private readonly object target;  7         private bool disposed = false;  8   9         /// <summary> 10         /// 獲取一個值,該值表示目標是否已釋放。 11         /// </summary> 12         /// <value><c>true</c> if disposed; otherwise, <c>false</c>.</value> 13         public bool Disposed { get { return disposed; } } 14  15         /// <summary> 16         /// 獲取一個值,該值表示目標的命令綁定源。 17         /// </summary> 18         /// <value>The command binding.</value> 19         public CommandBinding CommandBinding { get; private set; } 20  21         /// <summary> 22         /// 初始化 CommandTarget 新實例。 23         /// </summary>  24         /// <param name="binding">命令綁定源。</param> 25         private CommandTarget(CommandBinding binding) 26         { 27             CommandBinding = binding; 28             CommandBinding.Command.CanExecuteChanged += CommandStateChanged; 29         } 30  31  32         /// <summary> 33         /// 初始化 CommandTarget 新實例。 34         /// </summary> 35         /// <param name="control">綁定目標。</param> 36         /// <param name="commandBinding">命令綁定源。</param> 37         public CommandTarget(Control control, CommandBinding commandBinding) 38             : this(commandBinding) 39         { 40             target = control; 41             control.Click += OnClick; 42             var parameter = GetParameterValue(); 43             control.Enabled = commandBinding.Command.CanExecute(parameter); 44         } 45  46         /// <summary> 47         /// 初始化 CommandTarget 新實例。 48         /// </summary> 49         /// <param name="item">綁定目標。</param> 50         /// <param name="commandBinding">命令綁定源。</param> 51         public CommandTarget(ToolStripItem item, CommandBinding commandBinding) 52             : this(commandBinding) 53         { 54             target = item; 55             item.Click += OnClick; 56             var parameter = GetParameterValue(); 57             item.Enabled = commandBinding.Command.CanExecute(parameter); 58         } 59  60  61         /// <summary> 62         /// Handles the <see cref="E:Click" /> event. 63         /// </summary> 64         /// <param name="sender">The sender.</param> 65         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> 66         private void OnClick(object sender, EventArgs e) 67         { 68             object parameter = null; 69             if (CommandBinding.CommandParameter != null) 70             { 71                 parameter = CommandBinding.CommandParameter.Parameter; 72             } 73             var command = CommandBinding.Command; 74             if (command.CanExecute(parameter)) 75             { 76                 command.Execute(parameter); 77             } 78         } 79         /// <summary> 80         /// Commands the state changed. 81         /// </summary> 82         /// <param name="sender">The sender.</param> 83         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> 84         private void CommandStateChanged(object sender, EventArgs e) 85         { 86             var property = target.GetType().GetProperty("Enabled"); 87             if (property != null) 88             { 89                 var parameter = GetParameterValue(); 90                 var enable = CommandBinding.Command.CanExecute(parameter); 91                 property.SetValue(target, enable); 92             } 93         } 94  95         private object GetParameterValue() 96         { 97             if (CommandBinding.CommandParameter == null) 98             { 99                 return null;100             }101             return CommandBinding.CommandParameter.Parameter;102         }103 104         /// <summary>105         /// 執行與釋放或重置非托管資源相關的應用程序定義的任務。106         /// </summary>107         public void Dispose()108         {109             if (disposed)110             {111                 return;112             }113             disposed = true;114             CommandBindingManager.Unregister(this);115             CommandBinding.Command.CanExecuteChanged -= CommandStateChanged;116             if (target is Control)117             {118                 ((Control)target).Click -= OnClick;119             }120             if (target is ToolStripItem)121             {122                 ((Control)target).Click -= OnClick;123             }124         } 125     }
    CommandTarget 代碼
  5. 命令綁定管理器(CommandBindingManager)

    命令綁定管理器提供命令綁定(CommandBinding)與命令控件(WinForm控件)注冊與反注冊功能。

      1     /// <summary>  2     /// 表示命令注冊管理器。  3     /// </summary>  4     public static class CommandBindingManager  5     {  6         private static readonly List<CommandTarget> targets = new List<CommandTarget>();  7   8         /// <summary>  9         /// 注冊命令道指定的命令控件。 10         /// </summary> 11         /// <param name="control">綁定目標。</param> 12         /// <param name="commandBinding">命令綁定源。</param> 13         /// <returns>返回一個命令目標實例。</returns> 14         public static CommandTarget Register(Control control, CommandBinding commandBinding) 15         { 16             var target = new CommandTarget(control, commandBinding); 17             targets.Add(target); 18             return target; 19         } 20  21         /// <summary> 22         /// 注冊命令道指定的命令控件。 23         /// </summary> 24         /// <param name="stripItem">綁定目標。</param> 25         /// <param name="commandBinding">命令綁定源。</param> 26         /// <returns>返回一個命令目標實例。</returns> 27         public static CommandTarget Register(ToolStripItem stripItem, CommandBinding commandBinding) 28         { 29             var target = new CommandTarget(stripItem, commandBinding); 30             targets.Add(target); 31             return target; 32         } 33  34         /// <summary> 35         /// 注冊命令道指定的命令控件。 36         /// </summary> 37         /// <param name="control">綁定目標。</param> 38         /// <param name="command">綁定命令。</param> 39         /// <returns>返回一個命令目標實例。</returns> 40         public static CommandTarget Register(Control control, Command command) 41         { 42             return Register(control, new CommandBinding(command)); 43         } 44         /// <summary> 45         /// 注冊命令道指定的命令控件。 46         /// </summary> 47         /// <param name="stripItem">綁定目標。</param> 48         /// <param name="command">綁定命令。</param> 49         /// <returns>返回一個命令目標實例。</returns> 50         public static CommandTarget Register(ToolStripItem stripItem, Command command) 51         { 52             return Register(stripItem, new CommandBinding(command)); 53         } 54  55         /// <summary> 56         /// 注冊命令道指定的命令控件。 57         /// </summary> 58         /// <param name="control">綁定目標。</param> 59         /// <param name="command">綁定命令。</param> 60         /// <param name="source">構造命令參數的源。</param> 61         /// <param name="propertyName">構造命令參數的名稱。</param> 62         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 63         /// <returns>返回一個命令目標實例。</returns> 64         public static CommandTarget Register(Control control, Command command, object source, string propertyName, bool booleanOppose = false) 65         { 66             var commandBinding = new CommandBinding(command, source, propertyName, booleanOppose); 67             return Register(control, commandBinding); 68         } 69  70         /// <summary> 71         /// 注冊命令道指定的命令控件。 72         /// </summary> 73         /// <param name="stripItem">綁定目標。</param> 74         /// <param name="command">綁定命令。</param> 75         /// <param name="source">構造命令參數的源。</param> 76         /// <param name="propertyName">構造命令參數的名稱。</param> 77         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 78         /// <returns>返回一個命令目標實例。</returns> 79         public static CommandTarget Register(ToolStripItem stripItem, Command command, object source, string propertyName, bool booleanOppose = false) 80         { 81             var commandBinding = new CommandBinding(command, source, propertyName, booleanOppose); 82             return Register(stripItem, commandBinding); 83         } 84  85         /// <summary> 86         /// 注冊命令道指定的命令控件。 87         /// </summary> 88         /// <param name="control">綁定目標。</param> 89         /// <param name="command">綁定命令。</param> 90         /// <param name="staticSourceType">靜態類類型。</param> 91         /// <param name="propertyName">構造命令參數的名稱。</param> 92         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 93         /// <returns>返回一個命令目標實例。</returns> 94         public static CommandTarget Register(Control control, Command command, Type staticSourceType, string propertyName, bool booleanOppose = false) 95         { 96             var commandBinding = new CommandBinding(command, staticSourceType, propertyName, booleanOppose); 97             return Register(control, commandBinding); 98         } 99         /// <summary>100         /// 注冊命令道指定的命令控件。101         /// </summary>102         /// <param name="stripItem">綁定目標。</param>103         /// <param name="command">綁定命令。</param>104         /// <param name="staticSourceType">靜態類類型。</param>105         /// <param name="propertyName">構造命令參數的名稱。</param>106         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param>107         /// <returns>返回一個命令目標實例。</returns>108         public static CommandTarget Register(ToolStripItem stripItem, Command command, Type staticSourceType, string propertyName, bool booleanOppose = false)109         {110             var commandBinding = new CommandBinding(command, staticSourceType, propertyName, booleanOppose);111             return Register(stripItem, commandBinding);112         }113          114         /// <summary>115         /// 反注冊命令。116         /// </summary>117         /// <param name="target">注銷的命令目標。</param>118         public static void Unregister(CommandTarget target)119         {120             if (target == null)121             {122                 return;123             }124             if (targets.Contains(target))125             {126                 targets.Remove(target);127                 target.Dispose();128             }129         }130     }
    CommandBindingManager 代碼

     

最后附上委托命令(DegelateCommand)的實現。

 1     /// <summary> 2     /// 表示一個可被執行委托的方法的命令。 3     /// </summary> 4     public sealed class DelegateCommand : Command 5     { 6         private Action<object> execute; 7         private Func<object, bool> canExecute; 8         /// <summary> 9         /// 初始化 <see cref="DelegateCommand"/> 新實例。10         /// </summary>11         /// <param name="execute">當命令被調用時,指定的方法。</param>12         /// <param name="canExecute">當命令被確定是否能執行時,執行的方法。</param>13         public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)14         {15             this.execute = execute;16             this.canExecute = canExecute;17         }18         /// <summary>19         /// 定義用于確定此命令是否可以在其當前狀態下執行的方法。20         /// </summary>21         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>22         /// <returns>如果可以執行此命令,則為 true;否則為 false。</returns>23         public override bool CanExecute(object parameter)24         {25             if (canExecute == null)26             {27                 return true;28             }29             return canExecute(parameter);30         }31 32         /// <summary>33         /// 定義在調用此命令時調用的方法。34         /// </summary>35         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>36         public override void Execute(object parameter)37         {38             if (CanExecute(parameter))39             {40                 execute(parameter);41             }42         }43     } 
DelegateCommand 代碼

 

   補充:不好意思,忘記附上Demo示例,現補上,請前往 百度網盤 下載

 

  本文如有紕漏,歡迎大家批評指正!                                   


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩另类视频| 中文在线不卡视频| 日本久久久久久久久久久| 欧美在线观看一区二区三区| 国产精品免费一区二区三区都可以| 2019中文字幕在线观看| 欧美伦理91i| 日韩av最新在线| 欧美肥臀大乳一区二区免费视频| 午夜精品久久久久久久白皮肤| 国产精品亚洲美女av网站| 青青草成人在线| 成人黄色影片在线| 日韩电视剧免费观看网站| 欧美视频免费在线观看| 午夜精品一区二区三区在线视频| 久久成人精品一区二区三区| 色狠狠久久aa北条麻妃| 日本高清视频一区| 国产福利精品av综合导导航| 国产日韩欧美在线| 亚洲欧洲日韩国产| 亚洲区一区二区| 在线日韩av观看| 久久99国产精品久久久久久久久| 亚洲自拍av在线| 欧美国产第一页| 欧美视频免费在线观看| 亚洲人精品午夜在线观看| 亚洲免费精彩视频| 日韩av大片免费看| 国产日韩欧美在线播放| 亚洲大胆人体视频| 久久亚洲一区二区三区四区五区高| 成人福利视频网| 亚洲欧美国产高清va在线播| 亚洲综合视频1区| 45www国产精品网站| 久久色精品视频| 亚洲视频一区二区三区| 在线观看精品国产视频| 日韩电影中文字幕在线观看| 美女扒开尿口让男人操亚洲视频网站| 欧美黑人性生活视频| 国产欧美一区二区三区久久| 中文字幕免费国产精品| 亚洲精品国产精品自产a区红杏吧| 欧美日韩成人网| 911国产网站尤物在线观看| 久久久久久久一区二区| 亚洲片国产一区一级在线观看| 这里精品视频免费| 在线播放亚洲激情| 97超级碰碰人国产在线观看| 欧美黄网免费在线观看| 国产精品久久久久久久app| 日韩中文在线不卡| 久久亚洲精品成人| 亚洲人午夜精品免费| 国内精品久久久久久久久| 8090成年在线看片午夜| 日韩最新中文字幕电影免费看| 色哟哟网站入口亚洲精品| 国产精品色午夜在线观看| 萌白酱国产一区二区| 日韩欧美成人精品| 欧美精品国产精品日韩精品| 一区二区三区在线播放欧美| 日韩精品中文字幕在线观看| 国产深夜精品福利| 欧美巨乳美女视频| 成人免费网视频| www.日韩系列| 欧美日韩亚洲精品内裤| 91精品91久久久久久| 69国产精品成人在线播放| 免费91在线视频| 亚洲精品久久久久国产| 日韩av在线不卡| 亚洲一区中文字幕在线观看| 日韩电影在线观看永久视频免费网站| 久久久久国色av免费观看性色| 色偷偷亚洲男人天堂| 亚洲人成在线播放| 97成人精品视频在线观看| 69国产精品成人在线播放| 日韩在线观看免费网站| 亚洲电影中文字幕| 午夜精品一区二区三区av| 日韩电影网在线| 国产美女精品视频免费观看| 日韩av免费看网站| 2019中文字幕全在线观看| 中文国产亚洲喷潮| 欧美黑人巨大精品一区二区| 在线激情影院一区| 日本欧美精品在线| 欧美在线国产精品| 中文字幕日韩精品在线观看| 国产欧美一区二区三区久久| 久久久久久有精品国产| 一区二区三区www| 日韩在线欧美在线国产在线| 亚洲国产精品va在线看黑人动漫| 欧美二区乱c黑人| 国产精品久久久久久av福利软件| 欧美成人精品一区二区三区| 亚洲欧美在线看| …久久精品99久久香蕉国产| 中文字幕亚洲情99在线| 欧美日韩国产精品一区二区三区四区| 国内精品模特av私拍在线观看| 色综合久久88| 国产在线精品播放| 久热精品视频在线免费观看| 色yeye香蕉凹凸一区二区av| 97在线日本国产| 国产精品扒开腿做爽爽爽视频| 色妞色视频一区二区三区四区| 国模私拍一区二区三区| 日韩欧美国产视频| 日韩av最新在线观看| 国产伦精品免费视频| **欧美日韩vr在线| 国产精品永久免费在线| 国产性猛交xxxx免费看久久| 欧美精品videosex极品1| 日韩电视剧免费观看网站| 亚洲一区二区在线| 欧美在线视频一区二区| 国产欧美精品一区二区三区介绍| 欧美极品少妇xxxxⅹ裸体艺术| 亚洲国产精品久久91精品| 一区国产精品视频| 一区二区三区美女xx视频| 欧美激情va永久在线播放| 欧美高跟鞋交xxxxhd| 热久久免费视频精品| 7m第一福利500精品视频| 久久亚洲国产精品成人av秋霞| 国产一区二区丝袜| 日本不卡视频在线播放| 国产精品视频自拍| 欧美另类暴力丝袜| 国产精品久久久久9999| 亚洲日韩中文字幕在线播放| 欧美人成在线视频| 成人午夜在线观看| 亚洲国产欧美一区二区三区同亚洲| 欧美激情欧美激情| 亚洲欧美在线一区二区| 久久久人成影片一区二区三区观看| 成人妇女免费播放久久久| 欧美高清性猛交| 夜夜嗨av一区二区三区免费区| 欧美夫妻性生活xx| 欧美国产日韩二区| 亚洲视频在线观看| 国产一区二区香蕉| 日产精品99久久久久久| 日本不卡高字幕在线2019| 日韩电影大片中文字幕| 久久精品国产亚洲一区二区| 日本精品性网站在线观看|