Как я могу создать кнопку 2 в 1 в приложении C # Windows Forms? [Дубликат]

Вы можете получить один элемент, запустив

document.querySelector('.myElement').style.size = '100px';

, но он будет работать для первого элемента с классом .myElement.

Если вы хотите применить это для всех элементы с классом я предлагаю вам использовать

document.querySelectorAll('.myElement').forEach(function(element) {
    element.style.size = '100px';
});
30
задан tonytony 29 May 2012 в 17:33
поделиться

9 ответов

Вы можете показать ContextMenuStrip в событии клика:

private void button1_Click(object sender, EventArgs e) {
  contextMenuStrip1.Show(button1, new Point(0, button1.Height));
}

Чтобы сделать свое собственное определение, показывать ли меню выше или ниже кнопки, вы можете попробовать использовать этот код, который измеряет меню и определяет, будет ли он частично вне экрана:

private void button1_Click(object sender, EventArgs e) {
  Point screenPoint = button1.PointToScreen(new Point(button1.Left, button1.Bottom));
  if (screenPoint.Y + contextMenuStrip1.Size.Height > Screen.PrimaryScreen.WorkingArea.Height) {
    contextMenuStrip1.Show(button1, new Point(0, -contextMenuStrip1.Size.Height));
  } else {
    contextMenuStrip1.Show(button1, new Point(0, button1.Height));
  }    
}
40
ответ дан LarsTech 22 August 2018 в 16:23
поделиться
  • 1
    Похоже, что мне нужно. Вы знаете хороший способ определить, должно ли меню выпадало из нижней части кнопки или выпадало из верхней границы кнопок? – tonytony 29 May 2012 в 17:55
  • 2
    @tonytony Это должно произойти как бы автоматически. Если меню находится внизу нижней части экрана, окна будут подталкивать его так, чтобы все было видно. – LarsTech 29 May 2012 в 17:59
  • 3
    Как насчет перекрытия кнопки? Я думаю, я должен знать, будет ли это идти вверх или вниз. – tonytony 29 May 2012 в 18:02
  • 4
    @tonytony Обновленный пример. – LarsTech 29 May 2012 в 18:08
  • 5
    Большое спасибо :) – tonytony 29 May 2012 в 18:12

Я тоже занимался этой проблемой и нашел очень простое решение (хотя и немного грязно-взломанное): поместите ComboBox под Button, чтобы он показывал стрелку вниз рядом с кнопкой.

Затем используйте SelectedIndexChanged для ComboBox, чтобы изменить поведение Button или сделать то, что вы хотите сделать немедленно.

0
ответ дан Bart Friederichs 22 August 2018 в 16:23
поделиться
  • 1
    Интересное решение! Тем не менее, я боюсь, что поведение фокуса вклад даст вам. – tonytony 12 April 2017 в 15:23
  • 2
    Просто установите TabStop на False на ComboBox и нажмите клавишу со стрелкой вниз на Button? – Bart Friederichs 12 April 2017 в 15:25
  • 3
    может быть. Честно говоря, я давно отказался от windows.forms и c #. – tonytony 12 April 2017 в 15:28

Показывать контекстное меню под кнопкой при нажатии.

2
ответ дан clearpath 22 August 2018 в 16:23
поделиться
Кнопка

имеет правую сторону стрелки вниз, и вы можете установить ее из конструктора:

ss [/g0]

С ShowMenuUnderCursor:

ss [/g1]

Класс MenuButton:

public class MenuButton : Button
{
    [DefaultValue(null)]
    public ContextMenuStrip Menu { get; set; }

    [DefaultValue(false)]
    public bool ShowMenuUnderCursor { get; set; }

    protected override void OnMouseDown(MouseEventArgs mevent)
    {
        base.OnMouseDown(mevent);

        if (Menu != null && mevent.Button == MouseButtons.Left)
        {
            Point menuLocation;

            if (ShowMenuUnderCursor)
            {
                menuLocation = mevent.Location;
            }
            else
            {
                menuLocation = new Point(0, Height);
            }

            Menu.Show(this, menuLocation);
        }
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        base.OnPaint(pevent);

        if (Menu != null)
        {
            int arrowX = ClientRectangle.Width - 14;
            int arrowY = ClientRectangle.Height / 2 - 1;

            Brush brush = Enabled ? SystemBrushes.ControlText : SystemBrushes.ButtonShadow;
            Point[] arrows = new Point[] { new Point(arrowX, arrowY), new Point(arrowX + 7, arrowY), new Point(arrowX + 3, arrowY + 4) };
            pevent.Graphics.FillPolygon(brush, arrows);
        }
    }
}
46
ответ дан Jaex 22 August 2018 в 16:23
поделиться
  • 1
    Спасибо за ваш ответ! Я действительно думал о кнопке со стрелкой, когда размещал вопрос, и это отличная идея рисовать стрелку с помощью Graphics API. – tonytony 6 June 2014 в 23:00
  • 2
    Фантастика! Большое спасибо за этот ответ – Sverrir Sigmundarson 27 November 2014 в 15:50
  • 3
    Почему значение Menu всегда null, независимо от того, как установить значение свойства ContextMenuStrip? – Alex Jolig 2 November 2015 в 06:16
  • 4
    @Alex Добавить новый объект ContextMenuStrip в свойство Menu, а не свойство ContextMenuStrip. myButton.Menu = New ContextMenuStrip .. вы, вероятно, делаете myButton.ContextMenuStrip = New ContextMenuStrip – user1003916 31 May 2016 в 16:32
  • 5
    Если вам просто нужно использовать событие OnPaint на кнопке вместо наследования с Button, не забудьте использовать размеры кнопки, а не ClientRectangle. Вот так: Button btnSender = (Button)sender; int arrowX = btnSender.Width - 14; int arrowY = btnSender.Height / 2 - 1; – Andrew 24 December 2016 в 02:49

Класс MenuButton Jaex выше для меня был идеальным. Я добавил логику ниже в OnMouseDown, чтобы контекстное меню отображалось только в том случае, если я нажал на стрелку. Если щелкнуть по большей части, произойдет обычное событие щелчка. Разрешено действие щелчка по умолчанию.

if (Menu != null && mevent.Button == MouseButtons.Left)
{
    if (mevent.Location.X >= this.Width - 14)
    {
        System.Drawing.Point menuLocation;

        if (ShowMenuUnderCursor)
        {
            menuLocation = mevent.Location; 
        }
        else
        {
            menuLocation = new System.Drawing.Point(0, Height);
        }

        Menu.Show(this, menuLocation);
    }
}

Думал, что это может быть полезно кому-то. Спасибо Jaex

1
ответ дан Jeff Scott 22 August 2018 в 16:23
поделиться

Самый простой вариант - использовать ToolStripDropDownButton в незакрепленном ToolStrip, который отображает только одну кнопку. Затем вы можете добавить к нему подпозиции и т. Д. Чтобы сделать это: - перетащите панель инструментов на свой элемент управления / форму - используйте вспомогательный элемент макета для добавления DropDownButton - установите GripStyle в Hidden - установите Dock в None

В результате создается отдельная кнопка в стиле панели инструментов, которая поддерживает описанное выше раскрывающееся поведение.

5
ответ дан JoshL 22 August 2018 в 16:23
поделиться
  • 1
    Спасибо за ответ, это чисто и просто, но не совсем то, что мне нужно. Кнопка меню вид небудет, а я хочу чего-то более мясистого :) – tonytony 29 May 2012 в 17:54

Легко мы могли это сделать. это может помочь:)

ContextMenuStrip contextMenuStrip1 = new ContextMenuStrip();

        private void button1_Click(object sender, EventArgs e)
        {
            contextMenuStrip1.Items.Clear();
            contextMenuStrip1.Items.Add("item1");
            contextMenuStrip1.Items.Add("item2");

            contextMenuStrip1.Show(button1, new Point(0, button1.Height));
        }

        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == "item1")
            {
                MessageBox.Show(e.ClickedItem.Text);
            }
        }
6
ответ дан Mou 22 August 2018 в 16:23
поделиться

У Infragistics есть WinDropDownButton: http://help.infragistics.com/Help/NetAdvantage/WinForms/2012.1/CLR2.0/html/WinDropDownButton_About_WinDropDownButton.html

So он определенно существует, однако вы не можете искать платный сторонний элемент управления.

0
ответ дан roken 22 August 2018 в 16:23
поделиться

Расширение @Jaex answer немного, чтобы разрешить линию разделителя, условный чертеж стрелки, если ничего не настроено, и отдельное событие клика для основного тела кнопки и стрелки меню.

Следует отметить, что для лучшего выравнивания вы можете установить button.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;

Вот мое небольшое улучшение

public class SplitButton : Button
{
    [DefaultValue(null), Browsable(true),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public ContextMenuStrip Menu { get; set; }

    [DefaultValue(20), Browsable(true),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public int SplitWidth { get; set; }

    public SplitButton() 
    {
        SplitWidth = 20;
    }

    protected override void OnMouseDown(MouseEventArgs mevent)
    {
        var splitRect = new Rectangle(this.Width - this.SplitWidth, 0, this.SplitWidth, this.Height);

        // Figure out if the button click was on the button itself or the menu split
        if (Menu != null && 
            mevent.Button == MouseButtons.Left &&
            splitRect.Contains(mevent.Location) )
        {
            Menu.Show(this, 0, this.Height);    // Shows menu under button
            //Menu.Show(this, mevent.Location); // Shows menu at click location
        }
        else
        {
            base.OnMouseDown(mevent);
        }
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        base.OnPaint(pevent);

        if (this.Menu != null && this.SplitWidth > 0)
        { 
            // Draw the arrow glyph on the right side of the button
            int arrowX = ClientRectangle.Width - 14;
            int arrowY = ClientRectangle.Height / 2 - 1;

            var arrowBrush = Enabled ? SystemBrushes.ControlText : SystemBrushes.ButtonShadow;
            var arrows = new[] { new Point(arrowX, arrowY), new Point(arrowX + 7, arrowY), new Point(arrowX + 3, arrowY + 4) };
            pevent.Graphics.FillPolygon(arrowBrush, arrows);

            // Draw a dashed separator on the left of the arrow
            int lineX = ClientRectangle.Width - this.SplitWidth;
            int lineYFrom = arrowY - 4;
            int lineYTo = arrowY + 8;
            using( var separatorPen = new Pen(Brushes.DarkGray){DashStyle = DashStyle.Dot})
            {
                pevent.Graphics.DrawLine(separatorPen, lineX, lineYFrom, lineX, lineYTo);
            }
        }
    }
}
10
ответ дан Wolfgang 22 August 2018 в 16:23
поделиться
  • 1
    var splitRect = new Rectangle(this.Width - this.SplitWidth, this.Location.Y, this.SplitWidth, this.Height); второй параметр должен быть изменен на 0 – Jacky 11 January 2015 в 03:29
  • 2
    Джеки прав. Выпадающая область «щелчок» не покрывает всю высоту кнопки, если этот параметр не равен 0. – Jan Kadeřábek 26 February 2017 в 22:18
  • 3
    Я отредактировал код, чтобы исправить ошибку, которую @Jacky идентифицировал. – Wolfgang 1 December 2017 в 17:11
  • 4
Другие вопросы по тегам:

Похожие вопросы: