2013-02-27 3 views
5

Когда я перетаскиваю панель инструментов влево (возможно, просто чтобы получить ее в углу) с помощью другой инструментальной панели в той же самой панели инструментов панель, та, которую я перетаскиваю, перескакивает до «новой» строки, как будто я ее переместил. Это довольно сложно объяснить, так что вот пара диаграмм.Перемещение инструментальной панели чуть слишком далеко слева создаст новую строку, если другая панель инструментов находится на одной панели инструментальных панелей.

Диаграмма A: Я перемещаю инструментальную панель влево и «случайно» перехожу слишком далеко влево (ну только на пару десятков пикселей, что пользователи могут легко сделать).

Диаграмма B: Это происходит, перетаскиваемая полоска прокрутки падает вниз.

enter image description here

Как я могу предотвратить эту новую строку из бытия «создал»? В крайнем случае я был бы рад предотвратить создание новых строк при любых обстоятельствах (например: если пользователь намеревался перетащить его, чтобы создать новую строку).

Я экспериментировал с LayoutStyle безрезультатно.

+0

Ха, просто попробовал. Как очень странно. –

+0

Я видел это, но считаю, что это связано с тем, что я передвинул мышь вертикально. Насколько я могу судить, если мышь перемещается мертвой горизонталью, это не произошло для меня. –

ответ

1

Возможно, есть несколько способов сделать это. Я экспериментировал с несколькими, но ни один из них не идеален. Я бы сказал, что наименее сложный способ, который я нашел, - установить максимальный размер 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 вниз, из-за того, что Место сброса после она уже изменилась, поэтому он по существу движется вниз, а затем сразу же прыгает обратно.

Также стоит упомянуть, что это может раздражать пользователя, особенно если они намеренно пытаются поместить ToolStrip в новую строку, поэтому я бы не рекомендовал это делать. Но так как вы спросили, вот оно.

Обновление с полным шагом и кодом:

Я создал проект новой пустой Windows Forms. Я добавил новый файл 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 на форму из панели инструментов, установите Dock в Fill, установить цвета и т.д.

Затем я перетащил два ToolStripEx с (с значок шестеренки вы упомянули) из панели элементов 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); 
     } 
    } 
} 


Примечание Этот код предотвращает любой из панелей от расширения их строки (или столбцы, если они имеют Orientation из Orientation.Vertical) Если вы хотите боковую панель els, чтобы иметь возможность расширения, не устанавливать максимальный размер и избавиться от раздела else if parent.Orientation == Orientation.Vertical.

Это должно быть все, что нужно. Я побежал, и оба из ToolStripEx s не исчезли, перемещая их.

Как и Ганс, класс ToolStrip довольно изворотливый, и практически любое решение вашей проблемы не будет идеальным, если вы не разработаете собственные средства управления с нуля с учетом ваших потребностей.

Если по какой-либо причине вам необходимо расширить класс ToolStripContainer, сохраните его отдельно от нового класса ToolStripEx. Я подозреваю, что наличие вложенных классов заставляло вас по-прежнему использовать обычный ToolStrip, а не класс ToolStripEx.

Другое обновление - исправление мыши прыгает: Обнаружено это случайно при экспериментировании, чтобы избавиться от проблемы с курсором мыши. Добавьте к этому ToolStripEx класс:

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

Как ни странно, что, кажется, сократить значительно на сопротивления ToolStrip к тащат за пределы панели.Я не вникаю в то, почему это работает, но похоже, что ToolStrip реализует свое собственное поведение перетаскивания без использования основных функций перетаскивания и переопределения OnBeginDragDrop. ToolStrip затем использует свое настраиваемое поведение исключительно, что делает мышью намного приятнее при перетаскивании это

+0

Спасибо. Да, к сожалению, используя решение Ганса в сочетании с вашим, я все еще сталкиваюсь с проблемой исчезающей инструментальной панели. FYI, когда он исчезает, на самом деле он, вероятно, переместится в новую строку под текущей, поэтому он фактически не был «удален». –

+0

@DanW Он не должен переходить в новую строку, потому что местоположение по существу заблокировано до Y 0. Когда я тестировал это, я не мог заставить панель инструментов исчезнуть. И я видел, как исчезающая инструментальная панель произошла, когда я пробовал другие вещи. Возможно, вы могли бы обновить свой вопрос с помощью своего точного кода? – sparky68967

+1

Хорошо обновлено. Кстати, попробуйте просто перетащить инструментальную панель вниз с TopToolStripPanel и в ContentPanel, и вы увидите проблему более легко и сразу (она исчезнет). У вас тоже есть эта проблема? –

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

вам нужно будет возиться с этим, так что он проверяет его вне формы, а не сам контроль ... Таким образом, вы могли бы дать новые строки, которые будут созданы, когда они предназначены.

+0

Большое спасибо. К сожалению, другие ошибки, похоже, ползут. Например, перетаскивание другой панели инструментов влево иногда заставляет ее «скрываться» под другой панелью инструментов, а иногда я не могу перетащить это совсем не так. –

+0

Вы разместили Layout? Вам нужно будет на события мыши (Enter/Mouse Up) на r e-enable изменения макета. –

+0

Нет, я этого не делал, но вижу, что вы обновили код, поэтому я попробовал это. К сожалению, у меня все еще возникают проблемы с «застрявшими» и «исчезающими» инструментальными полосками и/или «объединенными» инструментальными полосками. Например, попробуйте переместить первую инструментальную панель слишком далеко слева, а затем наведите указатель мыши на часть «перетаскивания» другой инструментальной панели, а первая исчезнет. –

1

Классы инструментов в Winforms довольно изворотливые. Они были выпущены в .NET 2.0, и команда Winforms вскоре расформировалась. Многие члены команды перешли в проект WPF. В результате эти причуды не были решены. Вы можете сделать это очень мало, большая часть кода инструментальной панели заблокирована без какого-либо способа переопределить поведение. Там также довольно много, поэтому переписывание также не практично.

Вы: можете предотвратить вертикальный рост строки. Это можно сделать, установив свойство MaximumSize на верхней панели содержимого ToolStrip:

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

Но когда вы поиграйте с этим вы обнаружите, что это может сделать ToolStrip полностью исчезнуть. Никакого чистого исправления для этого.

Обратите внимание, что это не совсем настоящая проблема, расположение инструментальных панелей является выбором пользователя, и вы никоим образом не должны помогать. Вы можете рассчитывать на то, что пользователь упорядочивает их логически.

+0

Спасибо, я тоже испытал один из других инструментов, исчезающих, пытаясь это сделать. К сожалению, проблема - проблема в том смысле, что она вызывает раздражение у моих пользователей, поэтому я попробую два других ответа. –