C#中使用ListView的问题

super_admi 2014-10-30 05:45:12
最近做一个界面,使用的是System.Windows.Forms.ListView来显示文件。所有库都是基于.net 2.0
ListView.View使用明细表(即详细信息)
添加item:


foreach (FileInfo file in files)
{
ListViewItem item = new ListViewItem();
item.Tag = file;
item.SubItems.AddRange(SubItems.ToArray());
doRefreshingItem(item);
cSourceFiles.Items.Add(item);
}

这段代码是正常的。

但如果这样做:

foreach (FileInfo file in files)
{
ListViewItem item = new ListViewItem();
item.Tag = file;
item.SubItems.AddRange(SubItems.ToArray());

cSourceFiles.Items.Add(item);
doRefreshingItem(item);
}

问题就出来了:第一行数据无法更新,其它行都是正常的。

虽然创建ITEM的时候,按第一种写法,可以正常实现。但在后面可能会有更新操作,即可能会有类似第二种写法的执行过程,那么第一行数据,就始终得不到更新了……
请问,这个东西,如何解决?谢谢。
...全文
405 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ppi_2859662359 2014-11-03
  • 打赏
  • 举报
回复
ListView无刷新呈现图片示例 //ListView设置 <asp:ListView ID="lvPhoto" runat="server" GroupItemCount="4" DataKeyNames="ID" > <LayoutTemplate> <div ID="divPhoto" runat="server" align="center" style="width:650px; height:0px; margin:8px 0px 2px 10px; padding:8px 0px 2px 10px; text-align:center"> <div ID="groupPlaceholder" runat="server"> </div> </div> </LayoutTemplate> <GroupTemplate> <div ID="tr" style="width:100%;text-align:center"> <div ID="itemPlaceholder" runat="server"> </div> </div> <div ID="div1" style="height:5px"></div> <div ID="div2" style="height:20px; line-height:20px;"></div> </GroupTemplate> <ItemTemplate> <div style="width:158px;float:left"> <div style="width:155px; height:119px; background-image:url(images/001_07.gif);"> <div style="width:100%; height:10px; line-height:10px;"></div> <asp:LinkButton ID="lkbImg" runat="server" CommandArgument='<%# Eval("Url")%>' CommandName='<%# Eval("Descript")%>' oncommand="lkbImg_Command"> <img src='UpSmall/<%# Eval("Url")%>' alt='<%# Eval("Descript")%>' style="border-width:0px" width="133px" height="100px"/> </asp:LinkButton> </div> <div align="center" style="width:100%"> <%# Eval("Title")%> <br /> </div> </div> </ItemTemplate> </asp:ListView> //绑定数据显示 //绑定数据到ListView private void BindListView() { if (Session["categoryID"] != null) { DataSet ds = am.ShowPhoto(Int32.Parse(Session["categoryID"].ToString())); if (ds.Tables[0].Rows.Count == 0) { Response.Redirect("UserLogin.aspx"); } lvPhoto.DataSource = ds; lvPhoto.DataBind(); } else { return; } }
threenewbee 2014-10-31
  • 打赏
  • 举报
回复
天知道doRefreshingItem干嘛了 SubItems哪里来的也没说。
effun 2014-10-31
  • 打赏
  • 举报
回复
终于知道是为什么了,这应该是.net类库里的一个bug,先来看看最终解决方案。

            foreach (FileInfo file in files)
            {
                ListViewItem item = new ListViewItem();
                item.Tag = file;

                // 用Add替代AddRange
                for (int i = 1; i < listView1.Columns.Count; i++)
                    item.SubItems.Add(new ListViewItem.ListViewSubItem());

                listView1.Items.Add(item);
                doRefreshingItem(item);
            }
至于原因,先来看看ListViewSubItem.Text属性的源代码。


            public string Text {
                get { 
                    return text == null ? "" : text; 
                }
                set { 
                    text = value;
                    if (owner != null) { 
                        owner.UpdateSubItems(-1);
                    } 
                }
            } 
看它的赋值,只有owner非空时才会到界面上更新显示的文字,那么这个owner是在什么值被赋值的呢,当然是在被Add的时候。下面来看看Add和AddRange的代码。

            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里没有,这个就是问题所在了。
effun 2014-10-31
  • 打赏
  • 举报
回复
我猜你的doRefreshingItem应该是这样的

        private void doRefreshingItem(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();
        }
不知道为什么,ListViewItem在添加到ListView以后,无论如何改SubItem的Text,界面上都不会更新,即使使用Refresh或Invalidate也没用,但是在更改了ListViewItem的Text以后,所有的SubItem就全部改过来了。先不管为什么会是这种情况,解决办法很简单,在doRefreshingItem里,把对item.Text的赋值移到所有SubItem之后就可以了。

        private void doRefreshingItem(ListViewItem item)
        {
            FileInfo info = (FileInfo)item.Tag;
            
            item.SubItems[1].Text = info.Length.ToString("N0");
            item.SubItems[2].Text = info.LastWriteTime.ToString();
            item.Text = info.Name;
        }
poloyzhang 2014-10-31
  • 打赏
  • 举报
回复
其它只要得到值..............................其它都不是必须的.............................. 例如: 例得到个ListView 中的值我想这个不会是个太难的问题...
hualiang_ll 2014-10-31
  • 打赏
  • 举报
回复
可以想想是不是可以绕开这个问题,直接手工写修改的程序,参考这个帖子http://bbs.csdn.net/topics/280061499
KeepSayingNo 2014-10-31
  • 打赏
  • 举报
回复
这个应该不是你那样说的吧,人家是要附加一个数组,而不是一个对象,肯定用AddRange方法啊,楼主看看是否有个列头的问题,列头相当于不是数据列,需要单独考虑
fmonkey 2014-10-30
  • 打赏
  • 举报
回复
问题没说清楚,无法解答
bdmh 2014-10-30
  • 打赏
  • 举报
回复
无法更新是什么意思 doRefreshingItem干嘛了

110,962

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧