先说明确需求:
在Delphi中,有一个第三方的类似DataGridView控件,可以设置columnType 为radiobutton类型。这个总体需求不难实现,难点在于 当选择为radiobutton类型的ColumnType时,自动出现集合项属性,集合编辑后,能够按照集合编辑后的item数量和设置使用。如下图。这是我目前实现的状态。
我的问题是:集合编辑完成后,所有的添加项radiobutton都没有保存到RadioButtonCellTemplate模板上,集合数为零。
看了一下编辑器产生的代码,少了一步添加动作。也就是说在下写的自定义Column ,在做集合编辑的时候,编译器不做相应的添加动作。导致无法实现 预期功能。现把全部相关代码贴如下:

解决方案 »

  1.   

    [code=C#]
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    using System.Windows.Forms.Design;
    using System.Windows.Forms;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Collections;namespace diyControls
    {
        #region///////////自定义Column模板和 RadioButtonList控件
        /// <summary>
        /// 自定义Column模板RadioButton(基于上面的用户控件)
        /// </summary>
        ///     public class diyRadioButtonColumn : DataGridViewColumn//Control   //:
        {
            public diyRadioButtonColumn()  : base(new diyRadioButtonCell())
            {
            }        public override DataGridViewCell CellTemplate
            {
                get
                {
                    return base.CellTemplate;
                }
                set
                {
                    // Ensure that the cell used for the template is a CalendarCell.
                    if (value != null && !value.GetType().IsAssignableFrom(typeof(diyRadioButtonCell)))
                    {
                        throw new InvalidCastException("Must be a CalendarCell");
                    }
                    base.CellTemplate = value;
                }
            }
            private diyRadioButtonCell RadioButtonCellTemplate
            {
                get
                {
                    return (diyRadioButtonCell)this.CellTemplate;
                }
            }        public List<RadioButton> radioButtons = new List<RadioButton>();
            [Browsable(true)]
            [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
            public virtual  List<RadioButton> myRadioButtonItems
            {
                get
                {
                    try
                    {
                        if (this.RadioButtonCellTemplate == null)
                        {
                            throw new InvalidOperationException("DataGridViewColumn_CellTemplateRequired");
                        }
                        return this.RadioButtonCellTemplate.getRadioButtonItems(base.DataGridView);
                        //diyRadioButtonEditingControl drbc = DataGridView .EditingControl  as diyRadioButtonEditingControl;
                        //return drbc.myRadioButtonItem;// radioButtons;
                    }
                    catch
                    { return radioButtons; }
                }
                set
                {
                  // 
                    try
                    {
                        diyRadioButtonEditingControl drbc = DataGridView.EditingControl as diyRadioButtonEditingControl;                   drbc.myRadioButtonItem  = value;
                    
                    }
                    catch
                    { 
                        radioButtons = value;
                    }            }
            }        public List<Label> LabelButtons = new List<Label>();
            [Browsable(false )]
            [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
            public List<Label> myLabelButtonItems
            {
                get
                {
                    return LabelButtons;
                  
                }
                set
                {                LabelButtons = value;
                    try
                    {
                        // diyRadioButtonCell drbc = base.CellTemplate as diyRadioButtonCell;
                        //  ((diyRadioButtonCell)   ( base .CellTemplate)).myRadioButtonItems = value;
                        //diyRadioButtonCell.myRadioButtonItems = value;
                    }
                    catch { }            }
            }
            public int testText = 2;
            [Browsable(false )]
            [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
            public int TestText
            {
                get
                {
                    return testText;
                }
                set
                {
                    testText = value;
                    try
                    {
                        // diyRadioButtonCell drbc = base.CellTemplate as diyRadioButtonCell;
                        //  ((diyRadioButtonCell)   ( base .CellTemplate)).myRadioButtonItems = value;
                        //diyRadioButtonCell.myRadioButtonItems = value;
                    }
                    catch { }            }
            }    }  
      

  2.   

        public class diyRadioButtonCell : DataGridViewTextBoxCell
        {
            public  List<RadioButton> radioButtons = new List<RadioButton>();
            [Browsable(true)]
            [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
            public  List<RadioButton> myRadioButtonItems
            {
                get
                {
                    return radioButtons;
                }
                set
                {
                    radioButtons = value;            }
            }      
      
            public diyRadioButtonCell(): base()
            {
                // Use the short date format.
                // this.Style.Format = "d";        }
            public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
            {
                // Set the value of the editing control to the current cell value.
                base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);            //MaskedTextBoxEditingControl mtbec;
                //MaskedTextBoxColumn mtbcol;
                //DataGridViewColumn dgvc;            diyRadioButtonEditingControl mtbec;
                diyRadioButtonColumn mtbcol;
                DataGridViewColumn dgvc;            mtbec = DataGridView.EditingControl as diyRadioButtonEditingControl;            try            {
                    dgvc = this.OwningColumn;
                    if (dgvc is diyRadioButtonColumn)
                    {
                        mtbcol = dgvc as diyRadioButtonColumn;
                        // ctl.myRadioListControl1.myValue = (string)this.Value;                    mtbec.myRadioButtonItem = mtbcol.myRadioButtonItems;// myRadioButtonItems;//this .myRadioButtonItems ;                    mtbec.myValue = (string)this.Value;
                    }            }
                catch { }        }        public override Type EditType
            {
                get
                {
                    // Return the type of the editing contol that CalendarCell uses.
                    return typeof(diyRadioButtonEditingControl);
                }
            }        public override Type ValueType
            {
                get
                {
                    // Return the type of the value that CalendarCell contains.
                    return typeof(String);
                }        }        public override object DefaultNewRowValue
            {
                get
                {
                    // Use the current date and time as the default value.
                    return "空";
                }        }
            protected override void Paint(Graphics graphics,
              Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
              DataGridViewElementStates elementState, object value,
              object formattedValue, string errorText,
              DataGridViewCellStyle cellStyle,
              DataGridViewAdvancedBorderStyle advancedBorderStyle,
              DataGridViewPaintParts paintParts)
            {
                // The button cell is disabled, so paint the border,  
                // background, and disabled button for the cell.
                if (true)
                {
                    // Draw the cell background, if specified.
                    if ((paintParts & DataGridViewPaintParts.Background) ==
                        DataGridViewPaintParts.Background)
                    {
                        SolidBrush cellBackground =
                            new SolidBrush(cellStyle.BackColor);
                        graphics.FillRectangle(cellBackground, cellBounds);
                        cellBackground.Dispose();
                    }                // Draw the cell borders, if specified.
                    if ((paintParts & DataGridViewPaintParts.Border) ==
                        DataGridViewPaintParts.Border)
                    {
                        PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
                            advancedBorderStyle);
                    }                // Calculate the area in which to draw the button.
                    Rectangle buttonArea = cellBounds;
                    Rectangle buttonAdjustment =
                        this.BorderWidths(advancedBorderStyle);
                    buttonArea.X += buttonAdjustment.X;
                    buttonArea.Y += buttonAdjustment.Y;
                    buttonArea.Height -= buttonAdjustment.Height;
                    buttonArea.Width -= buttonAdjustment.Width;                // Draw the disabled button.                
                    //ButtonRenderer.DrawButton(graphics, buttonArea,
                    //    PushButtonState.Disabled);                // Draw the disabled button text. 
                    if (this.RowIndex != -1)
                    {
                        if (this.FormattedValue is String)
                        {                        //  myUCRadioItems b = new myUCRadioItems(); ;                        MyRadioListControl b = new MyRadioListControl();
                            b.myRadioButtonItem = this.myRadioButtonItems;//.myRadioButtonItems;
                            b.BackColor = Color.White;                        // b.myRadioListControl1.myValue = (string)this.Value;// myRadioButtonItem[2].Checked = true;
                            b.myValue = (string)this.Value;// myRadioButtonItem[2].Checked = true;                        #region//区域作图,绘制控件 到cell 里
                            Bitmap bmp = new Bitmap(b.Width, b.Height);                        // b.BackColor = cellStyle.SelectionBackColor;
                            Point currentCellAddress = base.DataGridView.CurrentCellAddress;
                            bool flag = (currentCellAddress.X == base.ColumnIndex) && (currentCellAddress.Y == rowIndex);
                            bool flag2 = flag && (base.DataGridView.EditingControl != null);
                            bool flag3 = (this.State & DataGridViewElementStates.Selected) != DataGridViewElementStates.None;                        //string s = "flag:【" + flag.ToString() + "】,flag2:【" + flag2.ToString() + "】,flag3:【" + flag3.ToString() + "】";
                            //Log.WriteOffLineMsg(s);
                            Color thisColor = b.BackColor = Color.White;
                            if ((flag3) && (!flag2))
                            {
                                thisColor = cellStyle.SelectionBackColor;
                                //b.myRadioListControl1.setRadioButtonTextColor(cellStyle.SelectionForeColor);
                                //b.myRadioListControl1.setBackColor(thisColor);
                                b.setRadioButtonTextColor(cellStyle.SelectionForeColor);
                                b.setBackColor(thisColor);
                            }
                            else
                            {
                                if (DataGridView.SelectedColumns.Contains(this.OwningColumn) || DataGridView.SelectedRows.Contains(this.OwningRow))
                                {
                                    thisColor = cellStyle.SelectionBackColor;
                                    //b.myRadioListControl1.setRadioButtonTextColor(cellStyle.SelectionForeColor);
                                    //b.myRadioListControl1.setBackColor(thisColor);
                                    b.setRadioButtonTextColor(cellStyle.SelectionForeColor);
                                    b.setBackColor(thisColor);
                                }
                                else
                                {
                                    //  thisColor = cellStyle.ForeColor ;
                                    thisColor = cellStyle.BackColor;
                                    //b.myRadioListControl1.setRadioButtonTextColor(cellStyle.ForeColor);
                                    //b.myRadioListControl1.setBackColor(thisColor);                                b.setRadioButtonTextColor(cellStyle.ForeColor);
                                    b.setBackColor(thisColor);
                                }
                            }
                            b.BackColor = thisColor;
                            b.DrawToBitmap(bmp, b.ClientRectangle);                        Point ulCorner = new Point(buttonArea.X, buttonArea.Y);//区域左上角
                            Point urCorner = new Point(buttonArea.X, buttonArea.Bottom);//区域左下角
                            Point llCorner = new Point(buttonArea.Right, buttonArea.Y);//区域右上角
                            Point[] destPara = { ulCorner, llCorner, urCorner };                        // Create rectangle for source image.
                            Rectangle srcRect = new Rectangle(0, 0, buttonArea.Width, buttonArea.Height);//()
                            GraphicsUnit units = GraphicsUnit.Pixel;                        graphics.DrawImage((Image)bmp, destPara, srcRect, units);
                            #endregion                    }
                    }
                }
                else
                {
                    // The button cell is enabled, so let the base class 
                    // handle the painting.                base.Paint(graphics, clipBounds, cellBounds, rowIndex,
                        elementState, value, formattedValue, errorText,
                        cellStyle, advancedBorderStyle, paintParts);
                }
            }
            public void tese()
            {        }        public List<RadioButton> getRadioButtonItems(DataGridView dataGridView)
            {
               
                List<RadioButton> rblist = ((diyRadioButtonEditingControl) dataGridView .EditingControl ).myRadioButtonItem;            return rblist;
            }        public void setRadioButtonItems(DataGridView dataGridView)
            {
     
            }    }
      

  3.   

        class diyRadioButtonEditingControl : MyRadioListControl, IDataGridViewEditingControl
        {
         //  new  public List<RadioButton>   radioButtons = new List<RadioButton>();        [Browsable(true)]
            [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
            public override  List<RadioButton>  myRadioButtonItem
            {
                get
                {
                    return radioButtons;
                }
                set
                {
                    radioButtons = value;
                }
            }
            DataGridView dataGridView;
            private bool valueChanged = false;
            int rowIndex;        public diyRadioButtonEditingControl()
            {            // this.Format = diyControls .MyRadioListControl .f;//DateTimePickerFormat.Short;
            }        // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
            // property.
            public object EditingControlFormattedValue
            {
                get
                {
                    // this .Value 
                    //  return this.myRadioListControl1.myValue;
                    return this.myValue;
                    //  return this.value;// Text;//ToShortDateString();
                }
                set
                {
                    if (value is String)
                    {
                        // this.Tag   =(String)value;
                        // this.myRadioListControl1.myValue = (String)value;
                        this.myValue = (String)value;
                    }
                }
            }        // Implements the 
            // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
            public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
            {
                string s = (string)EditingControlFormattedValue;
                return EditingControlFormattedValue;
            }        // Implements the 
            // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
            public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
            {
                this.Font = dataGridViewCellStyle.Font;            // this.myRadioListControl1.ForeColor = dataGridViewCellStyle.ForeColor;
                // this.myRadioListControl1.BackColor = dataGridViewCellStyle.BackColor;            this.ForeColor = dataGridViewCellStyle.ForeColor;
                this.BackColor = dataGridViewCellStyle.BackColor;
            }
            // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
            // property.
            public int EditingControlRowIndex
            {
                get
                {
                    return rowIndex;
                }
                set
                {
                    rowIndex = value;
                }
            }        // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
            // method.
            public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
            {
                // Let the DateTimePicker handle the keys listed.
                switch (key & Keys.KeyCode)
                {
                    case Keys.Left:
                    case Keys.Up:
                    case Keys.Down:
                    case Keys.Right:
                    case Keys.Home:
                    case Keys.End:
                    case Keys.PageDown:
                    case Keys.PageUp:
                        return true;
                    default:
                        return !dataGridViewWantsInputKey;
                }
            }        // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
            // method.
            public void PrepareEditingControlForEdit(bool selectAll)
            {
                // No preparation needs to be done.
            }        // Implements the IDataGridViewEditingControl
            // .RepositionEditingControlOnValueChange property.
            public bool RepositionEditingControlOnValueChange
            {
                get
                {
                    return false;
                }
            }        // Implements the IDataGridViewEditingControl
            // .EditingControlDataGridView property.
            public DataGridView EditingControlDataGridView
            {
                get
                {
                    return dataGridView;
                }
                set
                {
                    dataGridView = value;
                }
            }        // Implements the IDataGridViewEditingControl
            // .EditingControlValueChanged property.
            public bool EditingControlValueChanged
            {
                get
                {
                    return valueChanged;
                }
                set
                {
                    valueChanged = value;
                }
            }