This article explains how to drag and drop selected DataGrid row in WPF.
Getting Started:
Creating WPF Project. Open Visual Studio 2010.
Go to File => New => Project
Select Window in installed templates
Select WPF Application
Enter the Name and choose the location.
Click OK
First of all add a new class using add new item tab and rename that class name.
using
System.Collections.ObjectModel;
public
class Product
{
public int
ProductId { get; set;
}
public string
ProductName { get; set;
}
public string
ProductPrice { get; set;
}
}
public class
ProductCollection : ObservableCollection<Product>
{
public ProductCollection()
{
Add(new
Product() { ProductId = 111, ProductName =
"Books", ProductPrice = "500$" });
Add(new
Product() { ProductId = 222, ProductName =
"Cameras", ProductPrice = "600$" });
Add(new
Product() { ProductId = 333, ProductName =
"Cell Phones", ProductPrice = "700$"
});
Add(new
Product() { ProductId = 444, ProductName =
"Clothing", ProductPrice = "800$" });
Add(new
Product() { ProductId = 555, ProductName =
"Shoes", ProductPrice = "900$" });
Add(new
Product() { ProductId = 666, ProductName =
"Gift Cards", ProductPrice = "500$"
});
Add(new
Product() { ProductId = 777, ProductName =
"Crafts", ProductPrice = "400$" });
Add(new
Product() { ProductId = 888, ProductName =
"Computers", ProductPrice = "430$" });
Add(new
Product() { ProductId = 999, ProductName =
"Coins", ProductPrice = "460$" });
Add(new
Product() { ProductId = 332, ProductName =
"Cars", ProductPrice = "4600$" });
Add(new
Product() { ProductId = 564, ProductName =
"Boats", ProductPrice = "3260$" });
Add(new
Product() { ProductId = 346, ProductName =
"Dolls", ProductPrice = "120$" });
Add(new
Product() { ProductId = 677, ProductName =
"Gift Cards", ProductPrice = "960$"
});
}
}
MainPage.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfRowDragDropSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="WpfRowDragDropSample.MainWindow"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<local:ProductCollection
x:Key="ProductList"/>
</Window.Resources>
<Grid
DataContext="{Binding
Source={StaticResource
ProductList}}">
<DataGrid
d:LayoutOverrides="Width"
Margin="0,28,0,0"
Name="productsDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding}"
SelectionMode="Extended"
ColumnWidth="*"
AllowDrop="True" >
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding
ProductId}"
Header="ProductId"></DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding
ProductName}"
Header="ProductName"></DataGridTextColumn>
<DataGridTextColumn
Binding="{Binding
ProductPrice}"
Header="ProductPrice"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<TextBlock
TextWrapping="Wrap"
Text="DataGrid
Row Drag And Drop Sample"
VerticalAlignment="Top"
Margin="3,1,0,0"
Height="24"
HorizontalAlignment="Left"
Width="268"
FontSize="14.667"
FontWeight="Bold"
FontStyle="Italic"/>
</Grid>
</Window>
MainPage.xaml.cs
using
System.Windows.Controls.Primitives;
public
delegate Point
GetPosition(IInputElement
element);
int rowIndex = -1;
public MainWindow()
{
InitializeComponent();
productsDataGrid.PreviewMouseLeftButtonDown +=
new
MouseButtonEventHandler(productsDataGrid_PreviewMouseLeftButtonDown);
productsDataGrid.Drop += new
DragEventHandler(productsDataGrid_Drop);
}
void productsDataGrid_Drop(object
sender, DragEventArgs e)
{
if (rowIndex < 0)
return;
int index =
this.GetCurrentRowIndex(e.GetPosition);
if (index < 0)
return;
if (index == rowIndex)
return;
if (index ==
productsDataGrid.Items.Count - 1)
{
MessageBox.Show("This
row-index cannot be drop");
return;
}
ProductCollection
productCollection = Resources["ProductList"]
as ProductCollection;
Product changedProduct =
productCollection[rowIndex];
productCollection.RemoveAt(rowIndex);
productCollection.Insert(index, changedProduct);
}
void
productsDataGrid_PreviewMouseLeftButtonDown(object
sender, MouseButtonEventArgs e)
{
rowIndex = GetCurrentRowIndex(e.GetPosition);
if (rowIndex < 0)
return;
productsDataGrid.SelectedIndex = rowIndex;
Product selectedEmp =
productsDataGrid.Items[rowIndex] as
Product;
if (selectedEmp ==
null)
return;
DragDropEffects dragdropeffects =
DragDropEffects.Move;
if (DragDrop.DoDragDrop(productsDataGrid,
selectedEmp, dragdropeffects)
!= DragDropEffects.None)
{
productsDataGrid.SelectedItem = selectedEmp;
}
}
private bool
GetMouseTargetRow(Visual theTarget,
GetPosition position)
{
Rect rect =
VisualTreeHelper.GetDescendantBounds(theTarget);
Point point = position((IInputElement)theTarget);
return rect.Contains(point);
}
private DataGridRow
GetRowItem(int index)
{
if (productsDataGrid.ItemContainerGenerator.Status
!= GeneratorStatus.ContainersGenerated)
return
null;
return
productsDataGrid.ItemContainerGenerator.ContainerFromIndex(index)
as DataGridRow;
}
private int
GetCurrentRowIndex(GetPosition pos)
{
int curIndex = -1;
for (int
i = 0; i < productsDataGrid.Items.Count; i++)
{
DataGridRow itm =
GetRowItem(i);
if (GetMouseTargetRow(itm, pos))
{
curIndex = i;
break;
}
}
return curIndex;
}
Run the application.
Image 1.
Now select a row to drop on place of other row like I select computers product
row to put on the top of the grid.
Image 2.
Drag and drop selected row to other place.
Image 3.
See now books row is under the computer row.