I am trying to make an attached behavior to reorder rows bby doing Drag & Drop
I found some solution (On Stackoverflow and by googling) and using them i am trying to make the behavior... I took the example from Hordcodenet website (i dont have the link now)
Code
public static class DragDropRowBehavior
{
private static DataGrid dataGrid;
private static Popup popup;
private static bool enable;
private static object draggedItem;
public static object DraggedItem
{
get { return DragDropRowBehavior.draggedItem; }
set { DragDropRowBehavior.draggedItem = value; }
}
public static Popup GetPopupControl(DependencyObject obj)
{
return (Popup)obj.GetValue(PopupControlProperty);
}
public static void SetPopupControl(DependencyObject obj, Popup value)
{
obj.SetValue(PopupControlProperty, value);
}
// Using a DependencyProperty as the backing store for PopupControl. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PopupControlProperty =
DependencyProperty.RegisterAttached("PopupControl", typeof(Popup), typeof(DragDropRowBehavior), new UIPropertyMetadata(null, OnPopupControlChanged));
private static void OnPopupControlChanged(DependencyObject depObject, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null || !(e.NewValue is Popup))
{
throw new ArgumentException("Popup Control should be set", "PopupControl");
}
popup = e.NewValue as Popup;
dataGrid = depObject as DataGrid;
// Check if DataGrid
if (dataGrid == null)
return;
if (enable && popup != null)
{
dataGrid.BeginningEdit += new EventHandler<DataGridBeginningEditEventArgs>(OnBeginEdit);
dataGrid.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(OnEndEdit);
dataGrid.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(OnMouseLeftButtonUp);
dataGrid.MouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
dataGrid.MouseMove += new MouseEventHandler(OnMouseMove);
}
else
{
dataGrid.BeginningEdit -= new EventHandler<DataGridBeginningEditEventArgs>(OnBeginEdit);
dataGrid.CellEditEnding -= new EventHandler<DataGridCellEditEndingEventArgs>(OnEndEdit);
dataGrid.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(OnMouseLeftButtonUp);
dataGrid.MouseLeftButtonDown -= new MouseButtonEventHandler(OnMouseLeftButtonDown);
dataGrid.MouseMove -= new MouseEventHandler(OnMouseMove);
dataGrid = null;
popup = null;
draggedItem = null;
IsEditing = false;
IsDragging = false;
}
}
public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(EnabledProperty);
}
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
}
// Using a DependencyProperty as the backing store for Enabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(DragDropRowBehavior), new UIPropertyMetadata(false,OnEnabledChanged));
private static void OnEnabledChanged(DependencyObject depObject,DependencyPropertyChangedEventArgs e)
{
//Check if value is a Boolean Type
if (e.NewValue is bool == false)
throw new ArgumentException("Value should be of bool type", "Enabled");
enable = (bool)e.NewValue;
}
public static bool IsEditing { get; set; }
public static bool IsDragging { get; set; }
private static void OnBeginEdit(object sender, DataGridBeginningEditEventArgs e)
{
IsEditing = true;
//in case we are in the middle of a drag/drop operation, cancel it...
if (IsDragging) ResetDragDrop();
}
private static void OnEndEdit(object sender, DataGridCellEditEndingEventArgs e)
{
IsEditing = false;
}
/// <summary>
/// Initiates a drag action if the grid is not in edit mode.
/// </summary>
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (IsEditing) return;
var row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement)sender, e.GetPosition(dataGrid));
if (row == null || row.IsEditing) return;
//set flag that indicates we're capturing mouse movements
IsDragging = true;
DraggedItem = row.Item;
}
/// <summary>
/// Completes a drag/drop operation.
/// </summary>
private static void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!IsDragging || IsEditing)
{
return;
}
//get the target item
var targetItem = dataGrid.SelectedItem;
if (targetItem == null || !ReferenceEquals(DraggedItem, targetItem))
{
//remove the source from the list
((dataGrid).ItemsSource as IList).Remove(DraggedItem);
//get target index
var targetIndex = ((dataGrid).ItemsSource as IList).IndexOf(targetItem);
//move source at the target's location
((dataGrid).ItemsSource as IList).Insert(targetIndex, DraggedItem);
//select the dropped item
dataGrid.SelectedItem = DraggedItem;
}
//reset
ResetDragDrop();
}
/// <summary>
/// Closes the popup and resets the
/// grid to read-enabled mode.
/// </summary>
private static void ResetDragDrop()
{
IsDragging = false;
popup.IsOpen = false;
dataGrid.IsReadOnly = false;
}
/// <summary>
/// Updates the popup's position in case of a drag/drop operation.
/// </summary>
private static void OnMouseMove(object sender, MouseEventArgs e)
{
if (!IsDragging || e.LeftButton != MouseButtonState.Pressed) return;
//display the popup if it hasn't been opened yet
if (!popup.IsOpen)
{
//switch to read-only mode
dataGrid.IsReadOnly = true;
//make sure the popup is visible
popup.IsOpen = true;
}
Size popupSize = new Size(popup.ActualWidth, popup.ActualHeight);
popup.PlacementRectangle = new Rect(e.GetPosition(dataGrid), popupSize);
//make sure the row under the grid is being selected
Point position = e.GetPosition(dataGrid);
var row = UIHelpers.TryFindFromPoint<DataGridRow>(dataGrid, position);
if (row != null) dataGrid.SelectedItem = row.Item;
}
}
Helper Class
///
/// Common UI related helper methods.
///
public static class UIHelpers
{
#region find parent
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Do note, that for content element,
/// this method falls back to the logical tree of the element.
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(DependencyObject child)
{
if (child == null) return null;
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//if it's not a ContentElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
#endregion
#region update binding sources
/// <summary>
/// Recursively processes a given dependency object and all its
/// children, and updates sources of all objects that use a
/// binding expression on a given property.
/// </summary>
/// <param name="obj">The dependency object that marks a starting
/// point. This could be a dialog window or a panel control that
/// hosts bound controls.</param>
/// <param name="properties">The properties to be updated if
/// <paramref name="obj"/> or one of its childs provide it along
/// with a binding expression.</param>
public static void UpdateBindingSources(DependencyObject obj,
params DependencyProperty[] properties)
{
foreach (DependencyProperty depProperty in properties)
{
//check whether the submitted object provides a bound property
//that matches the property parameters
BindingExpression be = BindingOperations.GetBindingExpression(obj, depProperty);
if (be != null) be.UpdateSource();
}
int count = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i < count; i++)
{
//process child items recursively
DependencyObject childObject = VisualTreeHelper.GetChild(obj, i);
UpdateBindingSources(childObject, properties);
}
}
#endregion
/// <summary>
/// Tries to locate a given item within the visual tree,
/// starting with the dependency object at a given position.
/// </summary>
/// <typeparam name="T">The type of the element to be found
/// on the visual tree of the element at the given location.</typeparam>
/// <param name="reference">The main element which is used to perform
/// hit testing.</param>
/// <param name="point">The position to be evaluated on the origin.</param>
public static T TryFindFromPoint<T>(UIElement reference, Point point)
where T : DependencyObject
{
DependencyObject element = reference.InputHitTest(point)
as DependencyObject;
if (element == null) return null;
else if (element is T) return (T)element;
else return TryFindParent<T>(element);
}
}
Problem is that the Event OnMouseLeftButtonDown
is not called when i press it over a row to drag it... but OnMouseLeftButtonUp
is called after that....
Is there ne way to do this....
I cant seem to find a way
Finally i got the Problem and also made some changes for this to work properly
I used this example to make the Drag Drop Logic
amd made this behavior may be its use ful to others .... please suggest improvements i would be happy to change ...
Behavior
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using Microsoft.Windows.Controls;
using System.Windows.Input;
using System.Collections;
namespace DataGridDragAndDrop
{
public static class DragDropRowBehavior
{
private static DataGrid dataGrid;
private static Popup popup;
private static bool enable;
private static object draggedItem;
public static object DraggedItem
{
get { return DragDropRowBehavior.draggedItem; }
set { DragDropRowBehavior.draggedItem = value; }
}
public static Popup GetPopupControl(DependencyObject obj)
{
return (Popup)obj.GetValue(PopupControlProperty);
}
public static void SetPopupControl(DependencyObject obj, Popup value)
{
obj.SetValue(PopupControlProperty, value);
}
// Using a DependencyProperty as the backing store for PopupControl. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PopupControlProperty =
DependencyProperty.RegisterAttached("PopupControl", typeof(Popup), typeof(DragDropRowBehavior), new UIPropertyMetadata(null, OnPopupControlChanged));
private static void OnPopupControlChanged(DependencyObject depObject, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null || !(e.NewValue is Popup))
{
throw new ArgumentException("Popup Control should be set", "PopupControl");
}
popup = e.NewValue as Popup;
dataGrid = depObject as DataGrid;
// Check if DataGrid
if (dataGrid == null)
return;
if (enable && popup != null)
{
dataGrid.BeginningEdit += new EventHandler<DataGridBeginningEditEventArgs>(OnBeginEdit);
dataGrid.CellEditEnding += new EventHandler<DataGridCellEditEndingEventArgs>(OnEndEdit);
dataGrid.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(OnMouseLeftButtonUp);
dataGrid.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
dataGrid.MouseMove += new MouseEventHandler(OnMouseMove);
}
else
{
dataGrid.BeginningEdit -= new EventHandler<DataGridBeginningEditEventArgs>(OnBeginEdit);
dataGrid.CellEditEnding -= new EventHandler<DataGridCellEditEndingEventArgs>(OnEndEdit);
dataGrid.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(OnMouseLeftButtonUp);
dataGrid.MouseLeftButtonDown -= new MouseButtonEventHandler(OnMouseLeftButtonDown);
dataGrid.MouseMove -= new MouseEventHandler(OnMouseMove);
dataGrid = null;
popup = null;
draggedItem = null;
IsEditing = false;
IsDragging = false;
}
}
public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(EnabledProperty);
}
public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
}
// Using a DependencyProperty as the backing store for Enabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(DragDropRowBehavior), new UIPropertyMetadata(false,OnEnabledChanged));
private static void OnEnabledChanged(DependencyObject depObject,DependencyPropertyChangedEventArgs e)
{
//Check if value is a Boolean Type
if (e.NewValue is bool == false)
throw new ArgumentException("Value should be of bool type", "Enabled");
enable = (bool)e.NewValue;
}
public static bool IsEditing { get; set; }
public static bool IsDragging { get; set; }
private static void OnBeginEdit(object sender, DataGridBeginningEditEventArgs e)
{
IsEditing = true;
//in case we are in the middle of a drag/drop operation, cancel it...
if (IsDragging) ResetDragDrop();
}
private static void OnEndEdit(object sender, DataGridCellEditEndingEventArgs e)
{
IsEditing = false;
}
/// <summary>
/// Initiates a drag action if the grid is not in edit mode.
/// </summary>
private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (IsEditing) return;
var row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement)sender, e.GetPosition(dataGrid));
if (row == null || row.IsEditing) return;
//set flag that indicates we're capturing mouse movements
IsDragging = true;
DraggedItem = row.Item;
}
/// <summary>
/// Completes a drag/drop operation.
/// </summary>
private static void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!IsDragging || IsEditing)
{
return;
}
//get the target item
var targetItem = dataGrid.SelectedItem;
if (targetItem == null || !ReferenceEquals(DraggedItem, targetItem))
{
//get target index
var targetIndex = ((dataGrid).ItemsSource as IList).IndexOf(targetItem);
//remove the source from the list
((dataGrid).ItemsSource as IList).Remove(DraggedItem);
//move source at the target's location
((dataGrid).ItemsSource as IList).Insert(targetIndex, DraggedItem);
//select the dropped item
dataGrid.SelectedItem = DraggedItem;
}
//reset
ResetDragDrop();
}
/// <summary>
/// Closes the popup and resets the
/// grid to read-enabled mode.
/// </summary>
private static void ResetDragDrop()
{
IsDragging = false;
popup.IsOpen = false;
dataGrid.IsReadOnly = false;
}
/// <summary>
/// Updates the popup's position in case of a drag/drop operation.
/// </summary>
private static void OnMouseMove(object sender, MouseEventArgs e)
{
if (!IsDragging || e.LeftButton != MouseButtonState.Pressed) return;
popup.DataContext = DraggedItem;
//display the popup if it hasn't been opened yet
if (!popup.IsOpen)
{
//switch to read-only mode
dataGrid.IsReadOnly = true;
//make sure the popup is visible
popup.IsOpen = true;
}
Size popupSize = new Size(popup.ActualWidth, popup.ActualHeight);
popup.PlacementRectangle = new Rect(e.GetPosition(dataGrid), popupSize);
//make sure the row under the grid is being selected
Point position = e.GetPosition(dataGrid);
var row = UIHelpers.TryFindFromPoint<DataGridRow>(dataGrid, position);
if (row != null) dataGrid.SelectedItem = row.Item;
}
}
}
UIHelper Class
public static class UIHelpers
{
#region find parent
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
else
{
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Do note, that for content element,
/// this method falls back to the logical tree of the element.
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(DependencyObject child)
{
if (child == null) return null;
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//if it's not a ContentElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
#endregion
#region update binding sources
/// <summary>
/// Recursively processes a given dependency object and all its
/// children, and updates sources of all objects that use a
/// binding expression on a given property.
/// </summary>
/// <param name="obj">The dependency object that marks a starting
/// point. This could be a dialog window or a panel control that
/// hosts bound controls.</param>
/// <param name="properties">The properties to be updated if
/// <paramref name="obj"/> or one of its childs provide it along
/// with a binding expression.</param>
public static void UpdateBindingSources(DependencyObject obj,
params DependencyProperty[] properties)
{
foreach (DependencyProperty depProperty in properties)
{
//check whether the submitted object provides a bound property
//that matches the property parameters
BindingExpression be = BindingOperations.GetBindingExpression(obj, depProperty);
if (be != null) be.UpdateSource();
}
int count = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i < count; i++)
{
//process child items recursively
DependencyObject childObject = VisualTreeHelper.GetChild(obj, i);
UpdateBindingSources(childObject, properties);
}
}
#endregion
/// <summary>
/// Tries to locate a given item within the visual tree,
/// starting with the dependency object at a given position.
/// </summary>
/// <typeparam name="T">The type of the element to be found
/// on the visual tree of the element at the given location.</typeparam>
/// <param name="reference">The main element which is used to perform
/// hit testing.</param>
/// <param name="point">The position to be evaluated on the origin.</param>
public static T TryFindFromPoint<T>(UIElement reference, Point point)
where T : DependencyObject
{
DependencyObject element = reference.InputHitTest(point)
as DependencyObject;
if (element == null) return null;
else if (element is T) return (T)element;
else return TryFindParent<T>(element);
}
}
Usage
<!-- Drag and Drop Popup -->
<Popup x:Name="popup1"
AllowsTransparency="True"
IsHitTestVisible="False"
Placement="RelativePoint"
PlacementTarget="{Binding ElementName=shareGrid}">
<!-- Your own Popup construction Use properties of DraggedObject inside for Binding -->
<TextBlock Margin="8,0,0,0"
VerticalAlignment="Center"
FontSize="14"
FontWeight="Bold"
<!-- I used name property of in my Dragged row -->
Text="{Binding Path=Name}" />
</Popup>
<DataGrid x:Name="myDataGrid"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserSortColumns="False"
ItemsSource="{Binding}"
SelectionMode="Single"
this:DragDropRowBehavior.Enabled="True"
this:DragDropRowBehavior.PopupControl="{Binding ElementName=popup1}"></DataGrid >
if the event is not fired at the desired object, it is because some other control is "swallowing" it. Try to use OnPreviewMouseLeftButtonDown instead. If preview is not showing the event, try to move that preview method to a parent class.
I've created a behavior out of @Dave solution:
public class DragDropRowBehavior : Behavior<DataGrid>
{
private object draggedItem;
private bool isEditing;
private bool isDragging;
#region DragEnded
public static readonly RoutedEvent DragEndedEvent =
EventManager.RegisterRoutedEvent("DragEnded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DragDropRowBehavior));
public static void AddDragEndedHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uie = d as UIElement;
if (uie != null)
uie.AddHandler(DragDropRowBehavior.DragEndedEvent, handler);
}
public static void RemoveDragEndedHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uie = d as UIElement;
if (uie != null)
uie.RemoveHandler(DragDropRowBehavior.DragEndedEvent, handler);
}
private void RaiseDragEndedEvent()
{
var args = new RoutedEventArgs(DragDropRowBehavior.DragEndedEvent);
AssociatedObject.RaiseEvent(args);
}
#endregion
#region Popup
public static readonly DependencyProperty PopupProperty =
DependencyProperty.Register("Popup", typeof(System.Windows.Controls.Primitives.Popup), typeof(DragDropRowBehavior));
public System.Windows.Controls.Primitives.Popup Popup
{
get { return (System.Windows.Controls.Primitives.Popup)GetValue(PopupProperty); }
set { SetValue(PopupProperty, value); }
}
#endregion
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.BeginningEdit += OnBeginEdit;
AssociatedObject.CellEditEnding += OnEndEdit;
AssociatedObject.MouseLeftButtonUp += OnMouseLeftButtonUp;
AssociatedObject.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
AssociatedObject.MouseMove += OnMouseMove;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.BeginningEdit -= OnBeginEdit;
AssociatedObject.CellEditEnding -= OnEndEdit;
AssociatedObject.MouseLeftButtonUp -= OnMouseLeftButtonUp;
AssociatedObject.MouseLeftButtonDown -= OnMouseLeftButtonDown;
AssociatedObject.MouseMove -= OnMouseMove;
Popup = null;
draggedItem = null;
isEditing = false;
isDragging = false;
}
private void OnBeginEdit(object sender, DataGridBeginningEditEventArgs e)
{
isEditing = true;
//in case we are in the middle of a drag/drop operation, cancel it...
if (isDragging) ResetDragDrop();
}
private void OnEndEdit(object sender, DataGridCellEditEndingEventArgs e)
{
isEditing = false;
}
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (isEditing) return;
var row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement)sender, e.GetPosition(AssociatedObject));
if (row == null || row.IsEditing) return;
//set flag that indicates we're capturing mouse movements
isDragging = true;
draggedItem = row.Item;
}
private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (!isDragging || isEditing)
return;
//get the target item
var targetItem = AssociatedObject.SelectedItem;
if (targetItem == null || !ReferenceEquals(draggedItem, targetItem))
{
//get target index
var targetIndex = ((AssociatedObject).ItemsSource as IList).IndexOf(targetItem);
//remove the source from the list
((AssociatedObject).ItemsSource as IList).Remove(draggedItem);
//move source at the target's location
((AssociatedObject).ItemsSource as IList).Insert(targetIndex, draggedItem);
//select the dropped item
AssociatedObject.SelectedItem = draggedItem;
RaiseDragEndedEvent();
}
//reset
ResetDragDrop();
}
private void ResetDragDrop()
{
isDragging = false;
Popup.IsOpen = false;
AssociatedObject.IsReadOnly = false;
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
if (!isDragging || e.LeftButton != MouseButtonState.Pressed)
return;
Popup.DataContext = draggedItem;
//display the popup if it hasn't been opened yet
if (!Popup.IsOpen)
{
//switch to read-only mode
AssociatedObject.IsReadOnly = true;
//make sure the popup is visible
Popup.IsOpen = true;
}
var popupSize = new Size(Popup.ActualWidth, Popup.ActualHeight);
Popup.PlacementRectangle = new Rect(e.GetPosition(AssociatedObject), popupSize);
//make sure the row under the grid is being selected
var position = e.GetPosition(AssociatedObject);
var row = UIHelpers.TryFindFromPoint<DataGridRow>(AssociatedObject, position);
if (row != null) AssociatedObject.SelectedItem = row.Item;
}
}
Hope it helps the future users :)