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.
![img1.jpg]()
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.
![img2.jpg]()
Image 2.
Drag and drop selected row to other place.
![img3.jpg]()
Image 3.
See now books row is under the computer row.