wpf datagrid行拖拽 样式
时间: 2023-07-29 10:08:00 浏览: 216
WPF DataGrid 行拖拽
5星 · 资源好评率100%
要实现 WPF DataGrid 行拖拽的样式,可以使用以下方法:
1. 定义行拖拽的样式。可以在 XAML 中定义 DataGridRow 的 Style,添加一个 Thumb 控件,用于拖拽行。例如:
```xaml
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Grid>
<Thumb x:Name="PART_DragThumb" Width="8" Height="8" Background="Transparent"
DragDelta="PART_DragThumb_DragDelta"/>
<DataGridCellsPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
```
其中,PART_DragThumb 是拖拽用的 Thumb 控件,DataGridCellsPresenter 显示单元格内容。
2. 在 DataGrid 的 RowStyle 中添加 PreviewMouseLeftButtonDown、PreviewMouseMove 和 PreviewMouseLeftButtonUp 事件处理程序,分别处理行拖拽的开始、移动和结束事件。在 PreviewMouseLeftButtonDown 事件中,启用拖拽操作,并将拖拽的行保存到 _draggedRow 变量中。在 PreviewMouseMove 事件中,根据鼠标移动的距离调整拖拽用的 Thumb 控件的位置。在 PreviewMouseLeftButtonUp 事件中,结束拖拽操作,并将 _draggedRow 置为 null。例如:
```csharp
private DataGridRow _draggedRow;
private void DataGrid_RowStyle(object sender, EventArgs e)
{
DataGridRow row = e.OriginalSource as DataGridRow;
if (row != null)
{
row.PreviewMouseLeftButtonDown += DataGrid_RowPreviewMouseLeftButtonDown;
row.PreviewMouseMove += DataGrid_RowPreviewMouseMove;
row.PreviewMouseLeftButtonUp += DataGrid_RowPreviewMouseLeftButtonUp;
}
}
private void DataGrid_RowPreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
{
_draggedRow = sender as DataGridRow;
if (_draggedRow != null)
{
_draggedRow.IsSelected = true;
DragDrop.DoDragDrop(_draggedRow, _draggedRow.Item, DragDropEffects.Move);
}
}
private void DataGrid_RowPreviewMouseMove(object sender, MouseEventArgs e)
{
if (_draggedRow != null && e.LeftButton == MouseButtonState.Pressed)
{
Point currentPoint = e.GetPosition(DataGrid);
Vector diff = _dragStartPoint - currentPoint;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
Thumb thumb = _draggedRow.Template.FindName("PART_DragThumb", _draggedRow) as Thumb;
if (thumb != null)
{
DragDrop.AddPreviewDragOverHandler(thumb, DataGrid_DragOver);
DragDrop.AddPreviewDropHandler(thumb, DataGrid_Drop);
DataObject dragData = new DataObject("DataGridRow", _draggedRow.Item);
DragDrop.DoDragDrop(thumb, dragData, DragDropEffects.Move);
DragDrop.RemovePreviewDragOverHandler(thumb, DataGrid_DragOver);
DragDrop.RemovePreviewDropHandler(thumb, DataGrid_Drop);
}
}
}
}
private void DataGrid_RowPreviewMouseLeftButtonUp(object sender, MouseEventArgs e)
{
_draggedRow = null;
}
```
3. 在 DataGrid 的 DragOver 和 Drop 事件处理程序中,根据当前鼠标位置和目标行位置计算出拖拽的行应该插入到哪个位置,并调整 DataGrid 的 ItemsSource 中对应的元素的位置。例如:
```csharp
private void DataGrid_DragOver(object sender, DragEventArgs e)
{
Thumb thumb = sender as Thumb;
if (thumb != null)
{
Point dropPoint = e.GetPosition(DataGrid);
DataGridRow row = DataGrid.ItemContainerGenerator.ContainerFromIndex(DataGrid.Items.Count - 1) as DataGridRow;
double bottomEdge = row.TransformToAncestor(DataGrid).Transform(new Point(0, row.ActualHeight)).Y;
if (dropPoint.Y <= bottomEdge)
{
DataGridRow targetRow = DataGrid.HitTest(dropPoint).VisualHit.GetParentOfType<DataGridRow>();
if (targetRow != null && targetRow != _draggedRow)
{
int oldIndex = DataGrid.Items.IndexOf(_draggedRow.Item);
int newIndex = DataGrid.Items.IndexOf(targetRow.Item);
if (oldIndex < newIndex)
{
DataGrid.Items.Insert(newIndex + 1, _draggedRow.Item);
DataGrid.Items.RemoveAt(oldIndex);
}
else
{
DataGrid.Items.RemoveAt(oldIndex);
DataGrid.Items.Insert(newIndex, _draggedRow.Item);
}
_draggedRow.IsSelected = true;
DataGrid.SelectedItem = _draggedRow.Item;
}
}
}
}
private void DataGrid_Drop(object sender, DragEventArgs e)
{
_draggedRow = null;
}
```
注意,以上代码中使用了 GetParentOfType 扩展方法,用于查找指定元素的父级元素中第一个指定类型的元素。可以在代码中添加以下代码实现该扩展方法:
```csharp
public static T GetParentOfType<T>(this DependencyObject element) where T : DependencyObject
{
while (element != null && !(element is T))
{
element = VisualTreeHelper.GetParent(element);
}
return element as T;
}
```
最后,可以根据需要自定义拖拽用的 Thumb 控件的样式,例如在 XAML 中添加以下代码:
```xaml
<Thumb x:Name="PART_DragThumb" Width="8" Height="8" Background="Transparent"
DragDelta="PART_DragThumb_DragDelta">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="Gray" CornerRadius="4"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
```
这样就可以自定义拖拽用的 Thumb 控件的样式了。
阅读全文