【问题标题】:Reject drag/drop based on object data?根据对象数据拒绝拖放?
【发布时间】:2011-12-02 12:40:33
【问题描述】:

我修改了 c# DataGridViews,以便我可以在它们之间拖放行。我需要弄清楚如何禁用某些行的拖动,或拒绝这些行的拖放。我使用的标准是数据行中的一个值。

我想禁用该行(将其变灰且不允许拖动)作为我的第一选择。

我有什么选择?如何根据条件禁用或拒绝拖放?

【问题讨论】:

  • 拖动后能否查看行的索引?这就是诀窍
  • @Mr.DDD -你能详细说明一下吗?你有什么建议?
  • 你在其他人之间拖行,不是吗?好吧,如果您可以检查被拖动的行的索引(即新行将在其旁边的行),您可以接受/拒绝拖动。这取决于行数。
  • @Mr.DDD - 我还是不明白。该行的索引不是我要过滤的条件。
  • 您的标准是a value in the datarow。好的,使用行索引,您可以访问您的value on the row 并检查它。

标签: c# winforms user-interface drag-and-drop


【解决方案1】:

如果你想完全防止一行被拖动,请改用以下方法:

void dataGridView1_DragEnter(object sender, DragEventArgs e)
{
    DataGridViewRow row = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow)); // Get the row that is being dragged.
    if (row.Cells[0].Value.ToString() == "no_drag") // Check the value of the row.
        e.Effect = DragDropEffects.None; // Prevent the drag.
    else
        e.Effect = DragDropEffects.Move; // Allow the drag.
}

在这里,我假设您通过执行以下操作开始拖动操作:

DoDragDrop(dataGridView1.SelectedRows[0], DragDropEffects.Move);

在这种情况下,你当然不需要使用我之前回答的方法。

【讨论】:

  • -dataGridView1 是哪里的源网格(行开始的地方)?还是您的示例中的目的地?
  • -我仍然缺少一些东西。源网格的 DragEnter 事件永远不会被触发(因为我从未进入该网格)。 DragOver 和 DragLeave 也不起作用。
  • 起来,我的错。它应该是目标网格。我想我今天已经完成了足够多的编码;我越来越粗心了:)
  • 我没有使用如图所示的这个答案,但是这个答案是最有用的,并且帮助我找到了更好的方法。这行得通,但我觉得应该尽快阻止用户拖动行。我在源网格的 mouse_down 事件中设置了一些东西,以使用类似的代码立即停止拖动。
【解决方案2】:

这是一个可以帮助您入门的示例方法:

    void dataGridView1_DragOver(object sender, DragEventArgs e)
    {
        Point cp = PointToClient(new Point(e.X, e.Y)); // Get coordinates of the mouse relative to the datagridview.
        var dropped = dataGridView1.HitTest(cp.X, cp.Y); // Get the item under the mouse pointer.
        if (dataGridView1.Rows[dropped.RowIndex].Cells[0].Value.ToString() == "not_allowed") // Check the value.
            e.Effect = DragDropEffects.None; // Indicates dragging onto this item is not allowed.
        else
            e.Effect = DragDropEffects.Move; // Set the drag effect as required.
    }

当然,你应该这样使用它:

dataGridView1.DragOver += new DragEventHandler(dataGridView1_DragOver);

根据您的需要修改 if 子句中的条件。目前,如果第一个单元格值等于“not_allowed”,它会禁用拖动到一行。

【讨论】:

  • -我不太明白...我没有将任何东西拖到一行上,而是在 datagridviews 之间拖了整行。我不确定这如何应用?
  • @MAW74656 你在你的问题中说你想禁用拖动 on 某些行,这就是代码的作用。如果 B 具有特殊值,它会防止将 A 行拖到 B 行上。相反,您是否试图阻止 A 行被拖动(到任何地方)?
  • 正确,我想根据其中的某些值防止(完全)拖动行。
  • @MAW74656 那么请看我的下一个答案。为了清楚起见,您还可以考虑编辑您的问题。
【解决方案3】:

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.dodragdrop.aspx

可以重写 DragEnter 和 DragLeave 函数来实现

在 DragLeave 中 - 您可以根据选择查询您的对象,如果对象没有所需的值则取消操作

干杯

【讨论】:

  • -如何取消拖拽操作?
【解决方案4】:

可能有点晚了,但我今天遇到了同样的问题。我想防止在某些情况下拖动列表项。

我最终使用了 _ItemDrag 事件处理程序。在处理程序中,我检查了是否允许拖动项目,如果不是,我使用了 SendKeys.Send("{ESC}");命令取消拖动。

//Prevents dragging tree items that have at least one child item 
    private void lvTaxonomyItemLedgerAccounts_ItemDrag(object sender, ItemDragEventArgs e) 
        { 
           LedgerAccountTaxonomyItem accountTaxonomyItem = ((OLVListItem)e.Item).RowObject as LedgerAccountTaxonomyItem; 
           if (_ledgerAccountTaxonomyItems.FirstOrDefault(m => m.ParentAccountId == accountTaxonomyItem.Id) != null) 
               SendKeys.Send("{ESC}"); 
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-29
    • 2020-02-13
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    相关资源
    最近更新 更多