wpf实现datagrid仿照excel拖拽自动填充

控件选择

实现自动填充在控件上需要实现两个部分,
1.开始实现自动填充的单元格右下角有一个小方框标记,
2.拖拽过程中应该有一个框圈出所有的需要填充的单元格。

这里采用canvas和border,利用canvas.SetLeft和SetRight这些属性实现Border的精准控制size。

xaml实现

在这里插入图片描述
在datagrid的xaml上插入canvas并命名,方便在后台代码中直接调用canvas。

其他关键方法

private void DataGridCell_MouseEnter(object sender, MouseEventArgs e)
{
    Border border = new Border();
    border.BorderThickness = new Thickness(2);
    border.BorderBrush = Brushes.Black;

    DataGridCell cell = sender as DataGridCell;
    if (cell != null)
    {
        DataGridRow row = FindVisualParent<DataGridRow>(cell);
        if (row != null)
        {
            // Calculate the range of cells to be highlighted
            int columnIndex = cell.Column.DisplayIndex + 1; // Starting column index
            int rowIndex = row.GetIndex();
            int columnSpan = 3; // Number of columns to span
            int rowSpan = 2; // Number of rows to span

            // Find the starting and ending cells for the highlight
            DataGridCell startCell = GetCell(rowIndex, columnIndex);
            DataGridCell endCell = GetCell(rowIndex + rowSpan - 1, columnIndex + columnSpan - 1);

            // Get the rectangle of the highlight area
            Rect rectStart = GetCellRect(startCell);
            Rect rectEnd = GetCellRect(endCell);
            Rect rectHighlight = new Rect(rectStart.TopLeft, rectEnd.BottomRight);

            // Set the border size and position
            border.Width = rectHighlight.Width;
            border.Height = rectHighlight.Height;
            Canvas.SetLeft(border, rectHighlight.Left);
            Canvas.SetTop(border, rectHighlight.Top);

            // Add the border to the visual tree
            canvas.Children.Add(border);
        }
    }
}

private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
    DependencyObject parentObject = VisualTreeHelper.GetParent(child);
    if (parentObject == null) return null;

    T parent = parentObject as T;
    if (parent != null) return parent;

    return FindVisualParent<T>(parentObject);
}

private DataGridCell GetCell(int row, int column)
{
    DataGridRow rowContainer = GetRow(row);
    if (rowContainer != null)
    {
        DataGridCellsPresenter presenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
        if (presenter != null)
        {
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            return cell;
        }
    }
    return null;
}

private DataGridRow GetRow(int index)
{
    DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
    if (row == null)
    {
        dataGrid.UpdateLayout();
        dataGrid.ScrollIntoView(dataGrid.Items[index]);
        row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(index);
    }
    return row;
}

private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
    int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < childrenCount; i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(parent, i);
        T obj = child as T;
        if (obj != null) return obj;

        T childOfChild = FindVisualChild<T>(child);
        if (childOfChild != null) return childOfChild;
    }
    return null;
}

private Rect GetCellRect(DataGridCell cell)
{
    Rect rectCell = new Rect(cell.TransformToAncestor(dataGrid).Transform(new Point(0, 0)), cell.RenderSize);
    return rectCell;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值