Добавить кнопки управления в SplitContainer Splitter

Есть ли способ отобразить элементы управления (например, кнопки) на регулируемом разделителе, который отображается между двумя панелями в .NET SplitContainer?

Пример:

Диаграмма

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


person Adam Nofsinger    schedule 17.02.2011    source источник
comment
Вы использовали большую желтую метку, и я до сих пор не знаю, куда поставить курсор, чтобы начать перетаскивание. Нет видимой подсказки вообще. SplitContainer не поддерживает этот макет, его сплиттер не может иметь ширину. Вы можете заставить что-то работать с помощью старого элемента управления Splitter, расположенного справа от левой панели.   -  person Hans Passant    schedule 17.02.2011
comment
@ Ганс - я согласен, что с философской точки зрения это может быть не лучший подход. На самом деле я выбрал TableLayoutPanel, который работает почти так же, как SplitContainer, но без перетаскивания. Тем не менее, я бы сказал, что было бы полезно поставить на разветвитель индикатор ручки, даже вместо кнопок, и это тоже невозможно. Что касается ширины, я бы указал вам на свойство SplitContainer.SplitterWidth. И я не знаю ни одного старого управления Splitter (VS 2008)   -  person Adam Nofsinger    schedule 18.02.2011
comment
В качестве обходного пути можно сделать конструкцию, которая ведет себя как разделитель. Три отдельные панели. Тот, что посередине, узкий, как разветвитель. Реализуйте перетаскивание в событии MouseMove для средней панели. Поскольку это панель, она может содержать дочерние элементы управления (кнопки).   -  person Nick Alexeev    schedule 18.02.2011


Ответы (1)


Вот пример, который использует TableLayoutPanel для имитации SplitContainer.

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

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    TableLayoutPanel rootPanel;
    float originalWidth;
    int splitPointX;

    public Form1()
    {
        Controls.Add(rootPanel = new TableLayoutPanel
        {
            ColumnCount = 3,
            ColumnStyles =
            {
                // Notice the use of Absolute here as this will control the 'splitting'
                new ColumnStyle(SizeType.Absolute, 120F),
                // Size of button panel
                new ColumnStyle(SizeType.AutoSize),
                // Remaining size
                new ColumnStyle(SizeType.Percent, 100F),
            },
            Dock = DockStyle.Fill,
            RowCount = 1,
            RowStyles = { new RowStyle(SizeType.Percent, 100F) },
        });

        Panel buttonPanel;
        rootPanel.Controls.Add(buttonPanel = new Panel
        {
            Anchor = AnchorStyles.Top | AnchorStyles.Bottom,
            BackColor = SystemColors.ControlDark,
            Margin = new Padding(0),
            MinimumSize = new Size(80, 0),
            Size = new Size(80, 0),
            Controls =
            {
                // UseVisualStyleBackColor = true only because we altered the container's BackColor
                new Button { Text = ">>", Location = new Point(19, 112), Size = new Size(40, 23), UseVisualStyleBackColor = true },
                new Button { Text = ">", Location = new Point(19, 83), Size = new Size(40, 23), UseVisualStyleBackColor = true },
                new Button { Text = "<", Location = new Point(19, 54), Size = new Size(40, 23), UseVisualStyleBackColor = true },
                new Button { Text = "<<", Location = new Point(19, 25), Size = new Size(40, 23), UseVisualStyleBackColor = true },
            },
        }, 1, 0);

        buttonPanel.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    // Capture mouse so that all mouse move messages go to this control
                    (s as Control).Capture = true;

                    // Record original column width
                    originalWidth = rootPanel.ColumnStyles[0].Width;

                    // Record first clicked point
                    // Convert to screen coordinates because this window will be a moving target
                    Point windowPoint = (s as Control).PointToScreen(e.Location);
                    splitPointX = windowPoint.X;
                }
            };
        buttonPanel.MouseMove += (s, e) =>
            {
                if ((s as Control).Capture)
                {
                    Point windowPoint = (s as Control).PointToScreen(e.Location);

                    // Calculate distance of mouse from splitPoint
                    int offset = windowPoint.X - splitPointX;

                    // Apply to originalWidth
                    float newWidth = originalWidth + offset;

                    // Clamp it.
                    // The control in the left pane's MinimumSize.Width would be more appropriate than zero
                    newWidth = Math.Max(0, newWidth);

                    // Update column width
                    if (Math.Abs(newWidth - rootPanel.ColumnStyles[0].Width) >= 1)
                        rootPanel.ColumnStyles[0].Width = newWidth;
                }
            };
        buttonPanel.MouseUp += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    // Release mouse capture
                    if ((s as Control).Capture)
                        (s as Control).Capture = false;
                }
            };
    }
}
person Tergiver    schedule 18.02.2011
comment
Не помешало бы немного полировки, но отличное начало, если я когда-нибудь захочу вернуться к этому. В итоге я просто сказал, что это того не стоит, и использовал стандартную TableLayoutPanel и стационарную разделенную панель для среднего столбца. - person Adam Nofsinger; 22.02.2011
comment
Спасибо за это - адаптировал его для таблицы с 3 столбцами. - person Chuck Savage; 31.08.2011