在WPF ListBox中隐藏空组

时间:2018-06-07 12:50:03

标签: c# wpf listbox

我尝试进一步自定义WPF ListBox的内置功能,以便在组中显示项目。

简而言之,如果组内的所有项目都已折叠(Visibility属性),我想隐藏Group的容器(以及Group&#39}的标题。)

首先,我有一个非常简单的类City代表单个Item。该类包含Shown属性。在ItemContainerStyle内,如果此属性的值为DataTrigger,我只需VisibilityCollapsed设置为False

class City : INotifyPropertyChanged
{
    private bool m_Shown = true;

    public string Name { get; set; }
    public string Country { get; set; }

    public bool Shown
    {
        get
        {
            return m_Shown;
        }
        set
        {
            m_Shown = value;
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Shown"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

这是我添加样本城市的方法,添加组描述和所有工作正常。

m_cities = new List<City>
{
    new City() { Name = "Berlin", Country = "Germany" },
    new City() { Name = "Milano", Country = "Italy" },
    new City() { Name = "Frankfurt", Country = "Germany" },
    new City() { Name = "Rome", Country = "Italy" }
};

ICollectionView view = CollectionViewSource.GetDefaultView(m_cities);
view.GroupDescriptions.Add(new PropertyGroupDescription("Country"));
Cities = view; // <-- Binds to ItemsSource of ListBox

我尝试了几种方法来自动隐藏群组,如果其中没有可见的内容(所有内容都已折叠),但都没有运气。

一种方法是在上面的代码中重复最后3行,这有效,但我注意到使用此方法减速并且列表框必须能够快速为用户工作。

贝娄是我的一个例子,这实际上是为了隐藏,但我不能在那之后让团体可见。我尝试使用转换器和类似设备,但我无法再次显示

<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Style.Triggers>
                    <Trigger Property="ActualHeight" Value="20">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </Trigger>
                </Style.Triggers>
                <Setter Property="Visibility" Value="Visible"/>
                <Setter Property="MinHeight" Value="20"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <StackPanel>
                                <TextBlock Text="{Binding Path=Name}"/>
                                <ItemsPresenter/>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</ListBox.GroupStyle>

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

这有点晚了(!),但希望它将来可能对其他人有所帮助。

大多数GroupItem样式中都有一个ItemsPresenter,用于托管和显示属于该组的子项。有理由认为,如果所有子项都折叠,则此ItemsPresenter的高度将为零。

因此,您可以根据此条件向模板添加触发器,并相应地设置整个组项目的Visibility。普通属性触发器似乎不起作用,但是数据触发器将起作用。群组项目的控制模板中的内容如下:

<ControlTemplate.Triggers>
    <DataTrigger Binding="{Binding ActualHeight, ElementName=ItemsPresenter}" Value="0">
        <Setter Property="Visibility" Value="Collapsed" />
    </DataTrigger>
</ControlTemplate.Triggers>

您将需要在控制模板中命名ItemsPresenter。在这里,我刚刚将其称为“ ItemsPresenter”,但您可以根据需要将其命名为任意

<ItemsPresenter x:Name="ItemsPresenter" />

您显然在正确的轨道上,但是您需要绑定到ActualHeight的{​​{1}},并且它需要是数据触发器而不是常规属性触发器。