C# 空ListViewGroup未显示在ListView中

C# 空ListViewGroup未显示在ListView中,c#,.net,vb.net,winforms,listview,C#,.net,Vb.net,Winforms,Listview,我在MSDN上找不到任何将隐藏空ListViewGroup的备注。是故意的,还是我遗漏了什么?我下面的示例代码将仅显示带有项目“item1”的“group 2” 更新: 有没有办法在不添加虚拟项的情况下显示ListViewGroup 目前,我唯一的解决方案是使用(Vista和更高版本)这是Microsoft design无法做到的。 请看上的讨论。 不要被头衔所愚弄。它谈论的是空组。我上面提到的黑客不推荐使用。但是,如果确实希望显示空组,则只需将添加代码委托给一个单独的实用程序方法,该方法将检查

我在MSDN上找不到任何将隐藏空ListViewGroup的备注。是故意的,还是我遗漏了什么?我下面的示例代码将仅显示带有项目“item1”的“group 2”

更新: 有没有办法在不添加虚拟项的情况下显示ListViewGroup


目前,我唯一的解决方案是使用(Vista和更高版本)

这是Microsoft design无法做到的。
请看上的讨论。

不要被头衔所愚弄。它谈论的是空组。

我上面提到的黑客不推荐使用。但是,如果确实希望显示空组,则只需将添加代码委托给一个单独的实用程序方法,该方法将检查组是否为空。如果是,则会将其添加到“默认”组(因此它至少会显示),直到您向其中添加项目为止

public static void AddGroup(this ListView lv, ListViewGroup lg)
{
    if (lg.Items.Count > 0 || lv.Items.Cast<ListViewItem>().Any(tg => tg.Group == lg))
        lv.Groups.Add(lg);
    else
    {
        var item = lv.Items.Add(lg.Header);
        item.Tag = lg;
    }
}

public static void AddItem(this ListView lv, ListViewItem li, string groupKey) // Could also take ListViewGroup here...
{
    if (lv.Groups[groupKey] == null && lv.Items.ContainsKey(groupKey))
    {
        lv.Groups.Add((ListViewGroup)lv.Items[groupKey].Tag);
        lv.Items.RemoveByKey(groupKey);
    }
    lv.Items.Add(li);
    li.Group = lv.Groups[groupKey];
}

public static void AddItem(this ListView lv, ListViewItem li, ListViewGroup lg)
{
    lv.AddItem(li, lg.Header);
}
publicstaticvoidaddgroup(此ListView lv、ListViewGroup lg)
{
if(lg.Items.Count>0 | | lv.Items.Cast().Any(tg=>tg.Group==lg))
lv.组。添加(lg);
其他的
{
var item=lv.Items.Add(lg.Header);
item.Tag=lg;
}
}
public static void AddItem(此ListView lv、ListViewItem li、string groupKey)//也可以在此处获取ListViewGroup。。。
{
if(lv.Groups[groupKey]==null&&lv.Items.ContainsKey(groupKey))
{
添加((ListViewGroup)lv.Items[groupKey].Tag);
lv.Items.RemoveByKey(groupKey);
}
lv.项目。添加(li);
li.Group=lv.Groups[groupKey];
}
公共静态无效添加项(此ListView lv、ListViewItem li、ListViewGroup lg)
{
低压附加项(锂、lg头);
}
另一个警告,不推荐。这是相当大的开销,不值得费心(IMO)。但是,嘿,每个人都有自己的。这段代码完全没有经过测试,如果你真的需要它来工作,就把它扔到那里去(这种情况永远不会发生,最好寻找替代方案)。最糟糕的是,组声明几乎就驻留在ListItem本身中,这样您就可以很容易地更改组

最后一个警告,不推荐

编辑:我已经将上面的代码修改为ListView对象上的扩展方法,这样您就可以从这些方法直接访问ListView。无论何时添加组,只要调用
listView.AddGroup
,添加可以使用
listView.AddItem
方法的项即可。这与
listView.Items.Add
listView.Groups.Add
方法相反。需要记住的一点是,您不需要将项目分配给组,而只需要将组分配给项目。这使得您可以通过更改引用在组之间切换项目,而不必在组之间删除/添加引用。这还假设您已声明ListItemGroup的
标题
关键字
相同(换句话说,
新建ListItemGroup(“HeaderText”/*Key*/,“HeaderText”/*Header*/)
。否则,您只需更改
AddItem
中的逻辑即可引用正确的值(通常是
Name

“今年早些时候,我在考虑显示空组时遇到了同样的问题。根据设计,Microsoft不会显示任何项目为空的组名。您需要做的是创建/添加一个空项目或包含文本空白字符的项目到组中。当您有实际的数据项目时要填充该组,必须记住从该组中删除空/空白项。”

来源:

可以完全做到这一点。有一个ShowEmptyGroups属性可以做到这一点:


还有一个更好的ListView Express,它是免费软件,也支持组。它不是ListView包装器,而是对所有功能的完全重新实现,100%管理,刚刚改进…更好:-)

此方法确保ListView组显示

void MakeSureListViewGroupHeaderShows(ListView lv)
{
    foreach (ListViewGroup lvg in lv.Groups)
    {
        if (lvg.Items.Count == 0)
        {
            // add empty list view item
            ListViewItem lvi = new ListViewItem(string.Empty);
            lvi.Group = lvg;
            lv.Items.Add(lvi);
        }
        else
        {
            // remove our dummy list view item
            foreach (ListViewItem lvi in lvg.Items)
            {
                if (lvi.Text == string.Empty)
                {
                    lvi.Remove();
                }
            }
        }
    }
}

据我所知,空组根本不显示。您可以添加一个空白字符串项来显示组。正确。空组不会显示。您必须先向其中添加项。这是正确的。查看ListView的源代码,所有的绘制和分组都是通过PInvokes完成的,这意味着这不仅仅是一个简单的操作重写ListView的draw方法。可能有一种方法可以通过使用我将发布的一个小“hack”来实现,但它并不漂亮。在这种情况下,我支持Microsoft的设计决策。我不喜欢打开一个组而在其中找不到任何内容。最好不要显示任何内容。
void MakeSureListViewGroupHeaderShows(ListView lv)
{
    foreach (ListViewGroup lvg in lv.Groups)
    {
        if (lvg.Items.Count == 0)
        {
            // add empty list view item
            ListViewItem lvi = new ListViewItem(string.Empty);
            lvi.Group = lvg;
            lv.Items.Add(lvi);
        }
        else
        {
            // remove our dummy list view item
            foreach (ListViewItem lvi in lvg.Items)
            {
                if (lvi.Text == string.Empty)
                {
                    lvi.Remove();
                }
            }
        }
    }
}