Crear un DataGridView con una columna Radiobutton

Estoy tratando de crear una columna DataGridView alojada con Radiobuttons. he estado siguiendo este Artículo de MSDN.

Aunque he cambiado el código del tutorial para escribir mis propias clases, no funciona como se esperaba. La cosa es que no estoy del todo seguro de lo que me estoy perdiendo. No da errores al compilar. Pero aparece como casillas de verificación en lugar de botones de radio. enter image description here

He adjuntado el proyecto de Visual Studio. aquí. Y para aquellos que no están seguros de descargar archivos adjuntos desconocidos, aquí están las 3 clases que he escrito.

RadiobuttonColumn clase. Hereda el DataGridViewColumn clase.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class RadiobuttonColumn : DataGridViewColumn
    {
        public RadiobuttonColumn()
            : base(new RadiobuttonCell())
        {
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                if (value != null && !value.GetType().IsAssignableFrom(typeof(RadiobuttonCell)))
                {
                    throw new InvalidCastException("Must be a RadiobuttonCell");
                }
            }
        }
    }
}

ACTUALIZADO RadiobuttonCell la clase hereda DataGridViewCell clase.


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

namespace DataGridView_Radiobutton_column
{
    public class RadiobuttonCell : DataGridViewCell
    {
        public RadiobuttonCell()
            : base()
        { 
        }

        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            RadiobuttonEditingControl rdb = DataGridView.EditingControl as RadiobuttonEditingControl;
            if (this.Value == null)
            {
                rdb.Checked = false;
            }
            else
            {
                rdb.Checked = (Boolean)this.Value;
            }
        }

        public override Type EditType
        {
            get
            {
                return typeof(RadiobuttonEditingControl);
            }
        }

        public override Type ValueType
        {
            get
            {
                return typeof(Boolean);
            }
        }

        public override object DefaultNewRowValue
        {
            get
            {
                return false;
            }
        }

        protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            
            Rectangle rectRadioButton = default(Rectangle);

            rectRadioButton.Width = 14;
            rectRadioButton.Height = 14;
            rectRadioButton.X = cellBounds.X + (cellBounds.Width - rectRadioButton.Width) / 2;
            rectRadioButton.Y = cellBounds.Y + (cellBounds.Height - rectRadioButton.Height) / 2;

            ControlPaint.DrawRadioButton(graphics, rectRadioButton, ButtonState.Normal);
        }
    }
}

Las RadiobuttonEditingControl clase hereda el RadioButton clase e implementos IDataGridViewEditingControl Métodos de interfaz.

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class RadiobuttonEditingControl : RadioButton, IDataGridViewEditingControl
    {
        DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        public RadiobuttonEditingControl()
        {
            this.Checked = false;
        }

        public object EditingControlFormattedValue
        {
            get
            {
                return this.Checked = true;
            }
            set
            {
                this.Checked = false;
            }
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return EditingControlFormattedValue;
        }

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
        }

        public int EditingControlRowIndex
        {
            get
            {
                return rowIndex;
            }
            set
            {
                rowIndex = value;
            }
        }

        public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
        {
            switch (key & Keys.KeyCode)
            {
                case Keys.Space:
                    return true;
                default:
                    return !dataGridViewWantsInputKey;
            }
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {
        }

        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false;
            }
        }

        public DataGridView EditingControlDataGridView
        {
            get
            {
                return dataGridView;
            }
            set
            {
                dataGridView = value;
            }
        }

        public bool EditingControlValueChanged
        {
            get
            {
                return valueChanged;
            }
            set
            {
                valueChanged = value;
            }
        }

        public Cursor EditingPanelCursor
        {
            get
            {
                return base.Cursor;
            }
        }

        protected override void OnCheckedChanged(EventArgs eventArgs)
        {
            valueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.Checked = false;
        }
    }
}

Si alguien pudiera echar un vistazo a esto y señalarme la dirección correcta en cuanto a qué cambios se deben hacer en el código, estaría agradecido.

Gracias por su atención.

preguntado el 27 de julio de 12 a las 21:07

1 Respuestas

¿Qué sucede cuando comienzas a editar una celda? Se convierte en un botón de radio.

Esto se debe a que derivó de una celda de casilla de verificación que se pinta a sí misma como una casilla de verificación.

La DGV no es una grilla de controles. Es una cuadrícula de cuadros que se pintan para que parezcan controles hasta que el usuario intenta editar una celda. En ese momento, el DGV mueve el (único) control de edición de la celda a su posición y lo hace visible para que el usuario interactúe con él.

Vas a tener que derivar de la clase base DataGridViewCell e implementar todo el código de pintura también.

El código de ejemplo no tiene que hacer esto porque una celda de cuadro de texto sabe cómo pintar texto.

Actualizado

Las Pintura de control la clase puede ayudarte.

Respondido 28 Jul 12, 00:07

Gracias Tergiver por la respuesta. he cambiado el RadiobuttonCell clase como usted ha instruido. Por favor, vea el código actualizado en mi publicación original. he heredado el DataGridViewCell clase y anuló el Paint método. Sin embargo, me enfrento a un pequeño problema. El fondo de DataGridView aparece transparente. Aquí es una captura de pantalla. ¿Cómo puedo superar este problema? - Isuru

@ nK0de También tienes que pintar el fondo. Use el estilo de la celda para determinar si la celda está seleccionada o no. Creo que puedes usar graphics.Clear(cellStyle.BackColor : cellStyle.SelectedColor). También desea pintar el botón de opción según el valor actual de la celda. - Tergiver

@nK0de Además, el dibujo se realiza en fases, por lo que desea usar el parámetro paintParts para determinar qué parte se supone que debe pintar. - Tergiver

@nK0de Eché un vistazo al código fuente (de ILSpy) de DataGridViewCheckBoxCell. Deberías mirarlo tú mismo. Lo primero a tener en cuenta es que no utilizan un control de edición en el lugar (devuelven nulo para EditType), manejan tanto la pintura como la interacción. La pintura es bastante compleja porque maneja los estilos visuales correctamente, pero el código le muestra cómo pintar cada parte (borde, fondo, enfoque, primer plano e ícono de error). - Tergiver

@nK0de Realmente no hay mucho en el camino de GDI allí, ya que usan el código de clase base para la mayoría de los bits y un VisualRenderer o ControlPaint dependiendo de si los estilos visuales están habilitados o no para el resto de la pintura. ControlPaint es simple, VisualRenderer es un poco monstruoso. No creo que debas copiar y pegar, pero revisa ese código y usa MSDN para conocer las partes específicas que quizás no entiendas, o haz preguntas aquí. - Tergiver

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.