You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编辑模式下禁用DataGrid单元格内的拖放功能

问题解决思路与方案

你的核心问题是DataGrid单元格编辑时误触发拖放,以及多次点击引发的异常,根源在于MouseMove事件没有区分「点击编辑」和「拖动操作」,且编辑状态下的TextBox默认允许拖放。以下是针对性的解决步骤:

1. 区分拖动与点击,增加拖放阈值

通过记录鼠标按下的初始位置,只有当鼠标移动超过系统最小拖动距离时才触发拖放,避免点击编辑时误触发。

步骤1:添加MouseDown事件记录起点

在DataGridRow的Style中添加MouseDown事件绑定:

<Style TargetType="DataGridRow">
    <EventSetter Event="MouseDoubleClick" Handler="DGBottleListRow_DoubleClick"/>
    <EventSetter Event="MouseMove" Handler="DGBottleListRow_MouseMove"/>
    <EventSetter Event="MouseDown" Handler="DGBottleListRow_MouseDown"/>
</Style>

步骤2:后台记录并判断拖动距离

在窗口类中添加私有变量记录起点,修改MouseMove事件:

private Point _dragStartPoint;

protected void DGBottleListRow_MouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
        _dragStartPoint = e.GetPosition(null);
}

protected void DGBottleListRow_MouseMove(object sender, MouseEventArgs e)
{
    if (sender is not DataGridRow row)
        return;

    // 编辑状态下直接跳过拖放逻辑
    if (row.IsEditing || DGBottleList.IsEditing)
        return;

    if (row.Item is not WineBottle movedBottle)
        return;

    if (e.LeftButton == MouseButtonState.Pressed)
    {
        Point currentPoint = e.GetPosition(null);
        // 超过系统最小拖动距离才触发拖放
        if (Math.Abs(currentPoint.X - _dragStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
            Math.Abs(currentPoint.Y - _dragStartPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
        {
            DragDrop.DoDragDrop(row, movedBottle.ID.ToString(), DragDropEffects.Move);
        }
    }
}

2. 禁用编辑控件的拖放行为

DataGrid进入编辑状态时,单元格内的TextBox默认允许拖放,需要显式禁用:

为可编辑列设置EditingElementStyle

对所有非ReadOnly的DataGridTextColumn添加编辑样式:

<DataGridTextColumn Header="Name"     
                    Binding="{Binding Name}"     
                    Width="SizeToCells" 
                    MinWidth="45">
    <DataGridTextColumn.EditingElementStyle>
        <Style TargetType="TextBox">
            <Setter Property="AllowDrop" Value="False"/>
            <EventSetter Event="PreviewDragOver" Handler="TextBox_PreviewDragOver"/>
            <EventSetter Event="PreviewDrop" Handler="TextBox_PreviewDrop"/>
        </Style>
    </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<!-- 其他可编辑列(Vineyard、Vintage、Varietal、Region)同样添加此样式 -->

后台阻止拖放事件

添加事件处理确保拖放操作被完全阻止:

protected void TextBox_PreviewDragOver(object sender, DragEventArgs e)
{
    e.Handled = true;
}

protected void TextBox_PreviewDrop(object sender, DragEventArgs e)
{
    e.Handled = true;
}

3. 额外异常防护

在拖放方法外层添加try-catch,避免多次触发导致未处理异常:

if (Math.Abs(currentPoint.X - _dragStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
    Math.Abs(currentPoint.Y - _dragStartPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
{
    try
    {
        DragDrop.DoDragDrop(row, movedBottle.ID.ToString(), DragDropEffects.Move);
    }
    catch (Exception ex)
    {
        // 可记录日志或静默处理,避免程序崩溃
        Debug.WriteLine($"拖放异常:{ex.Message}");
    }
}

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:25:59