WinForms中单选按钮列表的第三方控件?

时间:2010-08-04 17:39:48

标签: c# .net winforms

是否有任何控件可以从对象列表中动态创建一组单选按钮?与CheckedBoxList控件类似的东西,但具有互斥选择。 This question指出此控件本身不存在于WinForms中,但有没有第三方控件执行此操作?

2 个答案:

答案 0 :(得分:3)

也许;但是,这样做更容易也更好(除非有人建议使用免费控制或更好的源代码,否则可以放入项目中)。

一点GUI智慧(我没有做到这一点,但我懒得包括引用):

如果单选按钮列表将具有> 7-10项,使用列表框。

当然我收集到你无法控制,或者如果你这样做,将不会满足于那个答案。

  • 向表单添加可滚动面板
  • 在代码中,循环到对象列表。循环内部:
    • 制作新的无线电按钮
    • 将.top属性设置为前一个的.bottom(如果之前没有,则为0)
    • 将您的对象的副本放在.Tag属性中(这样您就可以知道选择了哪个对象)
    • 设置宽度,以便在可滚动控件中找不到水平滚动条
    • 适当地设置.text。您可能需要截断以避免包装。如果你想要多线换行,那么你必须增加高度,但这需要很多带有control.creategraphics,graphics.MeasureString和其他GDI +功能的体操。请参阅Bob Powell的GDI +常见问题解答。
    • 添加处理程序,以便处理checkchanged(AddHandler MyRB,CC_Sub地址)
    • 将其添加到可滚动控件
  • 添加上面提到的CC_Sub - 可以通过添加radiobutton获取正确的函数签名,为CheckChanged添加处理程序,并删除单选按钮
  • 在此子程序中,将类的类型的表单级变量设置为发件人的标记(您必须进行ctypeing)
  • 当您的用户单击“确定”时,返回该变量,即选择的对象。

好的,看起来很难。因此,要么将其挤出管理层,要么将现金收入囊中。

如果你想要更好的东西,你可以使用标签,复选框/单选按钮等进行用户控制。你必须处理选择/取消选择。然后将usercontrol添加到可滚动面板而不是radiobutton。这提供了几乎无限的灵活性。

答案 1 :(得分:3)

控制供应商不能通过这样的控制赚钱。这里有一些代码可以帮助你开始:

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

class RadioList : ListBox {
    public event EventHandler SelectedOptionChanged;

    public RadioList() {
        this.DrawMode = DrawMode.OwnerDrawFixed;
        this.ItemHeight += 2;
    }
    public int SelectedOption {
        // Current item with the selected radio button
        get { return mSelectedOption; }
        set { 
            if (value != mSelectedOption) {
                Invalidate(GetItemRectangle(mSelectedOption));
                mSelectedOption = value; 
                OnSelectedOptionChanged(EventArgs.Empty);
                Invalidate(GetItemRectangle(value));
            }
        }
    }
    protected virtual void OnSelectedOptionChanged(EventArgs e) {
        // Raise SelectOptionChanged event
        EventHandler handler = this.SelectedOptionChanged;
        if (handler != null) handler(this, e);
    }
    protected override void OnDrawItem(DrawItemEventArgs e) {
        // Draw item with radio button
        using (var br = new SolidBrush(this.BackColor))
            e.Graphics.FillRectangle(br, e.Bounds);
        if (e.Index < this.Items.Count) {
            Rectangle rc = new Rectangle(e.Bounds.Left, e.Bounds.Top, e.Bounds.Height, e.Bounds.Height);
            ControlPaint.DrawRadioButton(e.Graphics, rc,
                e.Index == SelectedOption ? ButtonState.Checked : ButtonState.Normal);
            rc = new Rectangle(rc.Right, e.Bounds.Top, e.Bounds.Width - rc.Right, e.Bounds.Height);
            TextRenderer.DrawText(e.Graphics, this.Items[e.Index].ToString(), this.Font, rc, this.ForeColor, TextFormatFlags.Left);
        }
        if ((e.State & DrawItemState.Focus) != DrawItemState.None) e.DrawFocusRectangle();
    }
    protected override void OnMouseUp(MouseEventArgs e) {
        // Detect clicks on the radio button
        int index = this.IndexFromPoint(e.Location);
        if (index >= 0 && e.X < this.ItemHeight) SelectedOption = index;
        base.OnMouseUp(e);
    }
    protected override void OnKeyDown(KeyEventArgs e) {
        // Turn on option with space bar
        if (e.KeyData == Keys.Space && this.SelectedIndex >= 0) SelectedOption = this.SelectedIndex;
        base.OnKeyDown(e);
    }
    private int mSelectedOption;
}