如果另一个工具条位于同一个工具条面板上,那么移动工具条稍微过一点就会创建一个新行

Dan*_*n W 5 c# toolstrip winforms

当我在同一个工具条面板中使用另一个工具条向左拖动工具条(也许只是为了让它在角落里)时,我拖动的那个跳到一个"新"行,好像我把它向下移动了一样.解释起来相当棘手,所以这里有几个图表.

图A:我将工具条向左移动,并且"意外地"向左移动太远(只有几十个像素,用户可以轻松做到).

图B:发生这种情况,拖动的工具条会连续下降.

在此输入图像描述

如何防止这个新行被"创建"?作为最后的手段,我很乐意防止在任何情况下创建新行(例如:如果用户打算将其向下拖动以创建新行).

我尝试过LayoutStyle无济于事.

spa*_*967 1

可能有几种方法可以做到这一点。我尝试过一些,但没有一个是完美的。我想说的是,我发现的最简单的方法是像 Hans 提到的那样设置 ToolStripPanel 的最大大小,并且对 ToolStrip 进行子类化并覆盖OnLocationChanged(或者分配一个事件处理程序LocationChanged而不是子类化,但您必须分配一个处理程序)到每个工具条)。

public class ToolStripEx : ToolStrip
{
    protected override void OnLocationChanged(EventArgs e)
    {
        if (this.Location.Y >= this.Parent.MaximumSize.Height)
        {
            this.Location = new Point(this.Location.X, 0);
        }
        else
        {
            base.OnLocationChanged(e);
        }           
    }
}
Run Code Online (Sandbox Code Playgroud)


注意:这会导致鼠标在尝试向下拖动 ToolStrip 时来回跳跃,因为位置已更改会重置,因此它本质上是向下移动,然后立即向上跳回来。

还值得一提的是,这可能会给用户带来烦恼,特别是如果他们故意尝试将 ToolStrip 放在新行中,所以我真的不建议这样做。但既然你问了,那就是了。

更新完整的步骤和代码:

我创建了一个新的空白 Windows 窗体项目。我在解决方案中添加了一个新文件ToolStripEx.cs,里面的内容如下:

更新了其他面板及其Orientation

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public class ToolStripEx : ToolStrip
    {
        protected override void OnLocationChanged(EventArgs e)
        {
            if (this.Parent is ToolStripPanel)
            {
                ToolStripPanel parent = this.Parent as ToolStripPanel;

                if (parent.Orientation == Orientation.Horizontal)
                {
                    if (this.Location.Y != 0)
                    {
                        this.Location = new Point(this.Location.X, 0);
                        return;
                    }
                }
                else if (parent.Orientation == Orientation.Vertical)
                {
                    if (this.Location.X != 0)
                    {
                        this.Location = new Point(0, this.Location.Y);
                        return;
                    }
                }
            }
            base.OnLocationChanged(e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


然后我构建了解决方案,以便该类ToolStripEx将显示在工具箱中。

ToolStripContainer然后我将工具箱中的常规内容放入表单中,设置DockFill,设置颜色等。

然后我将两个ToolStripExs (带有您提到的齿轮图标)从工具箱拖到TopToolStripPanel. 我设置了它们的颜色和渲染器等等。

看起来像这样Form1.cs

更新以设置其他最大尺寸

using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.toolStripContainer1.TopToolStripPanel.MaximumSize = new Size(0, toolStripEx1.Height);
            this.toolStripContainer1.LeftToolStripPanel.MaximumSize = new Size(toolStripEx1.Height, 0);
            this.toolStripContainer1.BottomToolStripPanel.MaximumSize = new Size(0, toolStripEx1.Height);
            this.toolStripContainer1.RightToolStripPanel.MaximumSize = new Size(toolStripEx1.Height, 0);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


注意:此代码可防止任何面板扩展其行(或列,如果它们具有 of OrientationOrientation.Vertical。如果您希望侧面板能够扩展,请不要设置其最大尺寸并删除该else if parent.Orientation == Orientation.Vertical部分。

这应该就是全部了。我运行了这个,当移动它们时,两个ToolStripExs 都没有消失。

就像汉斯所说,这个ToolStrip类非常古怪,除非您从头开始开发自己的控件并考虑到您的需求,否则几乎任何问题的解决方案都不会是完美的。

如果由于某种原因您需要扩展该类ToolStripContainer,请将其与新ToolStripEx类分开。我怀疑嵌套类会导致您仍然使用常规类ToolStrip而不是ToolStripEx类。

另一个更新 - 修复鼠标跳跃: 我在尝试摆脱鼠标光标问题时偶然发现了这一点。将其添加到ToolStripEx类中:

protected override void OnBeginDrag(EventArgs e)
{
    //base.OnBeginDrag(e);
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,这似乎大大降低了工具条对被拖到面板外的阻力。我还没有深入研究为什么会这样,但似乎 ToolStrip 实现了自己的拖动行为,而不使用基本的拖/放功能,并且通过覆盖OnBeginDragDropToolStrip 然后专门使用其自定义行为,这使得鼠标在拖动时表现得更好。