Toolstrip с группой кнопок проверки
Я хотел бы иметь toolstrip с некоторыми кнопками на нем (WinFroms/c#/.net4). Я бы хотел, чтобы кнопка была проверена, а все остальные не отмечены, поэтому я хочу, чтобы только кнопка была проверена, все остальные не отмечены.
Я знаю, что кнопка toolstrip имеет свойство checkedonlclick, но когда я нажимаю одну кнопку, Другие также могут быть проверены. В старом добром VB6 было автоматическое решение этой проблемы: buttongroup на панели инструментов. Есть ли подобное в Винфомс?
или я должен обрабатывать его из кода?! Переключить все остальные кнопки в непроверенное состояние, когда одна кнопка проверена? Если так, то это не было бы моим любимым решением...
4 ответов
вызовите этот код в событиях toolStripButton_Click, и вы получите желаемый результат.
foreach (ToolStripButton item in ((ToolStripButton)sender).GetCurrentParent().Items)
{
if (item == sender) item.Checked = true;
if ((item != null) && (item != sender))
{
item.Checked = false;
}
}
Я думаю, это старый вопрос, однако я искал решение этой проблемы, а также и закончил тем, что сделал своего рода ToolStripRadioButton, расширив ToolStripButton. Насколько я вижу, поведение должно быть таким же, как у обычной радиокнопки. Однако я добавил идентификатор группы, чтобы иметь несколько групп переключателей в одной и той же полосе инструментов.
можно добавить переключатель в toolstrip как обычный ToolStripButton:
чтобы кнопка выделялась больше при проверке, я дал ей градиентный фон (CheckedColor1 для CheckedColor2 сверху вниз):
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
public class ToolStripRadioButton : ToolStripButton
{
private int radioButtonGroupId = 0;
private bool updateButtonGroup = true;
private Color checkedColor1 = Color.FromArgb(71, 113, 179);
private Color checkedColor2 = Color.FromArgb(98, 139, 205);
public ToolStripRadioButton()
{
this.CheckOnClick = true;
}
[Category("Behavior")]
public int RadioButtonGroupId
{
get
{
return radioButtonGroupId;
}
set
{
radioButtonGroupId = value;
// Make sure no two radio buttons are checked at the same time
UpdateGroup();
}
}
[Category("Appearance")]
public Color CheckedColor1
{
get { return checkedColor1; }
set { checkedColor1 = value; }
}
[Category("Appearance")]
public Color CheckedColor2
{
get { return checkedColor2; }
set { checkedColor2 = value; }
}
// Set check value without updating (disabling) other radio buttons in the group
private void SetCheckValue(bool checkValue)
{
updateButtonGroup = false;
this.Checked = checkValue;
updateButtonGroup = true;
}
// To make sure no two radio buttons are checked at the same time
private void UpdateGroup()
{
if (this.Parent != null)
{
// Get number of checked radio buttons in group
int checkedCount = this.Parent.Items.OfType<ToolStripRadioButton>().Count(x => x.RadioButtonGroupId == RadioButtonGroupId && x.Checked);
if (checkedCount > 1)
{
this.Checked = false;
}
}
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
this.Checked = true;
}
protected override void OnCheckedChanged(EventArgs e)
{
if (this.Parent != null && updateButtonGroup)
{
foreach (ToolStripRadioButton radioButton in this.Parent.Items.OfType<ToolStripRadioButton>())
{
// Disable all other radio buttons with same group id
if (radioButton != this && radioButton.RadioButtonGroupId == this.RadioButtonGroupId)
{
radioButton.SetCheckValue(false);
}
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
if (this.Checked)
{
var checkedBackgroundBrush = new LinearGradientBrush(new Point(0, 0), new Point(0, this.Height), CheckedColor1, CheckedColor2);
e.Graphics.FillRectangle(checkedBackgroundBrush, new Rectangle(new Point(0, 0), this.Size));
}
base.OnPaint(e);
}
}
возможно, полезно и для других.
Я не знаю, как это сделать в конструкторе, но это довольно просто сделать в коде:
readonly Dictionary<string, HashSet<ToolStripButton>> mButtonGroups;
...
ToolStripButton AddGroupedButton(string pText, string pGroupName) {
var newButton = new ToolStripButton(pText) {
CheckOnClick = true
};
mSomeToolStrip.Items.Add(newButton);
HashSet<ToolStripButton> buttonGroup;
if (!mButtonGroups.TryGetValue(pGroupName, out buttonGroup)) {
buttonGroup = new HashSet<ToolStripButton>();
mButtonGroups.Add(pGroupName, buttonGroup);
}
newButton.Click += (s, e) => {
foreach (var button in buttonGroup)
button.Checked = button == newButton;
};
return newButton;
}
Я не сделал этого немного, но если вы используете групповое поле вокруг переключателей, это позволит проверять только один за раз.