MouseMove 事件阻止 ComboBox "opened"
MouseMove event prevents ComboBox being "opened"
我遵循 this tutorial to implement Drag&Drop on my datagrid. I changed it according to this link 以便能够在组之间移动元素。
我的数据网格包含一个带有按钮的列,因此我按照 this answer 使按钮再次可用。我还有 3 列带有 ComboBoxes,但它们无法使用(您可以单击它们,然后它们看起来像组合框,但第二次单击不会展开它)。
其中两个定义为 DataGridComboBoxColumn
,一个定义为 DataGridTemplateColumn
和 ComboBox
标签 DataGridTemplateColumn.CellEditingTemplate
.
前两个是这样的:
<DataGridComboBoxColumn Header="Entity"
ItemsSource="{StaticResource tl}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValueBinding="{Binding Entity}"
x:Name="cmbEntity"></DataGridComboBoxColumn>
DataGrid 的定义如下所示:
<DataGrid Grid.Row="1" Name="myGrid" IsManipulationEnabled="True" ItemsSource="{Binding Source={StaticResource cvs}}" AutoGenerateColumns="False"
RowEditEnding="myGrid_RowEditEnding" PreviewKeyDown="myGrid_PreviewKeyDown" SelectedCellsChanged="myGrid_SelectedCellsChanged"
AllowDrop="True" MouseMove="DataGrid_MouseMove" PreviewMouseLeftButtonDown="DataGrid_PreviewMouseLeftButtonDown" Drop="DataGridView_Drop">
和上面说的一样,方法都是按照教程实现的。我曾尝试在事件处理程序中使用 e.Handled=false
,但它没有帮助(而且它可能无用,因为打开组合框不是事件?)
通过至少一次删除一个事件处理程序,我发现 MouseMove 事件是问题所在,代码如下:
void DataGrid_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed) {
Console.Out.WriteLine("MouseButtonState.Pressed");
DataGrid dataGrid = sender as DataGrid;
prevRowIndex = GetDataGridItemCurrentRowIndex(dataGrid, e.GetPosition);
if (prevRowIndex < 0) { return;}
dataGrid.SelectedIndex = prevRowIndex;
DefaultValue selectedDV = dataGrid.Items[prevRowIndex] as DefaultValue;
if (selectedDV == null) { return; }
DragDropEffects dragDropEffects = DragDropEffects.Move;
if (DragDrop.DoDragDrop(dataGrid, selectedDV, dragDropEffects) != DragDropEffects.None)
{
dataGrid.SelectedItem = selectedDV;
}
}
}
我不完全明白为什么会这样,因为我并没有真正移动鼠标,我只是点击包含组合框的单元格。是否有可能同时拥有拖放和组合框?
编辑: 我从 the tutorial I used to show the problem I have: Download from my dropbox 修改了项目
我将 Salary 列更改为组合框(当然还添加了分组,因为我认为这可能很重要)
首先,问题是什么。
即使在没有移动鼠标的情况下单击鼠标,也会触发 MouseMove 事件。快速搜索表明这是有意的行为。
然后 datagrid 会尝试将单击的单元格置于编辑模式,但鼠标移动事件代码会调用 DragDrop.DoDragDrop
阻止组合框出现。
我建议的解决方法是执行以下操作:
在主窗口中定义:
Point mousePositionOnButtonPress;
double deltaToStartDrag = 10;
并将您的 MouseMove 事件修改为以下内容:
if (e.LeftButton == MouseButtonState.Pressed)
{
var position = e.GetPosition(this);
if (mousePositionOnButtonPress == new Point())
{
mousePositionOnButtonPress = new Point(position.X, position.Y);
}
else
if (Math.Abs(mousePositionOnButtonPress.X - position.X) > deltaToStartDrag || Math.Abs(mousePositionOnButtonPress.Y - position.Y) > deltaToStartDrag)
{
Console.Out.WriteLine("MouseButtonState.Pressed");
DataGrid dataGrid = sender as DataGrid;
prevRowIndex = GetDataGridItemCurrentRowIndex(dataGrid, e.GetPosition);
if (prevRowIndex < 0) { return; }
dataGrid.SelectedIndex = prevRowIndex;
Employee selectedDV = dataGrid.Items[prevRowIndex] as Employee;
if (selectedDV == null) { return; }
DragDropEffects dragDropEffects = DragDropEffects.Move;
if (DragDrop.DoDragDrop(dataGrid, selectedDV, dragDropEffects) != DragDropEffects.None)
{
dataGrid.SelectedItem = selectedDV;
}
}
//
}
同时订阅 DataGrid 的 MouseUp 事件如下
private void dgEmployee_MouseUp(object sender, MouseButtonEventArgs e)
{
mousePositionOnButtonPress = new Point();
}
这将推迟拖放的开始,直到用户移动他的鼠标按下最多 10 个像素。
关于您的问题,这就是我要说的。
我也建议你看看这篇文章 http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop
IMO 它有更简洁的代码并且看起来更好。
我相信通过一些调整,您可以使其适用于群组。
我遵循 this tutorial to implement Drag&Drop on my datagrid. I changed it according to this link 以便能够在组之间移动元素。
我的数据网格包含一个带有按钮的列,因此我按照 this answer 使按钮再次可用。我还有 3 列带有 ComboBoxes,但它们无法使用(您可以单击它们,然后它们看起来像组合框,但第二次单击不会展开它)。
其中两个定义为 DataGridComboBoxColumn
,一个定义为 DataGridTemplateColumn
和 ComboBox
标签 DataGridTemplateColumn.CellEditingTemplate
.
前两个是这样的:
<DataGridComboBoxColumn Header="Entity"
ItemsSource="{StaticResource tl}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValueBinding="{Binding Entity}"
x:Name="cmbEntity"></DataGridComboBoxColumn>
DataGrid 的定义如下所示:
<DataGrid Grid.Row="1" Name="myGrid" IsManipulationEnabled="True" ItemsSource="{Binding Source={StaticResource cvs}}" AutoGenerateColumns="False"
RowEditEnding="myGrid_RowEditEnding" PreviewKeyDown="myGrid_PreviewKeyDown" SelectedCellsChanged="myGrid_SelectedCellsChanged"
AllowDrop="True" MouseMove="DataGrid_MouseMove" PreviewMouseLeftButtonDown="DataGrid_PreviewMouseLeftButtonDown" Drop="DataGridView_Drop">
和上面说的一样,方法都是按照教程实现的。我曾尝试在事件处理程序中使用 e.Handled=false
,但它没有帮助(而且它可能无用,因为打开组合框不是事件?)
通过至少一次删除一个事件处理程序,我发现 MouseMove 事件是问题所在,代码如下:
void DataGrid_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed) {
Console.Out.WriteLine("MouseButtonState.Pressed");
DataGrid dataGrid = sender as DataGrid;
prevRowIndex = GetDataGridItemCurrentRowIndex(dataGrid, e.GetPosition);
if (prevRowIndex < 0) { return;}
dataGrid.SelectedIndex = prevRowIndex;
DefaultValue selectedDV = dataGrid.Items[prevRowIndex] as DefaultValue;
if (selectedDV == null) { return; }
DragDropEffects dragDropEffects = DragDropEffects.Move;
if (DragDrop.DoDragDrop(dataGrid, selectedDV, dragDropEffects) != DragDropEffects.None)
{
dataGrid.SelectedItem = selectedDV;
}
}
}
我不完全明白为什么会这样,因为我并没有真正移动鼠标,我只是点击包含组合框的单元格。是否有可能同时拥有拖放和组合框?
编辑: 我从 the tutorial I used to show the problem I have: Download from my dropbox 修改了项目 我将 Salary 列更改为组合框(当然还添加了分组,因为我认为这可能很重要)
首先,问题是什么。
即使在没有移动鼠标的情况下单击鼠标,也会触发 MouseMove 事件。快速搜索表明这是有意的行为。
然后 datagrid 会尝试将单击的单元格置于编辑模式,但鼠标移动事件代码会调用 DragDrop.DoDragDrop
阻止组合框出现。
我建议的解决方法是执行以下操作:
在主窗口中定义:
Point mousePositionOnButtonPress;
double deltaToStartDrag = 10;
并将您的 MouseMove 事件修改为以下内容:
if (e.LeftButton == MouseButtonState.Pressed)
{
var position = e.GetPosition(this);
if (mousePositionOnButtonPress == new Point())
{
mousePositionOnButtonPress = new Point(position.X, position.Y);
}
else
if (Math.Abs(mousePositionOnButtonPress.X - position.X) > deltaToStartDrag || Math.Abs(mousePositionOnButtonPress.Y - position.Y) > deltaToStartDrag)
{
Console.Out.WriteLine("MouseButtonState.Pressed");
DataGrid dataGrid = sender as DataGrid;
prevRowIndex = GetDataGridItemCurrentRowIndex(dataGrid, e.GetPosition);
if (prevRowIndex < 0) { return; }
dataGrid.SelectedIndex = prevRowIndex;
Employee selectedDV = dataGrid.Items[prevRowIndex] as Employee;
if (selectedDV == null) { return; }
DragDropEffects dragDropEffects = DragDropEffects.Move;
if (DragDrop.DoDragDrop(dataGrid, selectedDV, dragDropEffects) != DragDropEffects.None)
{
dataGrid.SelectedItem = selectedDV;
}
}
//
}
同时订阅 DataGrid 的 MouseUp 事件如下
private void dgEmployee_MouseUp(object sender, MouseButtonEventArgs e)
{
mousePositionOnButtonPress = new Point();
}
这将推迟拖放的开始,直到用户移动他的鼠标按下最多 10 个像素。
关于您的问题,这就是我要说的。 我也建议你看看这篇文章 http://www.hardcodet.net/2009/03/moving-data-grid-rows-using-drag-and-drop IMO 它有更简洁的代码并且看起来更好。 我相信通过一些调整,您可以使其适用于群组。