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

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

實現類似“添加擴展程序…”的設計時支持

2019-11-17 03:49:15
字體:
來源:轉載
供稿:網友
  Ajax Control Toolkit這個控件庫內包含一些擴展控件,利用這些擴展控件,可以非常方便的為普通的控件添加Ajax效果,例如,利用AutoCompleteExtender控件,可以為文本框添加自動完成的ajax效果。當然,這并不是本文想討論的內容。

    將Ajax Control Toolkit加入到Visual Studio 2008的工具箱中,并打開一個新的aspx文件,向里面拖入一個TextBox。這時,有趣的事情發生了,在TextBox的SmartTasks面板里,竟然出現了一個“添加擴展程序…”的鏈接!我又試著拖入一個Button,一個Panel,無一例外的,每個控件的SmartTasks面板的底部都出現了“添加擴展程序…”的鏈接。

    最近我正打算把保存、刪除、關閉頁面等功能抽象成動作,每一種動作對應一個自定義的Web控件,將某個動作控件附加到目標控件(例如Button)上面之后,目標控件就擁有了諸如保存、刪除、關閉頁面的功能。如何在WebForm設計器里為一個Button控件方便地附加動作?我想要的正是類似“添加擴展程序…”這樣的效果。

    開發過自定義服務器控件的朋友應該知道,如果想給控件添加SmartTasks,需要重寫ControlDesigner的ActionLists屬性,并實現自己的DesignerActionList。顯然,一個TextBox并不知道AjaxControlToolkit的存在,所以“添加擴展程序…”這么一個DesignerActionMethodItem并不是它加進來的。那么,.net framework是否提供了某種接口,可以讓我們為別的控件“動態的注入”DesignerActionItem呢?

    通過對AjaxControlToolKit.dll的研究,我發現這些擴展控件的Designer并不負責提供“添加擴展程序”這個Action,他們只負責提供相應擴展程序對應的擴展內容,所以只能從Visual studio的webform designer作為入口來研究。用reflector打開Microsoft Visual Studio 9.0/Common7/IDE/Microsoft.Web.Design.Client.dll,找到了IWebSmartTasksPRovider接口,該接口有一個GetDesignerActionLists的方法,這個方法的返回值應該就是SmartTasks面板里顯示的內容了。這個接口有3個實現類,DataFormDesigner、DataFormXslValueOfDesigner、ElementDesigner。從這三個類的命名上可以推斷,ElementDesigner應該是用的最多的實現類了。ElementDesigner的GetDesignerActionLists的方法實現如下:

   1: DesignerActionListCollection IWebSmartTasksProvider.GetDesignerActionLists()
   2: {
   3:     DesignerActionListCollection componentActions = null;
   4:     if (this.Designer != null)
   5:     {
   6:         DesignerActionService service = (DesignerActionService) base.DesignerHost.GetService(typeof(DesignerActionService));
   7:         if (service != null)
   8:         {
   9:             componentActions = service.GetComponentActions(this.Designer.Component);
  10:         }
  11:     }
  12:     if (componentActions == null)
  13:     {
  14:         componentActions = new DesignerActionListCollection();
  15:     }
  16:     return componentActions;
  17: }
  18:  
  19:  
  20:  
  21:  

    從上面代碼里可以看到最終的DesignerActionListCollection是由System.Design程序集下的System.ComponentModel.Design.DesignerActionService類的GetComponentActions決定的,Microsoft.Web.Design.Client.dll下的Microsoft.Web.Design.WebFormDesigner+WebDesignerActionService繼承了該類,他的實現如下:

   1: protected override void GetComponentDesignerActions(IComponent component, DesignerActionListCollection actionLists)
   2: {
   3:     Control control = component as Control;
   4:     ElementDesigner parent = null;
   5:     if (control != null)
   6:     {
   7:         parent = ElementDesigner.GetElementDesigner(control);
   8:     }
   9:     if ((parent == null) || !parent.InTemplateMode)
  10:     {
  11:         base.GetComponentDesignerActions(component, actionLists);
  12:         if ((parent != null) && (parent.Designer != null))
  13:         {
  14:             ControlDesigner designer = parent.Designer as ControlDesigner;
  15:             if ((designer != null) && (designer.AutoFormats.Count > 0))
  16:             {
  17:                 actionLists.Insert(0, new AutoFormatActionList(parent));
  18:             }
  19:         }
  20:         if ((parent != null) && (parent.Element != null))
  21:         {
  22:             IWebDataFormElementCallback dataFormElementCallback = parent.Element.GetDataFormElementCallback();
  23:             if (dataFormElementCallback != null)
  24:             {
  25:                 DataFormElementActionList list = new DataFormElementActionList(parent, parent.Control, dataFormElementCallback);
  26:                 actionLists.Add(list);
  27:                 DataFormElementActionList.ModifyActionListsForListControl(actionLists, list);
  28:             }
  29:         }
  30:         if (((parent != null) && (parent.Designer != null)) && parent.DocumentDesigner.ExtenderControlHelper.ProvidesActionLists)
  31:         {
  32:             parent.DocumentDesigner.ExtenderControlHelper.AddActionLists(parent, actionLists);
  33:         }
  34:     }
  35:     if ((parent != null) && (parent.TemplateEditingUI != null))
  36:     {
  37:         actionLists.Add(new TemplateEditingActionList(parent.TemplateEditingUI, parent.Element));
  38:     }
  39: }
  40:  
  41:  
  42:  
  43:  

    這個方法里,有這么一段:

   1: if (((parent != null) && (parent.Designer != null)) && parent.DocumentDesigner.ExtenderControlHelper.ProvidesActionLists)
   2:        {
   3:            parent.DocumentDesigner.ExtenderControlHelper.AddActionLists(parent, actionLists);
   4:        }


    看來“添加擴展程序”這個action就是在這里加進去的了。繼續查看ExtenderControlHelper.AddActionLists的實現:

   1: public void AddActionLists(ElementDesigner element, DesignerActionListCollection lists)
   2: {
   3:     lists.Add(new ControlExtenderActionList(element));
   4:     ExtenderControl component = element.Designer.Component as ExtenderControl;
   5:     Control control = element.Designer.Component as Control;
   6:     if ((component == null) && (control != null))
   7:     {
   8:         IExtenderInformationService service = (IExtenderInformationService) control.Site.GetService(typeof(IExtenderInformationService));
   9:         if (service != null)
  10:         {
  11:             foreach (Control control3 in service.GetAppliedExtenders(control))
  12:             {
  13:                 lists.Add(new HoistedExtenderActionList(element.Designer, control3));
  14:             }
  15:         }
  16:     }
  17: }
  18:  
  19:  
  20:  
  21:  


    這個方法里的第一句是lists.Add(new ControlExtenderActionList(element)),ControlExtenderActionList繼承了System.ComponentModel.Design.DesignerActionList,他的GetSortedActionItems方法定義如下:

   1: public override DesignerActionItemCollection GetSortedActionItems()
   2: {
   3:     Control component = (Control) this._htmlDesigner.Component;
   4:     DesignerActionItemCollection items = new DesignerActionItemCollection();
   5:     IExtenderInformationService service = (IExtenderInformationService) component.Site.GetService(typeof(IExtenderInformationService));
   6:     string category = SR.GetString(SR.Ids.SmartTasksLabelExtenderSection, CultureInfo.CurrentUICulture);
   7:     if (service.IsControlExtendible(component))
   8:     {
   9:         string displayName = SR.GetString(SR.Ids.SmartTasksAddExtender, CultureInfo.CurrentUICulture);
  10:         items.Add(new DesignerActionMethodItem(this, "AddExtender", displayName, category, true));
  11:     }
  12:     if (service.IsControlExtended(component))
  13:     {
  14:         string str3 = SR.GetString(SR.Ids.SmartTasksRemoveExtender, CultureInfo.CurrentUICulture);
  15:         items.Add(new DesignerActionMethodItem(this, "RemoveExtender", str3, category, true));
  16:     }
  17:     return items;
  18: }
  19:  

    這下清楚了,“添加擴展程序”這個action,是在Visual studio的web form設計器里,寫死進去的,.net framework并沒有提供相應接口來供我們添加類似的action。但是我想要的效果是增加一個“添加動作”的action,所以我不能參考AjaxControlToolkit的方法去實現,應該要尋找別的方法。

    回過頭來,重新查看Microsoft.Web.Design.WebFormDesigner+WebDesignerActionService類的GetComponentActions方法,找到基類System.Web.UI.Design.WebFormsDesignerActionService(在System.Design程序集下)的定義,如下:

   1: protected override void GetComponentDesignerActions(IComponent component, DesignerActionListCollection actionLists)
   2: {
   3:     if (component == null)
   4:     {
   5:         throw new ArgumentNullException("component");
   6:     }
   7:     if (actionLists == null)
   8:     {
   9:         throw new ArgumentNullException("actionLists");
  10:     }
  11:     IServiceContainer site = component.Site as IServiceContainer;
  12:     if (site != null)
  13:     {
  14:         DesignerCommandSet service = (DesignerCommandSet) site.GetService(typeof(DesignerCommandSet));
  15:         if (service != null)
  16:         {
  17:             DesignerActionListCollection lists = service.ActionLists;
  18:             if (lists != null)
  19:             {
  20:                 actionLists.AddRange(lists);
  21:             }
  22:         }
  23:         if ((actionLists.Count == 0) || ((actionLists.Count == 1) && (actionLists[0] is ControlDesigner.ControlDesignerActionList)))
  24:         {
  25:             DesignerVerbCollection verbs = service.Verbs;
  26:             if ((verbs != null) && (verbs.Count != 0))
  27:             {
  28:                 DesignerVerb[] array = new DesignerVerb[verbs.Count];
  29:                 verbs.CopyTo(array, 0);
  30:                 actionLists.Add(new DesignerActionVerbList(array));
  31:             }
  32:         }
  33:     }
  34: }
  35:  
  36:  
  37:  
  38:  

    通過研究上述代碼,可以看到DesignerActionListCollection是由DesignerCommandSet這個service的ActionLists屬性負責返回的,而這個service是從component的Site里面取得的,只要我另外寫一個DesignerCommandSet,并且保證從Site里面取出的DesignerCommandSet是我寫的這個service就可以了。終于找到了切入點,下面是具體做法。

    首先,創建一個類繼承DesignerCommandSet,如下:

   1: public class MyDesignerCommandSet : DesignerCommandSet
   2:     {
   3:         private ComponentDesigner _componentDesigner;
   4:  
   5:         public MyDesignerCommandSet(ComponentDesigner componentDesigner)
   6:         {
   7:             _componentDesigner = componentDesigner;
   8:         }
   9:  
  10:         public override ICollection GetCommands(string name)
  11:         {
  12:             if (name.Equals("ActionLists"))
  13:             {
  14:                 return GetActionLists();
  15:             }
  16:             return base.GetCommands(name);
  17:         }
  18:  
  19:         private DesignerActionListCollection GetActionLists()
  20:         {
  21:             //先取得控件原有的DesignerActionLists
  22:             DesignerActionListCollection lists = _componentDesigner.ActionLists;
  23:             
  24:             //增加“添加動作”這個DesignerActionList
  25:             lists.Add(new ActionList(_componentDesigner));
  26:             return lists;
  27:         }
  28:  
  29:         internal class ActionList : DesignerActionList
  30:         {
  31:             private DesignerActionItemCollection _actions;
  32:  
  33:             public ActionList(IDesigner designer)
  34:                 : base(designer.Component)
  35:             {
  36:             }
  37:             public override DesignerActionItemCollection GetSortedActionItems()
  38:             {
  39:                 if (_actions == null)
  40:                 {
  41:                     const string actionCategory = "Actions";
  42:                     _actions = new DesignerActionItemCollection();
  43:                     _actions.Add(new DesignerActionMethodItem(this, "AddAction", "添加動作...", actionCategory, true));
  44:                 }
  45:                 return _actions;
  46:             }
  47:  
  48:             public void AddAction()
  49:             {
  50:                 //添加動作的邏輯,略
  51:             }
  52:         }
  53:     }


    下一步就是如何使component的Site這個ServiceProvider返回自己的這個service。方法是自己寫一個Site,并使Component的Site變成自己寫的SIte類的對象。

    自己寫的Site類的定義如下:

   1: public class SiteProxy : ISite, IServiceContainer
   2:     {
   3:         private ISite _site;
   4:         private ComponentDesigner _designer;
   5:  
   6:         public SiteProxy(ISite site, ComponentDesigner designer)
   7:         {
   8:             _site = site;
   9:             _designer = designer;
  10:  
  11:         }
  12:  
  13:         #region ISite 成員
  14:  
  15:         public IComponent Component
  16:         {
  17:             get { return _site.Component; }
  18:         }
  19:  
  20:         public System.ComponentModel.IContainer Container
  21:         {
  22:             get { return _site.Container; }
  23:         }
  24:  
  25:         public bool DesignMode
  26:         {
  27:             get { return _site.DesignMode; }
  28:         }
  29:  
  30:         public string Name
  31:         {
  32:             get { return _site.Name; }
  33:             set { _site.Name = value; }
  34:         }
  35:  
  36:         #endregion
  37:  
  38:         #region IServiceProvider 成員
  39:  
  40:         public object GetService(Type serviceType)
  41:         {
  42:             object service = _site.GetService(serviceType);
  43:  
  44:             if (serviceType == typeof(DesignerCommandSet) && !(_designer.Component is ExtenderControl))
  45:             {
  46:                 if (service == null || !(service is MyDesignerCommandSet))
  47:                 {
  48:                     if (service != null)
  49:                     {
  50:                         RemoveService(typeof(DesignerCommandSet));
  51:                     }
  52:                     //返回自己寫的DesignerCommandSet
  53:                     service = new MyDesignerCommandSet(_designer);
  54:                     AddService(typeof(DesignerCommandSet), service);
  55:                 }
  56:             }
  57:             return service;
  58:         }
  59:  
  60:         #endregion
  61:  
  62:         #region IServiceContainer 成員
  63:  
  64:         public void AddService(Type serviceType, ServiceCreatorCallback callback, bool promote)
  65:         {
  66:             (_site as IServiceContainer).AddService(serviceType, callback, promote);
  67:         }
  68:  
  69:         public void AddService(Type serviceType, ServiceCreatorCallback callback)
  70:         {
  71:             (_site as IServiceContainer).AddService(serviceType, callback);
  72:         }
  73:  
  74:         public void AddService(Type serviceType, object serviceInstance, bool promote)
  75:         {
  76:             (_site as IServiceContainer).AddService(serviceType, serviceInstance, promote);
  77:         }
  78:  
  79:         public void AddService(Type serviceType, object serviceInstance)
  80:         {
  81:             (_site as IServiceContainer).AddService(serviceType, serviceInstance);
  82:         }
  83:  
  84:         public void RemoveService(Type serviceType, bool promote)
  85:         {
  86:             (_site as IServiceContainer).RemoveService(serviceType, promote);
  87:         }
  88:  
  89:         public void RemoveService(Type serviceType)
  90:         {
  91:             (_site as IServiceContainer).RemoveService(serviceType);
  92:         }
  93:  
  94:         #endregion
  95:     }


    在這個Site的GetService方法中,判斷要get的service類型,如果是DesignerCommandSet,就返回自己創建的MyDesignerCommandSet。

    下一步是如何使component的Site變成自己寫的SiteProxy。一種方法是新增一種自定義控件,在該控件的ControlDesigner的Initialize方法中改變Container中其他控件的Site,只需要向WebForm中拖入該控件,就可以改變其他控件的Site;另外一種方法是寫一個vs package,在package中捕獲web form designer的相應事件。下面介紹第一種做法:

    新增一個繼承自Control的控件,叫做ActionManager,這個控件不用添加任何功能,只需要為它制作ControlDesigner。它的ControlDesigner類主要代碼如下:

   1: public class ActionManagerDesigner : ControlDesigner
   2:     {
   3:         private IDesignerHost _host;
   4:         private IDictionary<IComponent, ISite> _components;
   5:  
   6:         public override void Initialize(IComponent component)
   7:         {
   8:             base.Initialize(component);
   9:  
  10:             _components = new Dictionary<IComponent, ISite>();
  11:  
  12:             _host = GetService(typeof(IDesignerHost)) as IDesignerHost;
  13:             if (_host != null)
  14:             {
  15:                 //替換已有控件的Site
  16:                 ProcessComponent();
  17:  
  18:                 IComponentChangeService service =
  19:                     _host.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
  20:                 if (service != null)
  21:                 {
  22:                     service.ComponentAdded += ComponentAdded;
  23:                     service.ComponentRemoving += ComponentRemoving;
  24:                 }
  25:             }
  26:         }
  27:  
  28:         #region ProcessComponent
  29:  
  30:         private void ProcessComponent()
  31:         {
  32:             ComponentCollection components = _host.Container.Components;
  33:             foreach (IComponent component in components)
  34:             {
  35:                 if (component is ActionControl)
  36:                     continue;
  37:                 ProcessComponentSite(component);
  38:             }
  39:         }
  40:  
  41:         #endregion
  42:  
  43:         #region 替換Site
  44:  
  45:         /// <summary>
  46:         /// 替換Component原來的Site,換成SiteProxy
  47:         /// </summary>
  48:         private void ProcessComponentSite(IComponent component)
  49:         {
  50:             ComponentDesigner designer = _host.GetDesigner(component) as ComponentDesigner;
  51:             _components[component] = component.Site;
  52:             component.Site = new SiteProxy(component.Site, designer);
  53:         }
  54:  
  55:         /// <summary>
  56:         /// 恢復Component原來的site
  57:         /// </summary>
  58:         /// <param name="component"></param>
  59:         private void RestoreComponentSite(IComponent component)
  60:         {
  61:             if (_components.ContainsKey(component))
  62:             {
  63:                 ISite site = _components[component];
  64:                 component.Site = site;
  65:                 _components.Remove(component);
  66:             }
  67:         }
  68:  
  69:         #endregion
  70:  
  71:         #region on Component Add, remove, change
  72:         
  73:         private void ComponentRemoving(object sender, ComponentEventArgs e)
  74:         {
  75:             if (e.Component is ActionControl)
  76:             {
  77:                 return;
  78:             }
  79:             //在刪除Component的時候,要把他的Site屬性還原回去,否則DesignerHost中還會保留原來的Site,
  80:             //這樣再添加同名的Component的時候,會報“重復的組件名稱”錯誤
  81:             RestoreComponentSite(e.Component);
  82:         }
  83:        
  84:  
  85:         private void ComponentAdded(object sender, ComponentEventArgs e)
  86:         {
  87:             if (e.Component is ActionControl)
  88:             {
  89:                 return;
  90:             }
  91:             ProcessComponentSite(e.Component);
  92:         }
  93:  
  94:         #endregion
  95:  
  96:         #region dispose
  97:  
  98:         protected override void Dispose(bool disposing)
  99:         {
100:             if (_host != null)
101:             {
102:                 IComponentChangeService service =
103:                     _host.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
104:                 if (service != null)
105:                 {
106:                     service.ComponentAdded -= ComponentAdded;
107:                     service.ComponentRemoving -= ComponentRemoving;
108:                 }
109:             }
110:             base.Dispose(disposing);
111:         }
112:  
113:         #endregion
114:     }

   至此,只要把一個ActionManager控件拖入到web form designer中,就可以在其他控件的smart task面板上看到“添加動作…”這個鏈接了。但是這種方式需要在webform designer中放入額外的一個控件,該控件只在設計時有用,在運行時則無用,看起來比較奇怪,所以最好的做法是第二種做法,即開發一個vs package,在package的Initialize方法中,注冊IDesignerEventService的DesignerCreated事件,進而通過IDesignerHost和IComponentChangeService達到更改控件Site的目的,具體實現和上面差不多,就不再寫了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本久久久久久久久| 丝袜亚洲另类欧美重口| 97免费视频在线播放| 欧美性20hd另类| 成人网页在线免费观看| 九九热这里只有精品6| 91在线播放国产| 91精品视频专区| 亚洲精品成人av| 国产97在线视频| 国产精品自在线| 亚洲精品国产拍免费91在线| 欧洲美女免费图片一区| 亚洲欧美日韩区| 久久久久久有精品国产| 日日狠狠久久偷偷四色综合免费| 亚洲激情小视频| 欧美高清视频一区二区| 国产婷婷成人久久av免费高清| 91国偷自产一区二区三区的观看方式| 色伦专区97中文字幕| 国产精品视频在线观看| 日韩毛片中文字幕| 97超级碰碰碰久久久| 亚洲黄页视频免费观看| 亚洲а∨天堂久久精品9966| 国产精品免费一区二区三区都可以| 欧美亚洲成人xxx| 91亚洲精品视频| 欧美性生交大片免费| 日韩女优人人人人射在线视频| 国产大片精品免费永久看nba| 在线观看精品国产视频| 亚洲欧美综合v| 亚洲激情在线视频| 91啪国产在线| 国产精品v片在线观看不卡| 国产精品露脸av在线| 欧美一区二区三区……| 亚洲福利视频免费观看| 国产精品亚洲激情| 国产精品成人av性教育| 亚洲精品久久久久中文字幕欢迎你| 成人网中文字幕| 久久成人精品一区二区三区| 国产成人精品999| 欧美多人爱爱视频网站| 欧美日韩一二三四五区| 亚洲欧洲视频在线| 亚洲丁香久久久| 中文字幕免费国产精品| 亚洲色图50p| 亚洲成年人在线| 欧美精品videosex性欧美| 久热精品视频在线观看| 91色琪琪电影亚洲精品久久| 久久成人一区二区| 欧美另类老女人| 亚洲人a成www在线影院| 欧美一区二区大胆人体摄影专业网站| 国产不卡av在线免费观看| 日韩毛片在线观看| 日本国产精品视频| 国产精品久久久久久久久久久新郎| 日韩av黄色在线观看| 亚洲天堂久久av| 欧美成人精品在线播放| 国语自产精品视频在免费| 高清一区二区三区四区五区| 国产亚洲欧美日韩精品| 国语自产精品视频在线看抢先版图片| 国产精品一区二区三区久久久| 国产一区二区三区久久精品| 午夜欧美不卡精品aaaaa| 久久成人精品一区二区三区| 91国产在线精品| 欧美视频在线视频| 91欧美视频网站| 亚洲图片欧美日产| 精品色蜜蜜精品视频在线观看| 国产精品美女www爽爽爽视频| 久久99精品视频一区97| 怡红院精品视频| 久久久久久久97| 亚洲国产精品久久精品怡红院| 亚洲男人天堂2024| 5278欧美一区二区三区| 成人久久精品视频| 国产在线精品成人一区二区三区| 91香蕉亚洲精品| 成人午夜两性视频| 亚洲精品日韩丝袜精品| 欧美综合在线观看| 欧美亚洲国产视频| 国产美女精品视频免费观看| 高清欧美电影在线| 在线看日韩av| 美女福利视频一区| 亚洲级视频在线观看免费1级| 欧美日韩一区二区在线播放| 亚洲精选一区二区| 北条麻妃99精品青青久久| 日韩av在线直播| 91成人天堂久久成人| 欧美日韩人人澡狠狠躁视频| 国内精久久久久久久久久人| 精品国产一区二区在线| 欧美成人黑人xx视频免费观看| 欧美精品第一页在线播放| 亚洲成人动漫在线播放| zzjj国产精品一区二区| 国产日产久久高清欧美一区| 成人福利网站在线观看| 国产精品尤物福利片在线观看| 久久免费精品视频| 日韩中文字幕在线视频| 亚洲国产精品久久久| 92版电视剧仙鹤神针在线观看| 久久精品国产欧美激情| 国产精品国产亚洲伊人久久| 大量国产精品视频| 青青a在线精品免费观看| 久久久999成人| 久久天天躁狠狠躁夜夜躁| 一个人看的www欧美| 欧美一性一乱一交一视频| 精品久久久久久久久久久久久| 亚洲二区在线播放视频| 蜜臀久久99精品久久久无需会员| 国产精品海角社区在线观看| 国产日韩精品在线播放| 国产成人精品一区二区三区| 97精品视频在线播放| 国产精品av免费在线观看| 久热爱精品视频线路一| 4388成人网| 国产日韩精品视频| 国产精品1234| 久久免费少妇高潮久久精品99| 亚洲电影免费观看高清完整版在线| 欧美色videos| 欧美色xxxx| 九九综合九九综合| 欧美在线视频在线播放完整版免费观看| 日日摸夜夜添一区| 亚洲成人精品视频在线观看| 久久国产精品久久久久久久久久| 欧美色另类天堂2015| 亚洲欧美综合v| 福利二区91精品bt7086| 97在线视频免费播放| 国产精品视频网址| 成人午夜高潮视频| 亚洲香蕉成人av网站在线观看| 久久天堂av综合合色| 亚洲综合在线中文字幕| 91精品国产电影| 亚洲片在线观看| 精品在线小视频| 欧美午夜精品在线| 一区二区三区高清国产| 久久久精品影院| 91在线视频成人| 久久久国产精品x99av|