Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WinForms TreeView具有收音机和复选框_Winforms_Checkbox_Radio Button - Fatal编程技术网

WinForms TreeView具有收音机和复选框

WinForms TreeView具有收音机和复选框,winforms,checkbox,radio-button,Winforms,Checkbox,Radio Button,我希望TreeView能够在多个根节点上显示单选按钮,并在其子节点上显示复选框。任何根节点下只有一级子节点 收音机的行为也应类似于一个组,即选择一个根,取消选择其他的收音机 我一直试图用图像来伪装它,但它看起来不真实。我最初有一个列表框和一个单独的checkedlistbox,但可用性之神将其删除了 是否有人实现了此功能或有其他建议 这样想: (o) 麦当劳 []汉堡 []炸薯条 []饮料 (o) 汉堡王 []汉堡 []炸薯条 []饮料 (*)温迪的 [x] 汉堡 [x] 炸薯条 []饮料 您可

我希望TreeView能够在多个根节点上显示单选按钮,并在其子节点上显示复选框。任何根节点下只有一级子节点

收音机的行为也应类似于一个组,即选择一个根,取消选择其他的收音机

我一直试图用图像来伪装它,但它看起来不真实。我最初有一个列表框和一个单独的checkedlistbox,但可用性之神将其删除了

是否有人实现了此功能或有其他建议

这样想:

(o) 麦当劳
[]汉堡
[]炸薯条
[]饮料
(o) 汉堡王
[]汉堡
[]炸薯条
[]饮料
(*)温迪的
[x] 汉堡
[x] 炸薯条
[]饮料


您可以有一个大选项,但在大选项下选择1..n。

我根据本文提出了一个解决方案。我的实现继承自CheckedListBox,包括以下方法:

    protected override void OnDrawItem (DrawItemEventArgs e)
    {
        // Erase all background if control has no items
        if (e.Index < 0 || e.Index > this.Items.Count - 1)
        {
            e.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
            return;
        }

        // Calculate bounds for background, if last item paint up to bottom of control
        Rectangle rectBack = e.Bounds;
        if (e.Index == this.Items.Count - 1)
            rectBack.Height = this.ClientRectangle.Top + this.ClientRectangle.Height - e.Bounds.Top;
        e.Graphics.FillRectangle(new SolidBrush(this.BackColor), rectBack);

        // Determines text color/brush
        Brush brushText = SystemBrushes.FromSystemColor(this.ForeColor);
        if ((e.State & DrawItemState.Disabled) == DrawItemState.Disabled || (e.State & DrawItemState.Grayed) == DrawItemState.Grayed)
            brushText = SystemBrushes.GrayText;
        Boolean bIsChecked = this.GetItemChecked(e.Index);

        String strText;
        if (!string.IsNullOrEmpty(DisplayMember)) // Bound Datatable? Then show the column written in Displaymember
            strText = ((System.Data.DataRowView) this.Items[e.Index])[this.DisplayMember].ToString();
        else
            strText = this.Items[e.Index].ToString();

        Size sizeGlyph;
        Point ptGlyph;

        if (this.GetItemType(e.Index) == ItemType.Radio)
        {
            RadioButtonState stateRadio = bIsChecked ? RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal;
            if ((e.State & DrawItemState.Disabled) == DrawItemState.Disabled || (e.State & DrawItemState.Grayed) == DrawItemState.Grayed)
                stateRadio = bIsChecked ? RadioButtonState.CheckedDisabled : RadioButtonState.UncheckedDisabled;

            // Determines bounds for text and radio button
            sizeGlyph = RadioButtonRenderer.GetGlyphSize(e.Graphics, stateRadio);
            ptGlyph = e.Bounds.Location;
            ptGlyph.X += 4; // a comfortable distance from the edge
            ptGlyph.Y += (e.Bounds.Height - sizeGlyph.Height) / 2;

            // Draws the radio button
            RadioButtonRenderer.DrawRadioButton(e.Graphics, ptGlyph, stateRadio);
        }
        else
        {
            CheckBoxState stateCheck = bIsChecked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
            if ((e.State & DrawItemState.Disabled) == DrawItemState.Disabled || (e.State & DrawItemState.Grayed) == DrawItemState.Grayed)
                stateCheck = bIsChecked ? CheckBoxState.CheckedDisabled : CheckBoxState.UncheckedDisabled;

            // Determines bounds for text and radio button
            sizeGlyph = CheckBoxRenderer.GetGlyphSize(e.Graphics, stateCheck);
            ptGlyph = e.Bounds.Location;
            ptGlyph.X += 20; // a comfortable distance from the edge
            ptGlyph.Y += (e.Bounds.Height - sizeGlyph.Height) / 2;

            // Draws the radio button
            CheckBoxRenderer.DrawCheckBox(e.Graphics, ptGlyph, stateCheck);
        }

        // Draws the text
        Rectangle rectText = new Rectangle(ptGlyph.X + sizeGlyph.Width + 3, e.Bounds.Y, e.Bounds.Width - sizeGlyph.Width, e.Bounds.Height);
        e.Graphics.DrawString(strText.Substring(4), e.Font, brushText, rectText, this.oAlign);

        // If the ListBox has focus, draw a focus rectangle around the selected item.
        e.DrawFocusRectangle();
    }

    protected override void OnItemCheck (ItemCheckEventArgs ice)
    {
        base.OnItemCheck(ice);

        if (ice.NewValue == CheckState.Unchecked)
            return;

        if (this.GetItemType(ice.Index) == ItemType.Radio) // if they selected a root, deselect other roots and their children
        {
            for (Int32 i = 0; i < this.Items.Count; ++i)
            {
                if (i == ice.Index)
                    continue;
                if (this.GetItemType(i) == ItemType.Radio)
                {
                    this.SetItemChecked(i, false);
                    Int32 j = i + 1;
                    while (j < this.Items.Count && this.GetItemType(j) == ItemType.Checkbox)
                    {
                        this.SetItemChecked(j, false);
                        j++;
                    }
                }
            }
        }
        else if (this.GetItemType(ice.Index) == ItemType.Checkbox) // they selected a child; select the root too and deselect other roots and their children
        {
            // Find parent
            Int32 iParentIdx = ice.Index - 1;
            while (iParentIdx >= 0 && this.GetItemType(iParentIdx) == ItemType.Checkbox)
                iParentIdx--;
            this.SetItemChecked(iParentIdx, true);
        }
    }

    protected ItemType GetItemType (Int32 iIdx)
    {
        String strText = this.Items[iIdx].ToString();
        if (strText.StartsWith("(o)"))
            return (ItemType.Radio);
        else if (strText.StartsWith("[x]"))
            return (ItemType.Checkbox);

        throw (new Exception("Invalid item type"));
    }
受保护的覆盖无效OnDrawItem(DrawItemEventArgs e)
{
//如果控件没有任何项,则清除所有背景
如果(e.Index<0 | | e.Index>this.Items.Count-1)
{
e、 Graphics.FillRectangle(新的SolidBrush(this.BackColor)、this.ClientRectangle);
返回;
}
//如果最后一项绘制到控件底部,则计算背景的边界
矩形矩形矩形=e.边界;
if(e.Index==this.Items.Count-1)
rectBack.Height=this.ClientRectangle.Top+this.ClientRectangle.Height-e.Bounds.Top;
e、 Graphics.FillRectangle(新的SolidBrush(this.BackColor),rectBack);
//确定文本颜色/画笔
Brush brushText=SystemBrush.FromSystemColor(this.ForeColor);
if((e.State&DrawItemState.Disabled)=DrawItemState.Disabled | | |(e.State&DrawItemState.Grayed)==DrawItemState.Grayed)
brushText=systembrushs.GrayText;
Boolean bIsChecked=this.GetItemChecked(e.Index);
字符串strText;
如果(!string.IsNullOrEmpty(DisplayMember))//绑定的Datatable?则显示在DisplayMember中写入的列
strText=((System.Data.DataRowView)this.Items[e.Index])[this.DisplayMember].ToString();
其他的
strText=this.Items[e.Index].ToString();
大小;
点字形;
if(this.GetItemType(e.Index)==ItemType.Radio)
{
RadioButtonState状态Radio=bIsChecked?RadioButtonState.CheckedNormal:RadioButtonState.UncheckedNormal;
if((e.State&DrawItemState.Disabled)=DrawItemState.Disabled | | |(e.State&DrawItemState.Grayed)==DrawItemState.Grayed)
stateRadio=bIsChecked?RadioButtonState.CheckedDisabled:RadioButtonState.UncheckedDisabled;
//确定文本和单选按钮的边界
sizeGlyph=RadioButtonRenderer.GetGlyphSize(例如图形、stateRadio);
ptGlyph=e.Bounds.Location;
ptGlyph.X+=4;//与边缘的舒适距离
ptGlyph.Y+=(e.Bounds.Height-sizeGlyph.Height)/2;
//绘制单选按钮
RadioButtonRenderer.DrawRadioButton(例如图形、ptGlyph、stateRadio);
}
其他的
{
CheckBoxState stateCheck=bIsChecked?CheckBoxState.CheckedNormal:CheckBoxState.UncheckedNormal;
if((e.State&DrawItemState.Disabled)=DrawItemState.Disabled | | |(e.State&DrawItemState.Grayed)==DrawItemState.Grayed)
stateCheck=bIsChecked?CheckBoxState.CheckedDisabled:CheckBoxState.UncheckedDisabled;
//确定文本和单选按钮的边界
sizeGlyph=CheckBoxRenderer.GetGlyphSize(如图形、状态检查);
ptGlyph=e.Bounds.Location;
ptGlyph.X+=20;//与边缘的舒适距离
ptGlyph.Y+=(e.Bounds.Height-sizeGlyph.Height)/2;
//绘制单选按钮
DrawCheckBox(例如图形、ptGlyph、状态检查);
}
//绘制文本
矩形矩形文本=新矩形(ptGlyph.X+sizeGlyph.Width+3,e.Bounds.Y,e.Bounds.Width-sizeGlyph.Width,e.Bounds.Height);
e、 Graphics.DrawString(strText.Substring(4),例如Font、brushText、rectText、this.oAlign);
//如果列表框具有焦点,请围绕选定项绘制一个焦点矩形。
e、 DrawFocusRectangle();
}
受保护的覆盖检查(ItemCheckEventArgs ice)
{
基部。麦切克(冰);
if(ice.NewValue==CheckState.Unchecked)
返回;
if(this.GetItemType(ice.Index)=ItemType.Radio)//如果他们选择了根,则取消选择其他根及其子根
{
对于(Int32 i=0;i=0&&this.GetItemType(iParentIdx)==ItemType.Checkbox)
iParentIdx--;
this.SetItemChecked(iParentIdx,true);
}
}
受保护的ItemType GetItemType(Int32 iIdx)
{
字符串strText=this.Items[iIdx].ToString();
if(strText.StartsWith(“(o)”)
返回(ItemType.Ra)