所有内容折叠后隐藏扩展器

时间:2015-10-01 11:34:25

标签: c# wpf xaml expander

我有一个WPF Datagrid,它有一个Collection View Source,上面有3个分组级别。

我已将数据网格设计为使用3个扩展程序,使其看起来像这样:

Level 1 Expander
<content>
    Level 2 Expander
    <content>
        Level 3 Expander
        <content>

2级和1级只是小组的标题

我有第二个控件允许用户显示和隐藏3级项目,这些项目通过将Level 3扩展器绑定到后面对象中的布尔“IsVisible”属性来工作。

       <!--  Style for groups under the top level. this is the style for how a sample is displayed  -->
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Margin" Value="0,0,0,0" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type GroupItem}">

                                <!--  The parent control that determines whether or not an item needs to be displayed. This holds all of the sub controls displayed for a sample  -->
                                <Expander Margin="2"
                                          Background="{Binding Path=Name,
                                                               Converter={StaticResource SampleTypeToColourConverter}}"
                                          IsExpanded="True"
                                          Visibility="{Binding Path=Items[0].IsVisibleInMainScreen,
                                                               Converter={StaticResource BoolToVisibilityConverter}}">

这种方法效果很好。

无论其

如果用户取消选择3级扩展器中的所有项目,则2级扩展器标头仍会显示有价值的不动产已用完,显示没有可见数据的组的标题。

我想要的是一种将2级扩展器的可见性绑定到其子控件的方法,并说“如果所有子项都可见,则显示扩展器,否则将其折叠”

这可能吗?

4 个答案:

答案 0 :(得分:3)

假设您正在使用MVVM类型的样式,您可以绑定到组对象的属性,如果所有子项都不可见,则返回false:

public bool AreChildrenVisible { get { return _children.Any(x=>x.IsVisibleInMainScreen); } }

或者,通过Converter类传递Items集合以返回Visibility,具体取决于组中所有子项的聚合状态。

答案 1 :(得分:3)

我找到了一种相当简单和干净的方式,但并不完美,以实现你的目标。如果侯没有太多的团体,这应该可以解决问题。

我刚刚将此触发器添加到GroupItem ControlTemplate

<ControlTemplate.Triggers>
    <DataTrigger Binding="{Binding ElementName=IP, Path=ActualHeight}" Value="0">
        <Setter Property="Visibility" Value="Hidden"/>
        <Setter Property="Height" Value="1"/>
    </DataTrigger>
</ControlTemplate.Triggers>

ItemsPresenter(IP)ActualSize降至零时,它将几乎折叠标题。

为什么差不多?

当控件初始化并且在绑定发生之前,ItemPresenter ActualHeight为0,当Visibility设置为Collapsed时,ItemPresenter不会在所有

使用Visibility.Hidden允许ItemsPresenter进入渲染阶段并进行调整。 我成功地将Height放到.4 px但我怀疑这是设备依赖的。

答案 2 :(得分:1)

这不是一个直接的答案,因为您必须专门为您的需要实现它,但之前我已经使用了网格控件的覆盖来创建成员的动态网格分配,如果没有可见的成员,它会隐藏父组框。

public class DynamicLayoutGrid : Grid
{

       protected override void OnInitialized(EventArgs e)
       {
                //Hook up the loaded event (this is used because it fires after the visibility binding has occurred)
             this.Loaded += new RoutedEventHandler(DynamicLayoutGrid_Loaded);

             base.OnInitialized(e);
        }


        void DynamicLayoutGrid_Loaded(object sender, RoutedEventArgs e)
        {
            int numberOfColumns = ColumnDefinitions.Count;
            int columnSpan = 0;
            int rowNum = 0;
            int columnNum = 0;
            int visibleCount = 0;

            foreach (UIElement child in Children)
            {
                //We only want to layout visible items in the grid
                if (child.Visibility != Visibility.Visible)
                {
                    continue;
                }
                else
                {
                    visibleCount++;
                }

                //Get the column span of the element if it is not in column 0 as we might need to take this into account
                columnSpan = Grid.GetColumnSpan(child);

                //set the Grid row of the element
                Grid.SetRow(child, rowNum);

                //set the grid column of the element (and shift it along if the previous element on this row had a rowspan greater than 0
                Grid.SetColumn(child, columnNum);

                //If there isn't any columnspan then just move to the next column normally
                if (columnSpan == 0)
                {
                    columnSpan = 1;
                }

                //Move to the next available column
                columnNum += columnSpan;

                //Move to the next row and start the columns again
                if (columnNum >= numberOfColumns)
                {
                    rowNum++;
                    columnNum = 0;
                }
            }

            if (visibleCount == 0)
            {
                if (this.Parent.GetType() == typeof(GroupBox))
                {
                    (this.Parent as GroupBox).Visibility = Visibility.Collapsed;
                }
            }
        }
    }

答案 3 :(得分:0)

使用IMultiValueConverter实现将项目转换为可见性。 如果所有项IsVisibleInMainScreen属性都返回true,则转换器将返回可见的其他隐藏。

将转换器用于转换原始示例中第一项的相同位置