【问题标题】:CheckOnClick doesn't work when drag-and-drop is implemented实现拖放时 CheckOnClick 不起作用
【发布时间】:2013-09-17 15:11:52
【问题描述】:

我遇到了一个问题,我需要一个 CheckedListBox,我可以在其中通过单击一个项目来选中该框,还可以通过拖放对项目重新排序。

我使用以下代码实现了这一点:

private void chLB_BenötigteProzesse_MouseDown(object sender, MouseEventArgs e)
{
    if (this.chLB_BenötigteProzesse.SelectedItem == null)
        return;
    indexBefore = this.chLB_BenötigteProzesse.SelectedIndex;
    this.chLB_BenötigteProzesse.DoDragDrop(this.chLB_BenötigteProzesse.SelectedItem, DragDropEffects.Move);
}

private void chLB_BenötigteProzesse_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void chLB_BenötigteProzesse_DragDrop(object sender, DragEventArgs e)
{
    Point point = chLB_BenötigteProzesse.PointToClient(new Point(e.X, e.Y));
    int index = this.chLB_BenötigteProzesse.IndexFromPoint(point);
    if (index < 0) index = this.chLB_BenötigteProzesse.Items.Count - 1;
    if (index == indexBefore)
    {
        this.chLB_BenötigteProzesse.SetItemChecked(index, !this.chLB_BenötigteProzesse.GetItemChecked(index));
        return;
    }
    object data = e.Data.GetData(typeof(string));
    this.chLB_BenötigteProzesse.Items.Remove(data);
    this.chLB_BenötigteProzesse.Items.Insert(index, data);
}

问题是,对于 _MouseDown 事件,CheckOnClick 不再起作用。 因此,我尝试使用_MouseDown 中的 indexBefore = ... 和 DragDrop 中的 if (index == indexBefore)... 来解决此问题。 仅当我单击一个项目并将其移动一点以使其被拖动到与以前相同的位置时,这才有效。 简单的点击也不起作用。

接下来的尝试是在 _MouseUp 事件中使用此机制:

    private void chLB_BenötigteProzesse_MouseUp(object sender, MouseEventArgs e)
    {
        Point point = chLB_BenötigteProzesse.PointToClient(new Point(e.X, e.Y));
        int index = this.chLB_BenötigteProzesse.IndexFromPoint(point);
        if (index == indexBefore)
            this.chLB_BenötigteProzesse.SetItemChecked(index, !this.chLB_BenötigteProzesse.GetItemChecked(index));
    }

但是 _MouseUp 永远不会被触发。

你能告诉我如何让它正常工作吗(只需单击一个项目应该选中/取消选中它,并且应该使用拖放来更改顺序)? 有谁知道为什么_MouseUp 事件没有被触发?

谢谢!

编辑:

使用此代码可以正常工作(不能使用 e.LeftButton,因为它是 winforms 而不是 wpf):

    private void chLB_BenötigteProzesse_DragOver(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
    }

    private void chLB_BenötigteProzesse_DragDrop(object sender, DragEventArgs e)
    {
        Point point = chLB_BenötigteProzesse.PointToClient(new Point(e.X, e.Y));
        int index = this.chLB_BenötigteProzesse.IndexFromPoint(point);
        if (index < 0) index = this.chLB_BenötigteProzesse.Items.Count - 1;
        if (index == indexBefore)
        {
            this.chLB_BenötigteProzesse.SetItemChecked(index, !this.chLB_BenötigteProzesse.GetItemChecked(index));
            return;
        }

        object data = e.Data.GetData(typeof(string));
        bool checkState = chLB_BenötigteProzesse.GetItemChecked(indexBefore);
        this.chLB_BenötigteProzesse.Items.Remove(data);
        this.chLB_BenötigteProzesse.Items.Insert(index, data);
        this.chLB_BenötigteProzesse.SetItemChecked(index, checkState);
    }

    private void chLB_BenötigteProzesse_MouseMove(object sender, MouseEventArgs e)
    {
        if (!dragDropEnabled || this.chLB_BenötigteProzesse.SelectedItem == null || e.Location == mouseLocation)
            return;

        indexBefore = this.chLB_BenötigteProzesse.SelectedIndex;
        dragDropEnabled = false;
        this.chLB_BenötigteProzesse.DoDragDrop(this.chLB_BenötigteProzesse.SelectedItem, DragDropEffects.Move);
    }

    private void chLB_BenötigteProzesse_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            dragDropEnabled = true;
            mouseLocation = e.Location;
        }
    }

【问题讨论】:

  • 建议:您应该为您的方法和变量使用英文名称。至少在 StackOverflow。
  • 你是绝对正确的。代码是用非常糟糕的英语写的......

标签: c# winforms drag-and-drop click checkedlistbox


【解决方案1】:

我宁愿使用 OnMouseMove 而不是 OnMouseDown,然后检查是否按下鼠标左键以启动您的 darag 和 drop 操作,如 MSDN 所述。

因此,您的问题的解决方案应该是将 chLB_BenötigteProzesse_MouseDown 替换为:

private void chLB_BenötigteProzesse_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed || this.chLB_BenötigteProzesse.SelectedItem == null)
        return;
    indexBefore = this.chLB_BenötigteProzesse.SelectedIndex;
    this.chLB_BenötigteProzesse.DoDragDrop(this.chLB_BenötigteProzesse.SelectedItem, DragDropEffects.Move);    
}

不要忘记分离 mouseDown 处理程序并附加新的 mouseMove 处理程序!

【讨论】:

  • 太好了,这行得通。所以让我明白为什么_MouseUp 没有被解雇:难道DoDragDrop() 阻止了事件?
猜你喜欢
  • 2016-12-13
  • 1970-01-01
  • 2016-07-10
  • 2015-08-10
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多