Suplanus
Suplanus

Reputation: 1601

WPF Extended Toolkit PropertyGrid: Hide empty category

I hide specific properties with this code:

propertyItem.Visibility = Visibility.Collapsed;

Is it possible to hide a full category? Now my workaround is this:

if (propertyItem.Category == "MyCategory")
{
   propertyItem.Visibility = Visibility.Collapsed;
}

If i hide all items of a category, the header of it, is always visible. Is there a way to hide the header of a category?

Upvotes: 1

Views: 1102

Answers (1)

Il Vic
Il Vic

Reputation: 5666

Your target is not so easy to achieve, but at the same time is not impossible to reach. First of all we need to create our style for making hidden a category without visible properties:

<local:ItemsVisibleConverter x:Key="ItemsVisibleConverter" />

<Style x:Key="CustomPropertyItemGroupContainerStyle" TargetType="{x:Type GroupItem}">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Border>
                    <Expander Style="{StaticResource ExpanderStyle}" Header="{Binding Name}" IsExpanded="True">
                        <ItemsPresenter />
                    </Expander>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=Items, Converter={StaticResource ItemsVisibleConverter}}" Value="False">
            <Setter Property="Visibility" Value="Collapsed" />
        </DataTrigger>
    </Style.Triggers>
</Style>

As you can see, it uses a simple converter:

public class ItemsVisibleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        IEnumerable itemCollection = value as IEnumerable;
        if (itemCollection != null)
        {
            foreach (PropertyItem propertyItem in itemCollection)
            {
                if (propertyItem.Visibility == Visibility.Visible)
                {
                    return true;
                }
            }
        }

        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

and some other resources (I copied them from the standard ones by using ILSpy):

<SolidColorBrush x:Key="GlyphBrush" Color="#FF31347C" />

<ControlTemplate x:Key="ExpanderToggleButton" TargetType="{x:Type ToggleButton}">
    <Grid>
        <Rectangle Name="Rectangle" Margin="0,0,0,0" Fill="#00FFFFFF" />
        <Path Name="Up_Arrow" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{StaticResource GlyphBrush}" Data="M0,0L4,4 8,0z" RenderTransformOrigin="0.5,0.5">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="1" />
                    <SkewTransform AngleX="0" AngleY="0" />
                    <RotateTransform Angle="-90" />
                    <TranslateTransform X="0" Y="0" />
                </TransformGroup>
            </Path.RenderTransform>
        </Path>
        <Path Name="Down_Arrow" Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{StaticResource GlyphBrush}" Data="M0,4L4,0 8,4z" RenderTransformOrigin="0.5,0.5">
            <Path.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="1" />
                    <SkewTransform AngleX="0" AngleY="0" />
                    <RotateTransform Angle="135" />
                    <TranslateTransform X="0" Y="0" />
                </TransformGroup>
            </Path.RenderTransform>
        </Path>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="ToggleButton.IsChecked" Value="true">
            <Setter TargetName="Down_Arrow" Property="UIElement.Visibility" Value="Visible" />
            <Setter TargetName="Up_Arrow" Property="UIElement.Visibility" Value="Collapsed" />
            <Setter TargetName="Down_Arrow" Property="UIElement.OpacityMask" Value="#FF000000" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
    <Setter Property="Control.Padding" Value="0" />
    <Setter Property="Control.Background" Value="#FFF0F0F0" />
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Expander}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Name="ContentRow" Height="*" />
                    </Grid.RowDefinitions>
                    <Border Name="Border" Background="{TemplateBinding Control.Background}" BorderBrush="#FFF0F0F0">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <ToggleButton Template="{StaticResource ExpanderToggleButton}" OverridesDefaultStyle="True" IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
                            <ContentPresenter Grid.Column="1" Margin="1" RecognizesAccessKey="True" ContentSource="Header" TextElement.FontWeight="Bold" />
                        </Grid>
                    </Border>
                    <Border Name="ExpandSite" Visibility="Collapsed" Grid.Row="1" Background="{x:Static SystemColors.ControlBrush}" Padding="10 0 0 0">
                        <Border BorderThickness="0" Margin="0" Padding="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" Margin="{TemplateBinding Control.Padding}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" Focusable="False" />
                        </Border>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="Expander.IsExpanded" Value="True">
                        <Setter TargetName="ExpandSite" Property="UIElement.Visibility" Value="Visible" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now we need to extend the PropertyGrid control for setting our style in the PropertyItemsControl contained by the PropertyGrid:

public class PropertyGrid : Xceed.Wpf.Toolkit.PropertyGrid.PropertyGrid
{
    public GroupStyle GroupStyle
    {
        get;
        set;
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        PropertyItemsControl propertyItemsControl =
            Template.FindName("PART_PropertyItemsControl", this) as PropertyItemsControl;
        propertyItemsControl.GroupStyle.Clear();
        propertyItemsControl.GroupStyle.Add(GroupStyle);
    }
}

So your XAML will be

<local:PropertyGrid x:Name="pg">
    <local:PropertyGrid.GroupStyle>
        <GroupStyle ContainerStyle="{StaticResource CustomPropertyItemGroupContainerStyle}" />
    </local:PropertyGrid.GroupStyle>
</local:PropertyGrid>

I hope it can help you.

Upvotes: 0

Related Questions