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

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

.net類庫里ListView的一個BUG

2019-11-17 02:45:23
字體:
來源:轉載
供稿:網友
.net類庫里ListView的一個BUG

今天在CSDN論壇里看一個帖子,說是在ListView中添加了條目后第一行內容不顯示,為了還原他的問題我寫了以下代碼。

復制代碼 PRivate void LoadFiles(DirectoryInfo dir) { FileInfo[] files = dir.GetFiles(); foreach (FileInfo file in files) { ListViewItem item = new ListViewItem(); item.Tag = file; item.SubItems.AddRange(SubItems.ToArray()); listView1.Items.Add(item); UpdateItem(item); } } ListViewItem.ListViewSubItem[] SubItems { get { return new ListViewItem.ListViewSubItem[] { new ListViewItem.ListViewSubItem(), new ListViewItem.ListViewSubItem() }; } } private void UpdateItem(ListViewItem item) { FileInfo info = (FileInfo)item.Tag; item.Text = info.Name; item.SubItems[1].Text = info.Length.ToString("N0"); item.SubItems[2].Text = info.LastWriteTime.ToString(); }復制代碼ListView共有3列,分別顯示文件名、大小和最后修改時間,運行以后我發現,文件名可以顯示,但是后面2列不能顯示。經過各種調試和偶遇,終于讓我發現,只要改變ListViewItem.Text的值,后面兩列的內容就能夠顯示了,于是初步解決方案是改變ListViewItem.Text的賦值順序,把它放在所有SubItem.Text賦值以后再賦值。為了找到根本原因,我翻查了.net類庫的源代碼,最后終于發現問題所在,先來看看ListViewSubItem.Text的源代碼。復制代碼 public string Text { get { return text == null ? "" : text; } set { text = value; if (owner != null) { owner.UpdateSubItems(-1); } } }復制代碼在對此屬性賦值時,首先檢查owner字段的值是否為空,如果不為空才調用owner.UpateSubItems方法對ListView進行更新。很明顯,出現上面的問題時,owner值一定為空,通過在VS里調試證實了這點。現在的問題是,為什么這owner會為空,owner的類型是ListViewItem,從字面理解它應該是SubItem所屬的那個行項目,正常情況下在添加到ListViewItem.SubItems以后就應該不會為空,于是我猜是在添加的時候這個owner沒有被賦值。后來通過查看源代碼以后證實了我的想法,來看看ListViewSubItemCollection關于添加子項的源碼。復制代碼 public ListViewSubItem Add(ListViewSubItem item) { EnsureSubItemSpace(1, -1); item.owner = this.owner; owner.subItems[owner.SubItemCount] = item; owner.UpdateSubItems(owner.SubItemCount++); return item; } public void AddRange(ListViewSubItem[] items) { if (items == null) { throw new ArgumentNullException("items"); } EnsureSubItemSpace(items.Length, -1); foreach(ListViewSubItem item in items) { if (item != null) { owner.subItems[owner.SubItemCount++] = item; } } owner.UpdateSubItems(-1); }復制代碼很明顯,Add方法對owner進行了賦值,但AddRange方法沒有,而在帖子里所用的是AddRange方法,所以造成了這個問題。那為什么對Text賦值以后,子項里的內容又能夠顯示了呢?好吧,再來看看ListViewItem.Text的源碼復制代碼 public string Text { get { if (SubItemCount == 0) { return string.Empty; } else { return subItems[0].Text; } } set { SubItems[0].Text = value; } }復制代碼對ListViewItem.Text的賦值實際上就是對它第0個子項的Text賦值,那為什么這個子項可以工作呢,好吧,再來看看第0個子項的來歷,以下是ListViewItem.SubItems的源碼。復制代碼 public ListViewSubItemCollection SubItems { get { if (SubItemCount == 0) { subItems = new ListViewSubItem[1]; subItems[0] = new ListViewSubItem(this, string.Empty); SubItemCount = 1; } if (listViewSubItemCollection == null) { listViewSubItemCollection = new ListViewSubItemCollection(this); } return listViewSubItemCollection; } }復制代碼由于帖子里使用了ListViewItem的無參數構造函數,因此在第一次調用SubItems屬性時,SubItemCount的值為0,這時就會自動插入一個子項,而這里使用的構造函數直接把當前ListViewItem傳進去了,子項的owner就有了值,因此可以正常顯示文字?;叵肭懊娴膶ψ禹桾ext賦值的源碼,在賦值以后會調用owner.UpdateSubItems(-1)來更新顯示,這個方法并不是僅僅更新一個子項,而是會更新所有子項,因此所有的內容又都可以看到了。最后還有一個問題,為什么調用ListView.Refresh或Invalidate方法沒用呢?我沒有做深入研究,只是做一個猜想。因為.net的ListView控件只是對原生Windows的ListView控件的封裝,在OwnerDraw為false時,所有的繪圖都由原生的ListView控件完成。從以上代碼可以看出,子項的文本在托管代碼里保存了一份,而我敢肯定在原生的控件里也保存了一份,當owner存在時,這兩個值是相同的,而在owner不存在時,由于沒有更新導致原生控件里沒有更新而失去了同步,這樣無論怎么Refresh都是沒有用的。Bug就分析到此,原因找到了,解決辦也自然有了。但我想說的不是解決辦法,而是怎么利用這個BUG,再來看看ListViewItem.UpdateSubItems方法。復制代碼 internal void UpdateSubItems(int index){ UpdateSubItems(index, SubItemCount); } internal void UpdateSubItems(int index, int oldCount){ if (listView != null && listView.IsHandleCreated) { int subItemCount = SubItemCount; int itemIndex = Index; if (index != -1) { listView.SetItemText(itemIndex, index, subItems[index].Text); } else { for(int i=0; i < subItemCount; i++) { listView.SetItemText(itemIndex, i, subItems[i].Text); } } for (int i = subItemCount; i < oldCount; i++) { listView.SetItemText(itemIndex, i, string.Empty); } } }復制代碼ListViewSubItem.set_Text在調用此方法時,專入的參數是-1,可以看出這將會導致所有的子項重繪,這點前面說過了。按此計算,如果ListView有10列,那每行需要重繪100次,其中有90次是在做無用功,不但增加了CPU的負擔,還會可能會導致界面閃爍,但如果合理地利用這個BUG,可以有效改善這個情況。==補充======================================================做了一個實地測試,30列200行,做一次所有行和列的刷新,常規方法700ms,而利用這個BUG可以降到25ms。最后做個總結在為ListView添加行項目時,各項目的SubItem如果采用AddRange方法添加,會導致在后續更新SubItem的Text時,界面上不會更改,解決辦法有兩種:1、不要使用ListViewItem.SubItems.AddRange方法,而改用Add。2、仍舊使用AddRange方法,但在更新內容時,第0列(也就是ListViewItem.Text)最后更新。但是這個BUG歪打正著地為提升ListView性能提供了可能,可使用上面的第2個解決辦法實現,在大數量時效果尤其明顯。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲第一精品夜夜躁人人爽| 亚洲精品一区二区三区婷婷月| 国产在线观看91精品一区| 欧美三级欧美成人高清www| 亚洲福利在线播放| 亚洲人成自拍网站| 欧美电影《睫毛膏》| 国产脚交av在线一区二区| 国产精品久久久久免费a∨大胸| 欧美疯狂xxxx大交乱88av| 日韩激情在线视频| 亚洲福利在线看| 日韩av在线免费观看| 亚洲乱码国产乱码精品精| 国产精品老女人视频| 亚洲国产又黄又爽女人高潮的| 日韩在线精品一区| 一本大道亚洲视频| 色综合天天狠天天透天天伊人| 美女999久久久精品视频| 成人午夜一级二级三级| 久久精品久久久久电影| 91视频国产一区| 欧美国产日本高清在线| 国产一区二区美女视频| 91欧美日韩一区| 亚洲天堂av综合网| 久久99精品视频一区97| 热久久这里只有精品| 国产欧美欧洲在线观看| 国产精品久久久久高潮| 中文日韩在线视频| 国产亚洲成精品久久| 人人爽久久涩噜噜噜网站| 欧美超级免费视 在线| 国产偷国产偷亚洲清高网站| 国产精品国产福利国产秒拍| 亚洲第一区中文字幕| 国产在线拍揄自揄视频不卡99| 久久精品99久久香蕉国产色戒| 国产日产久久高清欧美一区| 91爱爱小视频k| 国产精品自产拍在线观看中文| 国产精品久久在线观看| 久久久精品国产| 中文字幕av一区中文字幕天堂| 亚洲香蕉成人av网站在线观看| 久久精品99久久久香蕉| 欧美激情在线狂野欧美精品| 亚洲欧美日本伦理| 色偷偷av一区二区三区| 亚洲精品日产aⅴ| 久久福利视频网| 欧美精品久久久久久久| 欧美精品一本久久男人的天堂| 久久久精品久久| 久久久久久久av| 最新亚洲国产精品| 久久香蕉频线观| 国产成人精品一区二区三区| 日本一本a高清免费不卡| 国产精品视频999| 中文字幕日韩av| 国产精品69久久| 2019日本中文字幕| 欧美精品九九久久| 欧美视频在线免费看| 中文字幕亚洲精品| 免费97视频在线精品国自产拍| 九九热这里只有在线精品视| 中文字幕国产亚洲2019| 国产精品亚洲一区二区三区| 亚洲视屏在线播放| 日韩在线视频二区| 国产成人综合av| 久久97精品久久久久久久不卡| 亚洲自拍偷拍区| 中文字幕亚洲一区在线观看| 一区二区三区精品99久久| 国产偷国产偷亚洲清高网站| 日韩精品视频在线免费观看| 日韩av在线网站| 岛国av一区二区在线在线观看| 国产欧美va欧美va香蕉在线| 欧美日韩美女在线| 日本高清不卡在线| 欧美性猛交xxxx免费看| 精品国产福利在线| 国产一区二区三区在线观看视频| 中文字幕精品www乱入免费视频| 精品国产乱码久久久久久虫虫漫画| 日本不卡免费高清视频| 国产成人精品日本亚洲专区61| 日本欧美中文字幕| 久久久噜噜噜久久| 一道本无吗dⅴd在线播放一区| 欧美日韩国产中字| 97成人精品区在线播放| 国产精品视频99| 国产精品亚洲美女av网站| 国产欧美韩国高清| 亚洲免费视频网站| 中文字幕日韩在线播放| 日韩中文字幕在线播放| 91精品国产乱码久久久久久蜜臀| 日韩亚洲精品电影| 2019国产精品自在线拍国产不卡| 亚洲精品99久久久久| 亚洲成色www8888| 欧美在线性视频| 精品久久久久久久久久久久久久| 97视频在线观看免费| 91亚洲国产成人精品性色| 不卡伊人av在线播放| 成人中文字幕+乱码+中文字幕| 国产美女精品免费电影| 亚洲国产一区二区三区四区| 欧美大片在线影院| 日韩美女在线看| 91精品久久久久久久久中文字幕| 国产精品h在线观看| 狠狠色狠狠色综合日日五| 欧美精品一区三区| 精品网站999www| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲va电影大全| 亚洲精品欧美日韩| 日韩在线一区二区三区免费视频| 91免费视频网站| 久久精品视频导航| 国产成人精品综合久久久| 日韩精品高清在线观看| 午夜精品一区二区三区在线视频| 国模吧一区二区| 国产精品免费网站| 欧美日韩在线视频一区二区| 亚洲mm色国产网站| 国产精品福利网站| 亚洲欧美日韩中文在线制服| 欧美福利视频在线| 在线观看国产精品日韩av| 亚洲91精品在线观看| 日韩精品在线免费观看视频| 精品久久久久人成| 国产日韩专区在线| 成人国产亚洲精品a区天堂华泰| 亚洲国产成人精品电影| 九九久久综合网站| 亚洲国产另类 国产精品国产免费| 97免费视频在线播放| 国产精品自拍偷拍| 久久69精品久久久久久国产越南| 久久夜色精品国产亚洲aⅴ| 久久影院中文字幕| 欧美午夜精品久久久久久浪潮| 久久久亚洲天堂| 久久久综合av| 国产三级精品网站| 久久精品91久久香蕉加勒比| 国产精品日韩欧美大师| 全色精品综合影院| 狠狠久久五月精品中文字幕| 国产在线98福利播放视频| 91av福利视频|