【问题标题】:MouseMove event prevents ComboBox being "opened"MouseMove 事件防止 ComboBox 被“打开”
【发布时间】:2015-09-08 08:40:56
【问题描述】:

我跟随this tutorial 在我的数据网格上实现拖放。我根据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修改了项目我曾经显示我遇到的问题:Download from my dropbox 我将 Salary 列更改为组合框(当然还添加了 Grouping,因为我认为它可能很重要)

【问题讨论】:

  • 如果您可以发布一个显示问题的简约项目,那就太好了,否则按照您完成的所有教程来重现您的错误非常耗时。
  • 好的,我会这样做,但这需要一些时间(我无法上传完整的项目,因为这是我自己的代码)。
  • 那么,进展如何?
  • @netaholic 现在添加它:)

标签: c# wpf combobox datagrid mousemove


【解决方案1】:

首先,问题是什么。

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 它的代码更简洁,看起来更好。 我相信通过一些调整,您可以使其与组一起使用。

【讨论】:

  • 真的很酷!我认为它可能是这样的(MouseMove 被解雇而不移动),但这对我来说没有意义......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多