65.9K
CodeProject is changing. Read more.
Home

Non-resizable columns in GridViewHeaderRowPresenter

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0 vote)

Sep 12, 2012

CPOL
viewsIcon

11340

Create a GridViewColumnCollection with resizable and non-resizable columns

Introduction

Recently I had the need for a simple grid where I didn't want all of the columns to be resizable. Changing the ControlTemplate to make the columns non-resizable is easy, but that makes all columns resizable and isn't what I wanted.

Using the code

The solution I found uses an Attached Property:

public class GridViewColumnHeaderResize : DependencyObject
{
    private static readonly DependencyProperty IsResizableProperty =
        DependencyProperty.RegisterAttached("IsResizable", typeof (bool),
        typeof (GridViewColumnHeaderResize), new FrameworkPropertyMetadata(true));
 
    public static void SetIsResizable(DependencyObject o, object value)
    {
        o.SetValue(IsResizableProperty, value);
    }
 
    public static bool GetIsResizable(DependencyObject o)
    {
        return (bool) o.GetValue(IsResizableProperty);
    }
}

In the controltemplate for the GridViewColumnHeader you can create a trigger that changes the visibility for the Thumb that is used to resize the column (the part that does the trick in bold):

<Style TargetType="GridViewColumnHeader">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GridViewColumnHeader" >
                <Grid SnapsToDevicePixels="True">
                    <Border BorderThickness="0,1,0,1" 
                            BorderBrush="{TemplateBinding Border.BorderBrush}" 
                            Background="{TemplateBinding Panel.Background}" 
                            Name="HeaderBorder">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition MaxHeight="7" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <Rectangle Fill="#FFE3F7FF" Name="UpperHighlight" Visibility="Collapsed" />
                            <Border Padding="{TemplateBinding Control.Padding}" Grid.RowSpan="2">
                                <ContentPresenter RecognizesAccessKey="True" 
                                   Content="{TemplateBinding ContentControl.Content}" 
                                   ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                                   ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" 
                                   Name="HeaderContent" Margin="0,0,0,1" 
                                   HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                                   VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                                   SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                            </Border>
                        </Grid>
                    </Border>
                    <Border BorderThickness="1,0,1,1" Name="HeaderHoverBorder" Margin="1,1,0,0" />
                    <Border BorderThickness="1,1,1,0" Name="HeaderPressBorder" Margin="1,0,0,1" />
                    <Canvas>
                        <Thumb Name="PART_HeaderGripper">
                            <Thumb.Style>
                                <Style TargetType="Thumb">
                                    <Style.Resources>
                                        <ResourceDictionary />
                                    </Style.Resources>
                                    <Setter Property="Canvas.Right" Value="-9"/>
                                    <Setter Property="FrameworkElement.Width" Value="18"/>
                                    <Setter Property="FrameworkElement.Height" 
                                       Value="{Binding ActualHeight, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                                    <Setter Property="Control.Padding" Value="0,0,0,0"/>
                                    <Setter Property="Panel.Background">
                                        <Setter.Value>
                                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                                <LinearGradientBrush.GradientStops>
                                                    <GradientStop Color="#FFF2F2F2" Offset="0" />
                                                    <GradientStop Color="#FFD5D5D5" Offset="1" />
                                                </LinearGradientBrush.GradientStops>
                                            </LinearGradientBrush>
                                        </Setter.Value>
                                    </Setter>
                                    <Setter Property="Control.Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="Thumb">
                                                <Border Padding="{TemplateBinding Control.Padding}" 
                                                       Background="#00FFFFFF">
                                                    <Rectangle Fill="{TemplateBinding Panel.Background}" 
                                                       Width="1" HorizontalAlignment="Center" />
                                                </Border>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </Thumb.Style>
                        </Thumb>
                    </Canvas>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="FixFloatTable:GridViewColumnHeaderResize.IsResizable" Value="False">
                        <Setter TargetName="PART_HeaderGripper" Property="Visibility" Value="Hidden"/>
                    </Trigger>
                            <Trigger Property="UIElement.IsMouseOver" Value="True">
                        <Setter Property="Panel.Background" TargetName="HeaderBorder">
                            <Setter.Value>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FFBDEDFF" Offset="0" />
                                        <GradientStop Color="#FFB7E7FB" Offset="1" />
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" 
                           TargetName="HeaderHoverBorder" Value="#FF88CBEB"/>
                        <Setter Property="UIElement.Visibility" 
                           TargetName="UpperHighlight" Value="Visible"/>
                        <Setter Property="Panel.Background" 
                           TargetName="PART_HeaderGripper" Value="#00FFFFFF"/>
                    </Trigger>
                    <Trigger Property="ButtonBase.IsPressed" Value="True">
                        <Setter Property="Panel.Background" TargetName="HeaderBorder">
                            <Setter.Value>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#FF8DD6F7" Offset="0" /> 
                                        <GradientStop Color="#FF8AD1F5" Offset="1" /> 
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Border.BorderBrush" 
                           TargetName="HeaderHoverBorder" Value="#FF95DAF9"/>
                        <Setter Property="Border.BorderBrush" 
                           TargetName="HeaderPressBorder" Value="#FF7A9EB1"/>
                        <Setter Property="UIElement.Visibility" 
                           TargetName="UpperHighlight" Value="Visible"/>
                        <Setter Property="Shape.Fill" 
                           TargetName="UpperHighlight" Value="#FFBCE4F9"/>
                        <Setter Property="UIElement.Visibility" 
                           TargetName="PART_HeaderGripper" Value="Hidden"/>
                        <Setter Property="FrameworkElement.Margin" 
                           TargetName="HeaderContent" Value="1,1,0,0"/>
                    </Trigger> 
                    <Trigger Property="FrameworkElement.Height" Value="NaN">
                        <Setter Property="FrameworkElement.MinHeight" Value="20"/>
                    </Trigger>
                    <Trigger Property="UIElement.IsEnabled" Value="False">
                        <Setter Property="TextElement.Foreground" 
                           Value="{DynamicResource ResourceKey={x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Note: I got the ControlTemplate by using the tool Show Me The Template.

In the GridViewColumnCollection that is used to fill the GridViewHeaderRowPresenter, we can used the Attached Property like this:

<GridViewColumnCollection x:Key="columns">
    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
    <GridViewColumn Width="60" DisplayMemberBinding="{Binding Value}"/>
        <GridViewColumnHeader Content="Value" 
           FixFloatTable:GridViewColumnHeaderResize.IsResizable="False"/>
    </GridViewColumn>
</GridViewColumnCollection ">

The Attached Property needs to be specified on the GridViewColumnHeader in order to work in the ControlTemplate.

I hope this tip is useful for someone else too Smile