5

当我将一个工具条与同一个工具条面板中的另一个工具条一起拖动到左侧(可能只是为了将它放在角落)时,我正在拖动的工具条会跳到“新”行,就好像我已经将它向下移动了一样。解释起来很棘手,所以这里有几个图表。

图 A:我将工具条向左移动,并且“不小心”向左移动了太远(只有几十个像素,用户可以轻松做到这一点)。

图 B:发生这种情况,拖动的工具条会下降一行。

在此处输入图像描述

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

我已经尝试过 LayoutStyle 无济于事。

4

3 回答 3

1

你如何暂停 OnMouseLeave 上的布局,然后重新启用它 OnMouseEnter/OnMouseUp/etc?

public class ToolStripContainerFix : ToolStripContainer
{
    public ToolStripContainerFix()
        : base()
    {
        this.TopToolStripPanel.MouseLeave += TopToolStripPanel_MouseLeave;
        this.TopToolStripPanel.MouseEnter += TopToolStripPanel_MouseEnter;
    }

    void TopToolStripPanel_MouseLeave(object sender, EventArgs e)
    {
        this.TopToolStripPanel.SuspendLayout();
    }

    void TopToolStripPanel_MouseEnter(object sender, EventArgs e)
    {
        this.TopToolStripPanel.ResumeLayout();
    }
}

你需要摆弄它,以便它在表单之外检查它,而不是控件本身......这样你就可以允许在预期时创建新行。

于 2013-03-03T22:50:32.810 回答
1

Winforms 中的工具条类非常古怪。它们在 .NET 2.0 中发布,然后 Winforms 团队很快就解散了。许多团队成员进入了 WPF 项目。结果,这些怪癖从未得到解决。您自己对此几乎无能为力,大多数工具条代码都被锁定,无法覆盖行为。它也相当多,因此重写也不实用。

可以防止行垂直增长。您可以通过在顶部工具条内容面板上设置 MaximumSize 属性来做到这一点:

    public Form1() {
        InitializeComponent();
        toolStripContainer1.TopToolStripPanel.MaximumSize =
            new Size(0, toolStrip1.Height);
    }

但是当你玩弄这个时,你会发现这会使工具条完全消失。没有干净的解决方法。

请注意,这并不是一个真正的问题,工具条的位置是用户的选择,您不应该以任何方式提供帮助。您可以指望用户以合乎逻辑的方式安排它们。

于 2013-03-04T01:24:54.857 回答
1

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

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);
        }           
    }
}


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

还值得一提的是,这可能会给用户带来烦恼,特别是如果他们故意尝试将 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);
        }
    }
}


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

然后我ToolStripContainer从工具箱中把一个规则放到表单上,设置DockFill,设置颜色等。

ToolStripEx然后我将两个s(带有你提到的齿轮图标)从工具箱拖到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);
        }
    }
}


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

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

就像 Hans 说的那样,这ToolStrip门课非常古怪,除非您根据自己的需求从头开始开发自己的控件,否则几乎任何解决您问题的方法都不会完美。

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

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

protected override void OnBeginDrag(EventArgs e)
{
    //base.OnBeginDrag(e);
}

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

于 2013-03-05T06:34:46.733 回答