我们正在开发一个利用数据网格的应用程序。大多数网格的功能都是相当标准的东西 - 样式单元格,单元格内编辑,排序等。但是,一个要求是提供“拖放”功能,如Excel。这是您在行中选择一个或多个单元格的位置,然后在它们周围绘制一个粗边框。边框在其右下角有一个小方块,当您向下拖动时,Excel会将选定的单元格值复制到下面的行中。
使用.Net WPF数据网格尝试和实现这听起来很可怕(并且没有商业数据网格组件提供此功能)。有没有人开发出类似的功能,或建议可能的方法来实现这一目标?简单的旧副本&粘贴不是一种选择!
答案 0 :(得分:1)
以下是在数据网格中围绕所选单元格绘制粗线的一些提示:
使用以下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;
}
}