Skip to content

Instantly share code, notes, and snippets.

@gekka
Last active January 5, 2021 09:29
Show Gist options
  • Save gekka/4b85228ac7ad29457145db0978f9cfd4 to your computer and use it in GitHub Desktop.
Save gekka/4b85228ac7ad29457145db0978f9cfd4 to your computer and use it in GitHub Desktop.
Answer code for QnA 102861

[QnA] WPF DataGrid resizing column causes extreme scrolling

<DataGrid x:Name="TheDataGrid" AutoGenerateColumns="False" >
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <EventSetter Event="FrameworkElement.Loaded" Handler="DataGridColumnHeader_Loaded"/>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Field 1" Binding="{Binding Field_1}" />
        <DataGridTextColumn Header="Field 2" Binding="{Binding Field_2}" />
        <DataGridTextColumn Header="Field 3" Binding="{Binding Field_3}" />
        <DataGridTextColumn Header="Field 4" Binding="{Binding Field_4}" />
    </DataGrid.Columns>
</DataGrid>
private const string LEFT = "PART_LeftHeaderGripper";
private const string RIGHT = "PART_RightHeaderGripper";
private Point startPoint;
private double startWidth;
private DataGridColumn targetColumn;

private void DataGridColumnHeader_Loaded(object sender, RoutedEventArgs e)
{
    var header = (DataGridColumnHeader)sender;

    var thumbLeft = header.Template.FindName(LEFT, header) as Thumb;
    thumbLeft.AddHandler(Thumb.DragStartedEvent, (DragStartedEventHandler)Thumb_DragStarted, true);
    thumbLeft.AddHandler(Thumb.DragCompletedEvent, (DragCompletedEventHandler)Thumb_DragCompleted, true);

    var thumbRight = header.Template.FindName(RIGHT, header) as Thumb;
    thumbRight.AddHandler(Thumb.DragStartedEvent, (DragStartedEventHandler)Thumb_DragStarted, true);
    thumbRight.AddHandler(Thumb.DragCompletedEvent, (DragCompletedEventHandler)Thumb_DragCompleted, true);
}

private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
{
    var thumb = (Thumb)sender;
    DataGrid dg = GetParent<DataGrid>(thumb);
    startPoint = Mouse.GetPosition(dg);

    DataGridColumnHeader header = GetParent<DataGridColumnHeader>(thumb);

    if (thumb.Name == RIGHT)
    {
        targetColumn = header.Column;
    }
    else
    {
        int index = header.Column.DisplayIndex - 1;
        if (index < 0)
        {
            return;
        }
        targetColumn = dg.Columns.FirstOrDefault(_ => _.DisplayIndex == index);
    }
    startWidth = targetColumn.ActualWidth;
    thumb.PreviewMouseMove += Thumb_PreviewMouseMove;
}

private void Thumb_PreviewMouseMove(object sender, MouseEventArgs e)
{
    var thumb = (Thumb)sender;
    if (!thumb.IsDragging || targetColumn == null) { return; }

    e.Handled = true;

    DataGrid dg = GetParent<DataGrid>(thumb);
    Point currentPoint = Mouse.GetPosition(dg);
    double diffX = (currentPoint - startPoint).X;
    double newWidth = Math.Max(targetColumn.MinWidth, Math.Min(startWidth + diffX, targetColumn.MaxWidth));
    var length = new DataGridLength(newWidth);

    targetColumn.SetValue(DataGridColumn.WidthProperty, length);
}

private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
    ((Thumb)sender).PreviewMouseMove -= Thumb_PreviewMouseMove;
    targetColumn = null;
}

private T GetParent<T>(DependencyObject d) where T : DependencyObject
{
    T t = null;
    while (t == null) { t = d as T; d = VisualTreeHelper.GetParent(d); }
    return t;
}
@Algorithman
Copy link

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment