У меня есть таблица данных, в которой я использую DragAndDropBehavior для перемещения элементов вверх / вниз:
public class DataGridRowDragAndDropBehavior
{
public delegate Point GetPosition(IInputElement element);
int rowIndex = -1;
public static DependencyProperty DataGridDragAndDropEnabled =
DependencyProperty.RegisterAttached("DataGridDragAndDropEnabled", typeof(bool),
typeof(DataGridRowDragAndDropBehavior), new UIPropertyMetadata(false, OnDataGridDragAndDropEnabled));
private static void OnDataGridDragAndDropEnabled(object sender, DependencyPropertyChangedEventArgs e)
{
var dataGrid = (DataGrid) sender;
dataGrid.PreviewMouseLeftButtonDown += Instance.productsDataGrid_PreviewMouseLeftButtonDown;
dataGrid.Drop +=Instance.productsDataGrid_Drop;
}
public static bool GetDataGridDragAndDropEnabled(DependencyObject obj)
{
return (bool) obj.GetValue(DataGridDragAndDropEnabled);
}
public static void SetDataGridDragAndDropEnabled(DependencyObject obj, bool value)
{
obj.SetValue(DataGridDragAndDropEnabled, value);
}
private static DataGridRowDragAndDropBehavior instance = new DataGridRowDragAndDropBehavior();
public static DataGridRowDragAndDropBehavior Instance
{
get { return instance; }
set { instance = value; }
}
void productsDataGrid_Drop(object sender, DragEventArgs e)
{
var dataGrid = (DataGrid) sender;
var dataGridSource = (System.Collections.IList)dataGrid.ItemsSource;
if (rowIndex < 0)
return;
var index = GetCurrentRowIndex(e.GetPosition,dataGrid);
if (index < 0)
return;
if (index == rowIndex)
return;
//if (index == dataGrid.Items.Count - 1)
//{
// MessageBox.Show("This row-index cannot be drop");
// return;
//}
var changedItem = dataGridSource[rowIndex];
dataGridSource.RemoveAt(rowIndex);
dataGridSource.Insert(index, changedItem);
}
void productsDataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var dataGrid = (DataGrid) sender;
rowIndex = GetCurrentRowIndex(e.GetPosition,dataGrid);
if (rowIndex < 0)
return;
dataGrid.SelectedIndex = rowIndex;
Register selectedEmp = dataGrid.Items[rowIndex] as Register;
if (selectedEmp == null)
return;
DragDropEffects dragdropeffects = DragDropEffects.Move;
if (DragDrop.DoDragDrop(dataGrid, selectedEmp, dragdropeffects)
!= DragDropEffects.None)
{
dataGrid.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,DataGrid dataGrid)
{
if (dataGrid.ItemContainerGenerator.Status
!= GeneratorStatus.ContainersGenerated)
return null;
return dataGrid.ItemContainerGenerator.ContainerFromIndex(index)
as DataGridRow;
}
private int GetCurrentRowIndex(GetPosition pos,DataGrid dataGrid)
{
int curIndex = -1;
for (int i = 0; i < dataGrid.Items.Count; i++)
{
DataGridRow itm = GetRowItem(i,dataGrid);
if (GetMouseTargetRow(itm, pos))
{
curIndex = i;
break;
}
}
return curIndex;
}
}
Проблема в том, что в этой DataGrid у меня есть столбец с флажком:
<DataGridTemplateColumn Header="CheckBox Column" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox>My checkbox</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Поэтому из-за этого поведения флажок не отвечает (когда я отключаю DragAndDrop, он работает).
Я подозреваю, что это из-за того, что мое поведение обрабатывает событие click, которое никогда не передается на мой флажок.
Как я могу предотвратить это? Я пытался установить e.Handled = false
где-то в своем поведении, но это не сработало.
P.S Просто для ясности, я использую свое поведение таким образом:
<DataGrid behaviors:DataGridRowDragAndDropBehavior.DataGridDragAndDropEnabled="true">