Что это за контроль?(Кнопка “Открыть” с выпадающим списком)
Вопрос
Кнопка "Открыть" в диалоговом окне "Открыть файл", используемая в некоторых приложениях Windows, включает стрелку выпадающего списка со списком дополнительных опций, а именно "Открыть с помощью ..".
Я не видел этого в каждом приложении Windows, поэтому вам, возможно, придется попробовать несколько, чтобы получить его, но SQL Server Management Studio и Visual Studio 2005 будут отображать кнопку таким образом, если вы зайдете в меню и выберете Файл->Открыть->Файл...
Я хочу использовать подобную кнопку со встроенным списком в одном из моих приложений, но я не могу найти элемент управления, который они используют, нигде в Visual Studio.Я должен уточнить, что я ищу эту конкретную кнопку, а не все диалоговое окно целиком.Есть какие-нибудь мысли?
Решение
Я использовал перетаскиваемый поиск в Spy ++ (установлен вместе с VS), чтобы посмотреть на кнопку разделить открытие в диалоговом окне открытия файла VS.
Это показало, что это обычная кнопка Windows со стилем, который включает BS_DEFSPLITBUTTON.Это волшебное ключевое слово, которое приведет вас в несколько интересных мест, в том числе
http://www.codeplex.com/windowsformsaero/SourceControl/FileView.aspx?itemId=212902&changeSetId=9930
и здесь
http://msdn.microsoft.com/en-us/library/bb775949.aspx#using_splits
Надеюсь, это поможет вам.
Редактировать:
На самом деле я только что попробовал этот код из CodePlex, и он создает разделенную кнопку - но вы должны убедиться, что вы установили для кнопки FlatStyle значение "System", а не "Standard", которое используется по умолчанию.Я не потрудился подключить элементы обработки событий для выпадающего списка, но, я думаю, это описано в ссылке MSDN.
Конечно, это доступно только для Vista (но для этого не требуется включение Aero, несмотря на название в codeplex) - если вам понадобится поддержка более ранней ОС, вы вернетесь к рисованию ее самостоятельно.
Другие советы
Я помнил это Кетарин у него есть такая кнопка.
Используя Отражатель Я нашел отличный элемент управления с открытым исходным кодом под названием Добрый день.Разделительная кнопка.
Я думаю, то, что вы ищете, называется ToolStripSplitButton .Он доступен только в панели инструментов.Но вы можете добавить ToolStripContainer в любое место вашей формы, а затем поместить ToolStrip и ToolStripSplitButton внутрь вашего контейнера.
Вы не захотите показывать ручки управления, поэтому захотите установить gripMargin = 0.Вы также можете установить свой autosize = true, чтобы полоска инструментов соответствовала вашей кнопке.Кнопка будет выглядеть как обычная кнопка (за исключением разделенной части) в вашей форме.
Я не знаком с использованием ни того, ни другого, но попробуйте поискать в msdn splitbutton или dropdownbutton.Я думаю, они похожи на то, что вы ищете.
Вот моя реализация разделенной кнопки.Он не рисует стрелку, и поведение фокусировки / расфокусировки немного отличается.
И мои, и оригиналы работают с визуальными стилями и отлично смотрятся в Aero.
Основанный на http://wyday.com/splitbutton/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Drawing;
using System.ComponentModel;
using System.Diagnostics;
// Original: http://blogs.msdn.com/jfoscoding/articles/491523.aspx
// Wyatt's fixes: http://wyday.com/splitbutton/
// Trimmed down and redone significantly from that version (Nick 5/6/08)
namespace DF
{
public class SplitButton : Button
{
private ContextMenuStrip m_SplitMenu = null;
private const int SplitSectionWidth = 14;
private static int BorderSize = SystemInformation.Border3DSize.Width * 2;
private bool mBlockClicks = false;
private Timer mTimer;
public SplitButton()
{
this.AutoSize = true;
mTimer = new Timer();
mTimer.Interval = 100;
mTimer.Tick += new EventHandler(mTimer_Tick);
}
private void mTimer_Tick(object sender, EventArgs e)
{
mBlockClicks = false;
mTimer.Stop();
}
#region Properties
[DefaultValue(null)]
public ContextMenuStrip SplitMenu
{
get
{
return m_SplitMenu;
}
set
{
if (m_SplitMenu != null)
m_SplitMenu.Closing -=
new ToolStripDropDownClosingEventHandler(m_SplitMenu_Closing);
m_SplitMenu = value;
if (m_SplitMenu != null)
m_SplitMenu.Closing +=
new ToolStripDropDownClosingEventHandler(m_SplitMenu_Closing);
}
}
private void m_SplitMenu_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
HideContextMenuStrip();
// block click events for 0.5 sec to prevent re-showing the menu
}
private PushButtonState _state;
private PushButtonState State
{
get
{
return _state;
}
set
{
if (!_state.Equals(value))
{
_state = value;
Invalidate();
}
}
}
#endregion Properties
protected override void OnEnabledChanged(EventArgs e)
{
if (Enabled)
State = PushButtonState.Normal;
else
State = PushButtonState.Disabled;
base.OnEnabledChanged(e);
}
protected override void OnMouseClick(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
if (State.Equals(PushButtonState.Disabled))
return;
if (mBlockClicks)
return;
if (!State.Equals(PushButtonState.Pressed))
ShowContextMenuStrip();
else
HideContextMenuStrip();
}
protected override void OnMouseEnter(EventArgs e)
{
if (!State.Equals(PushButtonState.Pressed) && !State.Equals(PushButtonState.Disabled))
{
State = PushButtonState.Hot;
}
}
protected override void OnMouseLeave(EventArgs e)
{
if (!State.Equals(PushButtonState.Pressed) && !State.Equals(PushButtonState.Disabled))
{
if (Focused)
{
State = PushButtonState.Default;
}
else
{
State = PushButtonState.Normal;
}
}
}
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
Graphics g = pevent.Graphics;
Rectangle bounds = this.ClientRectangle;
// draw the button background as according to the current state.
if (State != PushButtonState.Pressed && IsDefault && !Application.RenderWithVisualStyles)
{
Rectangle backgroundBounds = bounds;
backgroundBounds.Inflate(-1, -1);
ButtonRenderer.DrawButton(g, backgroundBounds, State);
// button renderer doesnt draw the black frame when themes are off =(
g.DrawRectangle(SystemPens.WindowFrame, 0, 0, bounds.Width - 1, bounds.Height - 1);
}
else
{
ButtonRenderer.DrawButton(g, bounds, State);
}
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
g.DrawString(Text, Font, SystemBrushes.ControlText, bounds, format);
}
private void ShowContextMenuStrip()
{
State = PushButtonState.Pressed;
if (m_SplitMenu != null)
{
m_SplitMenu.Show(this, new Point(0, Height), ToolStripDropDownDirection.BelowRight);
}
}
private void HideContextMenuStrip()
{
State = PushButtonState.Normal;
m_SplitMenu.Hide();
mBlockClicks = true;
mTimer.Start();
}
}
}
Я не думаю, что есть встроенный элемент управления, который может сделать это в .NET.Я копаюсь в документации MSDN для стандартного элемента управления кнопками Windows, но, похоже, его там нет.
Я действительно нашел Статья проекта Кода с пользовательской реализацией;это могло бы немного помочь.
Поскольку я нашел элемент управления в самой Windows, я надеялся найти его уже встроенным где-нибудь, поэтому мне не нужно было ничего добавлять в свою кодовую базу, чтобы использовать его.Но кнопка разделения на эта ссылка (найдено с помощью предложения msdn) выглядит довольно многообещающе.
Я попробую это позже сам, но я не знаю, насколько хорошо это будет работать с визуальными стилями.