gpt4 book ai didi

wpf - 在 WPF 数据网格中实现 "drag and fill"功能

转载 作者:行者123 更新时间:2023-12-04 18:25:32 26 4
gpt4 key购买 nike

我们正在开发一个使用数据网格的应用程序。网格的大部分功能将是相当标准的东西——样式化单元格、单元格内编辑、排序等。然而,一个要求是提供“拖放”功能,如 Excel。这是您在一行中选择一个或多个单元格的地方,然后在它们周围绘制一个粗边框。边框的右下角有一个小方 block ,当您向下拖动它时,Excel 会将选定的单元格值复制到下面的行。

尝试使用 .Net WPF 数据网格(并且没有任何商业数据网格组件提供此功能)来实现这听起来很可怕。有没有人开发过类似的功能,或者提出了实现此功能的可能方法?普通的旧复制和粘贴不是一种选择!

最佳答案

以下是在数据网格中选定的单元格周围绘制粗线的一些提示:

  • 订阅数据网格的 SelectedCellsChanged 事件。
  • 在事件处理程序中,获取数据网格的装饰器层,如果所选单元格的数量 > 0 并且还没有(缓存的)装饰器层,则向其添加自定义装饰器。通过装饰器的构造函数传递数据网格。如果所选单元格的数量 == 0 且缓存的装饰层 != null,则从装饰层中移除装饰。在事件处理程序结束时,调用 adornerLayer.Update(datagrid)
  • 使用以下 CustomAdorner 类:

    public class DataGridSelectionAdorner : Adorner {
    private readonly DataGrid datagrid;
    private readonly SolidColorBrush backgroundBrush = new SolidColorBrush(Color.FromArgb(30, 0, 0, 0));
    readonly Pen pen = new Pen(new SolidColorBrush(Colors.Black), 1);
    private readonly Dictionary<DataGridCellInfo, int[]> cellInfoToTableRowAndColumn = new Dictionary<DataGridCellInfo, int[]>();

    public DataGridSelectionAdorner(UIElement adornedElement)
    : base(adornedElement) {
    datagrid = (DataGrid)adornedElement;
    pen.DashStyle = new DashStyle(new[] { 3.0, 3.0 }, 0);
    IsHitTestVisible = false;
    }

    protected override void OnRender(DrawingContext drawingContext) {
    ItemContainerGenerator generator = datagrid.ItemContainerGenerator;
    IEnumerable<int> rows =
    datagrid.SelectedCells.Select(c =>
    generator.IndexFromContainer(
    generator.ContainerFromItem(c.Item)
    )
    );
    IEnumerable<int> columns = datagrid.SelectedCells.Select(
    c => c.Column.DisplayIndex
    );
    int minRow = rows.Min();
    int maxRow = rows.Max();
    int minColumn = columns.Min();
    int maxColumn = columns.Max();

    foreach (var cell in datagrid.SelectedCells) {
    int row = generator.IndexFromContainer(generator.ContainerFromItem(cell.Item));
    int column = cell.Column.DisplayIndex;
    cellInfoToTableRowAndColumn[cell] = new[] { row, column };
    }

    var topLeft = cellInfoToTableRowAndColumn.First(c => c.Value[0] == minRow && c.Value[1] == minColumn).Key;
    var bottomRight = cellInfoToTableRowAndColumn.First(c => c.Value[0] == maxRow && c.Value[1] == maxColumn).Key;

    var topLeftCell = GetDataGridCell(topLeft);
    var bottomRightCell = GetDataGridCell(bottomRight);

    const double marginX = 4.5;
    const double marginY = 3.5;
    Point topLeftPoint = topLeftCell.TranslatePoint(new Point(marginX, marginY), datagrid);
    Point bottomRightPoint = bottomRightCell.TranslatePoint(
    new Point(bottomRightCell.RenderSize.Width - marginX, bottomRightCell.RenderSize.Height - marginY),
    datagrid
    );

    drawingContext.DrawRectangle(backgroundBrush, pen, new Rect(topLeftPoint, bottomRightPoint));
    }

    private static DataGridCell GetDataGridCell(DataGridCellInfo cellInfo) {
    var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
    if (cellContent != null)
    return (DataGridCell)cellContent.Parent;
    return null;
    }
    }

关于wpf - 在 WPF 数据网格中实现 "drag and fill"功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14258663/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com