<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        DataGridView多維表頭的實(shí)現(xiàn)方法

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:41:17
        文檔

        DataGridView多維表頭的實(shí)現(xiàn)方法

        DataGridView多維表頭的實(shí)現(xiàn)方法:背景 對于.NET 原本提供的DataGridView控件,制作成如下形式的表格是毫無壓力的。 但是如果把表格改了一下,變成如下形式 傳統(tǒng)的DataGridView就做不到了,如果擴(kuò)展一下還是行的,有不少網(wǎng)友也擴(kuò)展了DataGridView控件,不過有些也只能制作出二維的表頭。或者
        推薦度:
        導(dǎo)讀DataGridView多維表頭的實(shí)現(xiàn)方法:背景 對于.NET 原本提供的DataGridView控件,制作成如下形式的表格是毫無壓力的。 但是如果把表格改了一下,變成如下形式 傳統(tǒng)的DataGridView就做不到了,如果擴(kuò)展一下還是行的,有不少網(wǎng)友也擴(kuò)展了DataGridView控件,不過有些也只能制作出二維的表頭。或者

        背景

        對于.NET 原本提供的DataGridView控件,制作成如下形式的表格是毫無壓力的。

        但是如果把表格改了一下,變成如下形式

        傳統(tǒng)的DataGridView就做不到了,如果擴(kuò)展一下還是行的,有不少網(wǎng)友也擴(kuò)展了DataGridView控件,不過有些也只能制作出二維的表頭。或者使用第三方的控件,之前也用過DevExpress的BoundGridView。不過在沒有可使用的第三方控件的情況下,做到下面的效果,就有點(diǎn)麻煩了。

        那得自己擴(kuò)展了,不過最后還是用了一個(gè)控件庫的報(bào)表控件,Telerik的Reporting。不過我自己還是擴(kuò)展了DataGridView,使之能制作出上面的報(bào)表。

        準(zhǔn)備

        學(xué)習(xí)了一些網(wǎng)友的代碼,原來制作這個(gè)多維表頭都是利用GDI+對DataGirdView的表頭進(jìn)行重繪。

        用到的方法包括

        Graphics.FillRectangle //填充一個(gè)矩形

        Graphics.DrawLine //畫一條線

        Graphics.DrawString  //寫字符串

        此外為了方便組織表頭,本人還定義了一個(gè)表頭的數(shù)據(jù)結(jié)構(gòu) HeaderItem 和 HeaderCollection 分別作為每個(gè)表頭單元格的數(shù)據(jù)實(shí)體和整個(gè)表頭的集合。

        HeaderItem的定義如下

        代碼如下:
        public class HeaderItem
             {
                 private int _startX;//起始橫坐標(biāo)
                 private int _startY;//起始縱坐標(biāo)
                 private int _endX; //終止橫坐標(biāo)
                 private int _endY; //終止縱坐標(biāo)
                 private bool _baseHeader; //是否基礎(chǔ)表頭

                 public HeaderItem(int startX, int endX, int startY, int endY, string content)
                 {
                     this._endX = endX;
                     this._endY = endY;
                     this._startX = startX;
                     this._startY = startY;
                     this.Content = content;
                 }

                 public HeaderItem(int x, int y, string content):this(x,x,y,y,content)
                 {

                 }

                 public HeaderItem()
                 {

                 }

                 public static HeaderItem CreateBaseHeader(int x,int y,string content)
                 {
                     HeaderItem header = new HeaderItem();
                     header._endX= header._startX = x;
                     header._endY= header._startY = y;
                     header._baseHeader = true;
                     header.Content = content;
                     return header;
                 }

                 public int StartX
                 {
                     get { return _startX; }
                     set
                     {
                         if (value > _endX)
                         {
                             _startX = _endX;
                             return;
                         }
                         if (value < 0) _startX = 0;
                         else _startX = value;
                     }
                 }

                 public int StartY
                 {
                     get { return _startY; }
                     set
                     {
                         if (_baseHeader)
                         {
                             _startY = 0;
                             return;
                         }
                         if (value > _endY)
                         {
                             _startY = _endY;
                             return;
                         }
                         if (value < 0) _startY = 0;
                         else _startY = value;
                     }
                 }

                 public int EndX
                 {
                     get { return _endX; }
                     set
                     {
                         if (_baseHeader)
                         {
                             _endX = _startX;
                             return;
                         }
                         if (value < _startX)
                         {
                             _endX = _startX;
                             return;
                         }
                         _endX = value;
                     }
                 }

                 public int EndY
                 {
                     get { return _endY; }
                     set
                     {
                         if (value < _startY)
                         {
                             _endY = _startY;
                             return;
                         }
                         _endY = value;
                     }
                 }

                 public bool IsBaseHeader
                 {get{ return _baseHeader;} }

                 public string Content { get; set; }
             }

        設(shè)計(jì)思想是利用數(shù)學(xué)的直角坐標(biāo)系,給每個(gè)表頭單元格定位并劃定其大小。與計(jì)算機(jī)顯示的坐標(biāo)定位不同,這里的原點(diǎn)是跟數(shù)學(xué)的一樣放在左下角,X軸正方向是水平向右,Y軸正方向是垂直向上。如下圖所示

        之所以要對GridView中原始的列頭進(jìn)行特別處理,是因?yàn)檫@里的起止坐標(biāo)和終止坐標(biāo)都可以設(shè)置,而原始列頭的起始縱坐標(biāo)(StartY)只能是0,終止橫坐標(biāo)(EndX)必須與起始橫坐標(biāo)(StartY)相等。

        另外所有列頭單元格的集合HeaderCollection的定義如下
        代碼如下:
        public class HeaderCollection
             {
                 private List<HeaderItem> _headerList;
                 private bool _iniLock;

                 public DataGridViewColumnCollection BindCollection{get;set;}

                 public HeaderCollection(DataGridViewColumnCollection cols)
                 {
                     _headerList = new List<HeaderItem>();
                     BindCollection=cols;
                     _iniLock = false;
                 }

                 public int GetHeaderLevels()
                 {
                     int max = 0;
                     foreach (HeaderItem item in _headerList)
                         if (item.EndY > max)
                             max = item.EndY;

                     return max;
                 }

                 public List<HeaderItem> GetBaseHeaders()
                 {
                     List<HeaderItem> list = new List<HeaderItem>();
                     foreach (HeaderItem item in _headerList)
                         if (item.IsBaseHeader) list.Add(item);
                     return list;
                 }

                 public HeaderItem GetHeaderByLocation(int x, int y)
                 {
                     if (!_iniLock) InitHeader();
                     HeaderItem result=null;
                     List<HeaderItem> temp = new List<HeaderItem>();
                     foreach (HeaderItem item in _headerList)
                         if (item.StartX <= x && item.EndX >= x)
                             temp.Add(item);
                     foreach (HeaderItem item in temp)
                         if (item.StartY <= y && item.EndY >= y)
                             result = item;

                     return result;
                 }

                 public IEnumerator GetHeaderEnumer()
                 {
                     return _headerList.GetEnumerator();
                 }

                 public void AddHeader(HeaderItem header)
                 {
                     this._headerList.Add(header);
                 }

                 public void AddHeader(int startX, int endX, int startY, int endY, string content)
                 {
                     this._headerList.Add(new HeaderItem(startX,endX,startY,endY,content));
                 }

                 public void AddHeader(int x, int y, string content)
                 {
                     this._headerList.Add(new HeaderItem(x, y, content));
                 }

                 public void RemoveHeader(HeaderItem header)
                 {
                     this._headerList.Remove(header);
                 }

                 public void RemoveHeader(int x, int y)
                 {
                    HeaderItem header= GetHeaderByLocation(x, y);
                    if (header != null) RemoveHeader(header);
                 }

                 private void InitHeader()
                 {
                     _iniLock = true;
                     for (int i = 0; i < this.BindCollection.Count; i++)
                         if(this.GetHeaderByLocation(i,0)==null)
                         this._headerList.Add(HeaderItem.CreateBaseHeader(i,0 , this.BindCollection[i].HeaderText));
                     _iniLock = false;
                 }
             }

        這里仿照了.NET Frameword的Collection那樣定義了Add方法和Remove方法,此外說明一下那個(gè) GetHeaderByLocation 方法,這個(gè)方法可以通過給定的坐標(biāo)獲取那個(gè)坐標(biāo)的HeaderItem。這個(gè)坐標(biāo)是忽略了整個(gè)表頭合并單元格的情況,例如

        上面這幅圖,如果輸入0,0 返回的是灰色區(qū)域,輸入2,1 或3,2 或 5,1返回的都是橙色的區(qū)域。

        擴(kuò)展控件

        到真正擴(kuò)展控件了,最核心的是重寫 OnCellPainting 方法,這個(gè)其實(shí)是與表格單元格重繪時(shí)觸發(fā)事件綁定的方法,通過參數(shù) DataGridViewCellPaintingEventArgs 的 ColumnIndex 和 RowIndex 屬性可以知道當(dāng)前重繪的是哪個(gè)單元格,于是就通過HeaderCollection獲取要繪制的表頭單元格的信息進(jìn)行重繪,對已經(jīng)重繪的單元格會進(jìn)行標(biāo)記,以防重復(fù)繪制。
        代碼如下:
        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
                 {
                     if (e.ColumnIndex == -1 || e.RowIndex != -1)
                     {
                         base.OnCellPainting(e);
                         return;
                     }
                     int lev=this.Headers.GetHeaderLevels();
                     this.ColumnHeadersHeight = (lev + 1) * _baseColumnHeadHeight;
                     for (int i = 0; i <= lev; i++)
                     {
                         HeaderItem tempHeader= this.Headers.GetHeaderByLocation(e.ColumnIndex, i);
                         if (tempHeader==null|| i != tempHeader.EndY || e.ColumnIndex != tempHeader.StartX) continue;
                         DrawHeader(tempHeader, e);
                     }
                     e.Handled = true;
                 }

        上面的代碼中,最初是先判斷當(dāng)前要重繪的單元格是不是表頭部分,如果不是則調(diào)用原本的OnCellPainting方法。 e.Handled=true; 比較關(guān)鍵,有了這句代碼,重繪才能生效。

        繪制單元格的過程封裝在方法DrawHeader里面

        代碼如下:
        private void DrawHeader(HeaderItem item,DataGridViewCellPaintingEventArgs e)
                 {
                     if (this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.DisableResizing)
                         this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
                     int lev=this.Headers.GetHeaderLevels();
                     lev=(lev-item.EndY)*_baseColumnHeadHeight;

                     SolidBrush backgroundBrush = new SolidBrush(e.CellStyle.BackColor);
                     SolidBrush lineBrush = new SolidBrush(this.GridColor);
                     Pen linePen = new Pen(lineBrush);
                     StringFormat foramt = new StringFormat();
                     foramt.Alignment = StringAlignment.Center;
                     foramt.LineAlignment = StringAlignment.Center;

                     Rectangle headRec = new Rectangle(e.CellBounds.Left, lev, ComputeWidth(item.StartX, item.EndX)-1, ComputeHeight(item.StartY, item.EndY)-1);
                     e.Graphics.FillRectangle(backgroundBrush, headRec);
                     e.Graphics.DrawLine(linePen, headRec.Left, headRec.Bottom, headRec.Right, headRec.Bottom);
                     e.Graphics.DrawLine(linePen, headRec.Right, headRec.Top, headRec.Right, headRec.Bottom);
                     e.Graphics.DrawString(item.Content, this.ColumnHeadersDefaultCellStyle.Font, Brushes.Black,headRec, foramt);
                 }

        填充矩形時(shí),記得要給矩形的常和寬減去一個(gè)像素,這樣才不會與相鄰的矩形重疊區(qū)域?qū)е戮匦蔚倪吘€顯示不出來。還有這里的要設(shè)置 ColumnHeadersHeightSizeMode 屬性,如果不把它設(shè)成 DisableResizing ,那么表頭的高度是改變不了的,這樣即使設(shè)置了二維,三維,n維,最終只是一維。

        這里用到的一些輔助方法如下,分別是通過坐標(biāo)計(jì)算出高度和寬度。

        代碼如下:
        private int ComputeWidth(int startX, int endX)
                 {
                     int width = 0;
                     for (int i = startX; i <= endX; i++)
                         width+= this.Columns[i].Width;
                     return width;
                 }

                 private int ComputeHeight(int startY, int endY)
                 {
                     return _baseColumnHeadHeight * (endY - startY+1);
                 }

        給一段使用的實(shí)例代碼,這里要預(yù)先給DataGridView每一列設(shè)好綁定的字段,否則自動(dòng)添加的列是做不出效果來的。

        代碼如下:
        HeaderItem item= this.boundGridView1.Headers.GetHeaderByLocation(0, 0);
                     item.EndY = 2;
                     item = this.boundGridView1.Headers.GetHeaderByLocation(9,0 );
                     item.EndY = 2;
                     item = this.boundGridView1.Headers.GetHeaderByLocation(10, 0);
                     item.EndY = 2;
                     item = this.boundGridView1.Headers.GetHeaderByLocation(11, 0);
                     item.EndY = 2;

                     this.boundGridView1.Headers.AddHeader(1, 2, 1, 1, "語文");
                     this.boundGridView1.Headers.AddHeader(3, 4, 1, 1, "數(shù)學(xué)");
                     this.boundGridView1.Headers.AddHeader(5, 6, 1, 1, "英語");
                     this.boundGridView1.Headers.AddHeader(7, 8, 1, 1, "X科");
                     this.boundGridView1.Headers.AddHeader(1, 8, 2, 2, "成績");

        效果圖如下所示

         

        總的來說自我感覺有點(diǎn)小題大做,但想不出有什么更好的辦法,各位如果覺得以上說的有什么不好的,歡迎拍磚;如果發(fā)現(xiàn)以上有什么說錯(cuò)了,懇請批評指正;如果覺得好的,請支持一下。謝謝!最后附上整個(gè)控件的源碼
        控件的完整代碼
        代碼如下:

             public class BoundGridView : DataGridView
             {
                 private int _baseColumnHeadHeight;

                 public BoundGridView():base()
                 {
                     this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
                     _baseColumnHeadHeight = this.ColumnHeadersHeight;
                     this.Headers = new HeaderCollection(this.Columns);
                 }

                 public HeaderCollection Headers{ get;private set; }

                 protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
                 {
                     if (e.ColumnIndex == -1 || e.RowIndex != -1)
                     {
                         base.OnCellPainting(e);
                         return;
                     }
                     int lev=this.Headers.GetHeaderLevels();
                     this.ColumnHeadersHeight = (lev + 1) * _baseColumnHeadHeight;
                     for (int i = 0; i <= lev; i++)
                     {
                         HeaderItem tempHeader= this.Headers.GetHeaderByLocation(e.ColumnIndex, i);
                         if (tempHeader==null|| i != tempHeader.EndY || e.ColumnIndex != tempHeader.StartX) continue;
                         DrawHeader(tempHeader, e);
                     }
                     e.Handled = true;
                 }

                 private int ComputeWidth(int startX, int endX)
                 {
                     int width = 0;
                     for (int i = startX; i <= endX; i++)
                         width+= this.Columns[i].Width;
                     return width;
                 }

                 private int ComputeHeight(int startY, int endY)
                 {
                     return _baseColumnHeadHeight * (endY - startY+1);
                 }

                 private void DrawHeader(HeaderItem item,DataGridViewCellPaintingEventArgs e)
                 {
                     if (this.ColumnHeadersHeightSizeMode != DataGridViewColumnHeadersHeightSizeMode.DisableResizing)
                         this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
                     int lev=this.Headers.GetHeaderLevels();
                     lev=(lev-item.EndY)*_baseColumnHeadHeight;

                     SolidBrush backgroundBrush = new SolidBrush(e.CellStyle.BackColor);
                     SolidBrush lineBrush = new SolidBrush(this.GridColor);
                     Pen linePen = new Pen(lineBrush);
                     StringFormat foramt = new StringFormat();
                     foramt.Alignment = StringAlignment.Center;
                     foramt.LineAlignment = StringAlignment.Center;

                     Rectangle headRec = new Rectangle(e.CellBounds.Left, lev, ComputeWidth(item.StartX, item.EndX)-1, ComputeHeight(item.StartY, item.EndY)-1);
                     e.Graphics.FillRectangle(backgroundBrush, headRec);
                     e.Graphics.DrawLine(linePen, headRec.Left, headRec.Bottom, headRec.Right, headRec.Bottom);
                     e.Graphics.DrawLine(linePen, headRec.Right, headRec.Top, headRec.Right, headRec.Bottom);
                     e.Graphics.DrawString(item.Content, this.ColumnHeadersDefaultCellStyle.Font, Brushes.Black,headRec, foramt);
                 }
             }

             public class HeaderItem
             {
                 private int _startX;
                 private int _startY;
                 private int _endX;
                 private int _endY;
                 private bool _baseHeader;

                 public HeaderItem(int startX, int endX, int startY, int endY, string content)
                 {
                     this._endX = endX;
                     this._endY = endY;
                     this._startX = startX;
                     this._startY = startY;
                     this.Content = content;
                 }

                 public HeaderItem(int x, int y, string content):this(x,x,y,y,content)
                 {

                 }

                 public HeaderItem()
                 {

                 }

                 public static HeaderItem CreateBaseHeader(int x,int y,string content)
                 {
                     HeaderItem header = new HeaderItem();
                     header._endX= header._startX = x;
                     header._endY= header._startY = y;
                     header._baseHeader = true;
                     header.Content = content;
                     return header;
                 }

                 public int StartX
                 {
                     get { return _startX; }
                     set
                     {
                         if (value > _endX)
                         {
                             _startX = _endX;
                             return;
                         }
                         if (value < 0) _startX = 0;
                         else _startX = value;
                     }
                 }

                 public int StartY
                 {
                     get { return _startY; }
                     set
                     {
                         if (_baseHeader)
                         {
                             _startY = 0;
                             return;
                         }
                         if (value > _endY)
                         {
                             _startY = _endY;
                             return;
                         }
                         if (value < 0) _startY = 0;
                         else _startY = value;
                     }
                 }

                 public int EndX
                 {
                     get { return _endX; }
                     set
                     {
                         if (_baseHeader)
                         {
                             _endX = _startX;
                             return;
                         }
                         if (value < _startX)
                         {
                             _endX = _startX;
                             return;
                         }
                         _endX = value;
                     }
                 }

                 public int EndY
                 {
                     get { return _endY; }
                     set
                     {
                         if (value < _startY)
                         {
                             _endY = _startY;
                             return;
                         }
                         _endY = value;
                     }
                 }

                 public bool IsBaseHeader
                 {get{ return _baseHeader;} }

                 public string Content { get; set; }
             }

             public class HeaderCollection
             {
                 private List<HeaderItem> _headerList;
                 private bool _iniLock;

                 public DataGridViewColumnCollection BindCollection{get;set;}

                 public HeaderCollection(DataGridViewColumnCollection cols)
                 {
                     _headerList = new List<HeaderItem>();
                     BindCollection=cols;
                     _iniLock = false;
                 }

                 public int GetHeaderLevels()
                 {
                     int max = 0;
                     foreach (HeaderItem item in _headerList)
                         if (item.EndY > max)
                             max = item.EndY;

                     return max;
                 }

                 public List<HeaderItem> GetBaseHeaders()
                 {
                     List<HeaderItem> list = new List<HeaderItem>();
                     foreach (HeaderItem item in _headerList)
                         if (item.IsBaseHeader) list.Add(item);
                     return list;
                 }

                 public HeaderItem GetHeaderByLocation(int x, int y)
                 {
                     if (!_iniLock) InitHeader();
                     HeaderItem result=null;
                     List<HeaderItem> temp = new List<HeaderItem>();
                     foreach (HeaderItem item in _headerList)
                         if (item.StartX <= x && item.EndX >= x)
                             temp.Add(item);
                     foreach (HeaderItem item in temp)
                         if (item.StartY <= y && item.EndY >= y)
                             result = item;

                     return result;
                 }

                 public IEnumerator GetHeaderEnumer()
                 {
                     return _headerList.GetEnumerator();
                 }

                 public void AddHeader(HeaderItem header)
                 {
                     this._headerList.Add(header);
                 }

                 public void AddHeader(int startX, int endX, int startY, int endY, string content)
                 {
                     this._headerList.Add(new HeaderItem(startX,endX,startY,endY,content));
                 }

                 public void AddHeader(int x, int y, string content)
                 {
                     this._headerList.Add(new HeaderItem(x, y, content));
                 }

                 public void RemoveHeader(HeaderItem header)
                 {
                     this._headerList.Remove(header);
                 }

                 public void RemoveHeader(int x, int y)
                 {
                    HeaderItem header= GetHeaderByLocation(x, y);
                    if (header != null) RemoveHeader(header);
                 }

                 private void InitHeader()
                 {
                     _iniLock = true;
                     for (int i = 0; i < this.BindCollection.Count; i++)
                         if(this.GetHeaderByLocation(i,0)==null)
                         this._headerList.Add(HeaderItem.CreateBaseHeader(i,0 , this.BindCollection[i].HeaderText));
                     _iniLock = false;
                 }
             }

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        DataGridView多維表頭的實(shí)現(xiàn)方法

        DataGridView多維表頭的實(shí)現(xiàn)方法:背景 對于.NET 原本提供的DataGridView控件,制作成如下形式的表格是毫無壓力的。 但是如果把表格改了一下,變成如下形式 傳統(tǒng)的DataGridView就做不到了,如果擴(kuò)展一下還是行的,有不少網(wǎng)友也擴(kuò)展了DataGridView控件,不過有些也只能制作出二維的表頭。或者
        推薦度:
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 91亚洲国产成人精品下载| 老司机午夜在线视频免费| 亚洲乱码av中文一区二区| 免费无码婬片aaa直播表情| 成年女人色毛片免费看| 亚洲午夜久久久久久久久久| 久久精品国产亚洲av品善| 69堂人成无码免费视频果冻传媒| 久久亚洲国产精品一区二区| 永久免费无码网站在线观看个| 免费黄色大片网站| 亚洲电影唐人社一区二区| 国产午夜精品久久久久免费视| 国产男女猛烈无遮挡免费视频网站| 亚洲乱码一二三四区乱码| 最近中文字幕2019高清免费| 亚洲va久久久噜噜噜久久狠狠 | 国产精品久久亚洲不卡动漫| 亚洲精品成a人在线观看| 香港经典a毛片免费观看看| 亚洲精品视频在线观看视频| 亚洲伦乱亚洲h视频| 女人18毛片a级毛片免费| 亚洲AV成人无码网天堂| 免费一级黄色毛片| av片在线观看永久免费| 亚洲精品一级无码中文字幕| 69式国产真人免费视频| 毛片免费在线观看| 特级做a爰片毛片免费看| 亚洲小说图区综合在线| 亚洲福利精品电影在线观看| 岛国精品一区免费视频在线观看| 亚洲一区AV无码少妇电影☆| 国产精品国产午夜免费福利看 | mm1313亚洲国产精品无码试看| 亚洲综合色丁香麻豆| 久久青草亚洲AV无码麻豆| 亚洲国产精品不卡毛片a在线| 免费高清资源黄网站在线观看| 四虎免费影院ww4164h|