Hank
Hank

Reputation: 2616

How to get column reorder working in datagrid

I have created a datagrid with a little customization. The last column header is made up of the usual textblock plus a stackpanel under it with rotated text.

In order to make it look better I made the first 6 columns 25 in height with vertical alignment at the bottom, otherwise they would have stretched to the top.

enter image description here

My second image shows that I can reorder the last column. enter image description here

However I can not reorder any of the first six.

In the next pics (Left) I removed the vertical alignment altogether making it sit in the center by default, (Right) I set the vertical alignment to the Top. enter image description here

As you can see there must be another level of component, you cannot just alter the DataGridColumnHeader style and expect it to be reordered via dragging.

Questions:

Here is my XAML code:

<Window x:Class="DGTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="250" Width="500">

    <Window.Resources>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Background" Value="Transparent"/>
        </Style>
        <Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
            <Setter Property="Height" Value="25" />
            <Setter Property="VerticalAlignment" Value="Bottom"/>
        </Style>

    </Window.Resources>

    <Grid Name="gridUsers" Background="Transparent">
        <DockPanel Background="Transparent">
            <DataGrid Background="Transparent" CanUserReorderColumns="True" AutoGenerateColumns="False" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" CanUserReorder="True" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=User_ID}"/>
                    <DataGridTextColumn Header="Name" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Name}"/>
                    <DataGridTextColumn Header="Username" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Username}"/>
                    <DataGridTextColumn Header="Job Title" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Job_Title}"/>
                    <DataGridTextColumn Header="Department" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Department}"/>
                    <DataGridTextColumn Header="Company" CanUserReorder="True" CanUserSort="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" Binding="{Binding Path=Company}"/>
                    <DataGridTemplateColumn CanUserReorder="True" CanUserSort="False" >
                        <DataGridTemplateColumn.Header>
                            <StackPanel Orientation="Vertical" Background="Transparent" HorizontalAlignment="Center">
                                <Label Background="AliceBlue" HorizontalAlignment="Stretch" Height="25" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" >
                                    Access
                                </Label>
                                <StackPanel Orientation="Horizontal" Background="Transparent" CanVerticallyScroll="False" CanHorizontallyScroll="False">
                                    <TextBlock Text="Read" Width="80" Margin="20,1,0,1" >
                                        <TextBlock.LayoutTransform>
                                          <RotateTransform Angle="-60"/>
                                        </TextBlock.LayoutTransform>
                                    </TextBlock>
                                    <TextBlock Text="Write" Width="80" Margin="-15,1,0,1" >
                                        <TextBlock.LayoutTransform>
                                          <RotateTransform Angle="-60"/>
                                        </TextBlock.LayoutTransform>
                                    </TextBlock>
                                    <TextBlock Text="Administrator" Width="80" Margin="-15,1,0,1" >
                                        <TextBlock.LayoutTransform>
                                          <RotateTransform Angle="-60"/>
                                        </TextBlock.LayoutTransform>
                                    </TextBlock>
                                </StackPanel>
                            </StackPanel>
                        </DataGridTemplateColumn.Header>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </DockPanel>
    </Grid>
</Window>

Upvotes: 0

Views: 2668

Answers (2)

Boopesh
Boopesh

Reputation: 404

I tried to fulfill your requirement with the following changes. Change the ColumnHeaderStyle as given below. I just given raw style of column headers with the following changes. Change that as per your application needs.

  <Style TargetType="DataGridColumnHeader">
        <Setter Property="Background" Value="Transparent"/>
    </Style>

 <Style x:Key="ColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="VerticalContentAlignment" Value="Bottom"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridColumnHeader">
                    <Grid>
                    <Border Background="Gray" VerticalAlignment="Bottom" Margin="1">
                        <ContentPresenter Content="{TemplateBinding Content}" Margin="5" VerticalAlignment="Bottom"/>
                    </Border>
                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left">
                        <Thumb.Style>
                            <Style TargetType="{x:Type Thumb}">
                                <Setter Property="Width" Value="8"/>
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="Cursor" Value="SizeWE"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Thumb}">
                                            <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Thumb.Style>
                    </Thumb>
                    <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right">
                        <Thumb.Style>
                            <Style TargetType="{x:Type Thumb}">
                                <Setter Property="Width" Value="8"/>
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="Cursor" Value="SizeWE"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Thumb}">
                                            <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Thumb.Style>
                    </Thumb>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Also set the DragIndicatorStyle of all columns as given below.

 <Style x:Key="DragIndicatorStyle" TargetType="Control">
        <Setter Property="Height" Value="75"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Margin" Value="0,-25,0,0"/>
        <Setter Property="VerticalAlignment" Value="Bottom"/>
        <Setter Property="VerticalContentAlignment" Value="Bottom"/>                   
    </Style>

Upvotes: 2

Iain
Iain

Reputation: 2550

I think your problem is to do with making the Header only 25 high removes the correct drag/drop targets which is why it doesn't work correctly.

Putting a custom Header on each row seems to give the behaviour you desire. In this case as it is being wrapped in a Grid, there is a control filling the entire space so the drag/drop can work correctly. (The styling of the header could be moved to a Style I think rather than repeating it on each column). I think there must be a better way than giving the stack panel a size of 90 but I can't find a better way at the moment.

<DataGridTextColumn CanUserReorder="True" CanUserSort="True" Binding="{Binding Path=Company}">
    <DataGridTextColumn.Header>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="25"></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Height="90"  Grid.Row="0"/>
            <TextBlock Height="25" Grid.Row="1">Access</TextBlock>
        </Grid>
    </DataGridTextColumn.Header>                        
</DataGridTextColumn>

Upvotes: 0

Related Questions