0

我在 C# 中的表单 (System.Windows.Forms) 上放置了一个 toolStrip1,并向其中添加了五个 toolStrip 按钮。现在我想知道如何让用户通过将它们拖动到 toolStrip1 中的另一个位置来重新排序这些按钮。正如微软在一篇文章中建议的那样,我将toolStrip1.AllowItemReorder 设置为 true,并将AllowDrop 设置为 false 。

现在应该在 toolStrip1 中启用项目重新排序的自动处理。但它不起作用 - 只有当我按住 ALT 键时,toolStrip1 才会对用户的重新排序尝试做出反应。我真的要自己处理DragEvent、DragEnter、DragLeave以避免在重新排序项目期间按住 Alt 键吗?

如果是这样,请给我一个示例,如果我希望在不按住任何 ALT 键的情况下将一个项目拖动到 toolStrip1 中的不同位置(如 Internet Explorer 收藏夹那样),则此事件在带有 toolStripButtons 的 toolStrip 上的外观如何。我在这件事上没有经验。

4

1 回答 1

2

好吧,您可能不得不使用这个有点hacky的解决方案。整个想法是您必须通过代码按住Alt键。我已经尝试过MouseDown事件(即使在 a 中PreFilterMessage handler),但它失败了。Alt唯一适合在触发时按住键的事件是MouseEnter. 您必须MouseEnter为所有的 注册事件处理程序ToolStripItems,当鼠标离开这些项目之一时,您必须释放事件处理程序Alt中的键。MouseLeave释放键后Alt,我们必须发送ESC键以激活表单(否则,所有悬停效果似乎都被忽略了,即使在控制按钮上,包括Minimize, Maximize, Close)。这是有效的代码:

public partial class Form1 : Form {
  [DllImport("user32.dll", SetLastError = true)]
  static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
  public Form1(){
     InitializeComponent();
     //Register event handlers for all the toolstripitems initially
     foreach (ToolStripItem item in toolStrip1.Items){
        item.MouseEnter += itemsMouseEnter;
        item.MouseLeave += itemsMouseLeave;
     }
     //We have to do this if we add/remove some toolstripitem at runtime
     //Otherwise we don't need the following code
     toolStrip1.ItemAdded += (s,e) => {
        item.MouseEnter += itemsMouseEnter;
        item.MouseLeave += itemsMouseLeave;
     };
     toolStrip1.ItemRemoved += (s,e) => {
        item.MouseEnter -= itemsMouseEnter;
        item.MouseLeave -= itemsMouseLeave;
     };
  }
  bool pressedAlt;
  private void itemsMouseEnter(object sender, EventArgs e){
        if (!pressedAlt) {
            //Hold the Alt key
            keybd_event(0x12, 0, 0, 0);//VK_ALT = 0x12
            pressedAlt = true;
        }
  }
  private void itemsMouseLeave(object sender, EventArgs e){
        if (pressedAlt){
            //Release the Alt key
            keybd_event(0x12, 0, 2, 0);//flags = 2  -> Release the key
            pressedAlt = false;
            SendKeys.Send("ESC");//Do this to make the GUI active again
        }            
  }
}
于 2013-09-27T15:58:58.730 回答