我正在尝试进一步自定义 WPF ListBox 的内置功能,以按组显示项目。
简而言之,如果组内的所有项目都折叠(Visibility属性),我想隐藏组的容器(以及组的标题)。
首先,我有非常简单的代表单个项目的 City 类。此类包括Shown财产。在里面ItemContainerStyle我只是将DataTrigger其设置Visibility为Collapsedif 该属性的值为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;
}
Run Code Online (Sandbox Code Playgroud)
这就是我添加样本城市、添加组描述的方法,一切正常。
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
Run Code Online (Sandbox Code Playgroud)
我尝试了多种方法来自动隐藏组,如果其中没有更多可见的项目(所有项目都折叠起来),但都没有运气。
一种方法是重复上面代码中的最后 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>
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助。
有点(!)晚了,但希望它将来可以帮助其他人。
大多数(所有?)样式的控件模板内部GroupItem都有一个ItemsPresenter用于托管和显示属于该组的子项的模板。按理说,如果所有子项都折叠起来,则其ItemsPresenter高度将为零。
因此,您可以根据此条件在控件模板中添加触发器,并Visibility相应地设置整个组项的值。普通的属性触发器似乎不起作用,但数据触发器可以。像这样的东西:
<ControlTemplate>
<StackPanel x:Name="Root">
...
<ItemsPresenter x:Name="ItemsPresenter" />
...
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding ActualHeight, ElementName=ItemsPresenter}" Value="0">
<Setter TargetName="Root" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
您需要命名控件模板的根元素(在本例中,它是StackPanel我命名为“Root”的元素)以及ItemsPresenter元素(我刚刚将其命名为“ItemsPresenter”)。显然,根元素可能是不同的类型,您可以使用您喜欢的任何名称。
您的方向是正确的,但您需要绑定到ActualHeight,ItemsPresenter并且它需要是数据触发器而不是普通的属性触发器。
| 归档时间: |
|
| 查看次数: |
871 次 |
| 最近记录: |