none
Combobox in Datagridview RRS feed

  • Domanda

  • Buongiorno,

    ho la necessità di poter cambiar il colore del carattere dentro i combobox in unda datagridview.

    In un normale combobox (non interno ad una datagridview) basta intercettare l'evento del tipo: Combobox1_drawItem con il codice seguente:

    private void combobox1_DrawItem(object sender, DrawItemEventArgs e)
            {
                e.DrawBackground();
                if (e.Index > -1)
                {
                    Font oldFont = new Font("Arial", 10, FontStyle.Regular);
                    Font newFont = new Font("Arial", 10, FontStyle.Bold);
                    if (Lista.Contains(combobox1.Items[e.Index].ToString()) == true)
                    {
                        e.Graphics.DrawString(combobox1.Items[e.Index].ToString(),
                                     newFont,
                                     new SolidBrush(Color.Red),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                    else
                    {
                        e.Graphics.DrawString(combobox1.Items[e.Index].ToString(),
                                     oldFont,
                                     new SolidBrush(Color.Black),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                }
            }

    Dovrei fare la stessa cosa in una DataGridViewComboBoxColumn o forse meglio in una DataGridViewComboBoxCell. Ma tali oggetti a me risulta non abbiano l'evento DrawItem utilizzato nei combobox. Come posso fare?

    grazie .

    Nicola

    lunedì 22 aprile 2013 06:43

Risposte

  • Ciao Carmelo,

    devo dissentire da te poichè io devo cambiare il colore del carattere in fase di disegno degli item del combobox così che quando clicco sul controllo gli items sono gia stati filtrati con il colore appropriato. In altre parole l'evento da utilizzare è prorio Drawitem. Nel mio caso se l'tem è contenuto in una lista avrà il carattere rosso altrimenti nero. Ti posto il codice e quindi la soluzione, dove ListaOpzioni2 è il form contenente il combobox:

     private void ListaOpzioni2_Load(object sender, EventArgs e)
            {
              AddEvents();
           }
    
            private void AddEvents()
            {
                OpzionidataGrid.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(
                    OpzionidataGrid_EditingControlShowing);
            }
    
            private void OpzionidataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                combo = e.Control as ComboBox;
    
                if (combo != null)
                {
                    combo.DrawMode = DrawMode.OwnerDrawFixed;
                    combo.DrawItem -= new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                    combo.DrawItem += new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                }
            }
    
    
            private void combo_DrawItem(object sender, DrawItemEventArgs e)
            {
                e.DrawBackground();
                ComboBox cmb = sender as ComboBox;
                
                if (e.Index > -1)
                {
                    Font oldFont = new Font("Arial", 10, FontStyle.Bold);
                    Font newFont = new Font("Arial", 10, FontStyle.Bold);
                    if (Lista.Contains(cmb.Items[e.Index].ToString()) == true)
                    {
                        e.Graphics.DrawString(cmb.Items[e.Index].ToString(),
                                     newFont,
                                     new SolidBrush(Color.Red),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                    else
                    {
                        e.Graphics.DrawString(cmb.Items[e.Index].ToString(),
                                     oldFont,
                                     new SolidBrush(Color.Black),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                }
            }

    • Contrassegnato come risposta Nicola Mod domenica 5 maggio 2013 17:13
    domenica 5 maggio 2013 17:12

Tutte le risposte

  • Ciao Nicola,

    puoi dare uno sguardo a questo articolo tratto da Msdn , il quale aggiunge un controllo DataGrid , con all'interno un controllo DataGridViewComboboxCell , gestendo poi l'evento SelectedIndexChanged viene impostato mediante la proprietà BackColor il colore di sfondo della cella , per provarlo devi eseguire qualche accorgimento , creare l'eventlo load del Form e vai a richiamare il metodo AddColorColumn() dove viene configurata la DataGridViewComboboxCell , ed in fondo al metodo AddColorColumn aggiungi l'istruzione this.Controls.Add(datagridview1); che corrisponde al controllo DataGridView che vedi come oggetto creato in designer , all'interno dell'evento SelectedIndexChanged e impostata la proprietà BackColor , dovrai sostituirla con ForeColor , dovrebbe essere quello che chiedi ovviamente da adattare poi alle tue esigenze.

    http://msdn.microsoft.com/it-it/library/system.windows.forms.datagridviewcomboboxeditingcontrol.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

    Ciao.


    martedì 23 aprile 2013 13:10
  • Ciao Carmelo,

    l'esempio, come tu dicevi, dovevo adattarlo alle mie esigenze ma putroppo non riesco a farlo funzionare, in pratica ho sostituito l'evento IndexChanged con DrawItem, facendo un po di debug ho notato però che nel EventHandler combo_DrawItem non ci passa mai! Ti posto un po di codice:

    private void ListaOpzioni2_Load(object sender, EventArgs e)
            {
                 AddColorColumn();
            }
    
            private void AddColorColumn()
            {
                DataGridViewComboBoxColumn comboBoxColumn = new DataGridViewComboBoxColumn();
                comboBoxColumn.Items.AddRange(Color.Red, Color.Yellow, Color.Green, Color.Blue);
                comboBoxColumn.ValueType = typeof(Color);
                OpzionidataGrid.Columns.Add(comboBoxColumn);
                OpzionidataGrid.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(
                    OpzionidataGrid_EditingControlShowing);
            }
    
            private void OpzionidataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                combo = e.Control as ComboBox;
                if (combo != null)
                {
                    combo.DrawItem -= new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                    //combo.SelectedIndexChanged -=
                    //    new EventHandler(ComboBox_SelectedIndexChanged);
    
                    combo.DrawItem += new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                    //combo.SelectedIndexChanged +=
                    //    new EventHandler(ComboBox_SelectedIndexChanged);
                }
            }
          
            private void combo_DrawItem(object sender, DrawItemEventArgs e)
            {
                e.DrawBackground();
                if (e.Index > -1)
                {
                    Font oldFont = new Font("Arial", 10, FontStyle.Regular);
                    Font newFont = new Font("Arial", 10, FontStyle.Bold);
                    //if (Lista.Contains(combo.Items[e.Index].ToString()) == true)
                    if (combo.Items[e.Index].ToString() == "Red")
                    {
                        e.Graphics.DrawString(combo.Items[e.Index].ToString(),
                                     newFont,
                                     new SolidBrush(Color.Red),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                    else
                    {
                        e.Graphics.DrawString(combo.Items[e.Index].ToString(),
                                     oldFont,
                                     new SolidBrush(Color.Black),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                }
            }

    venerdì 26 aprile 2013 14:24
  • Ciao Carmelo,

    l'esempio, come tu dicevi, dovevo adattarlo alle mie esigenze ma putroppo non riesco a farlo funzionare, in pratica ho sostituito l'evento IndexChanged con DrawItem, facendo un po di debug ho notato però che nel EventHandler combo_DrawItem non ci passa mai!        

    l'evento drawitem , secondo quanto letto su Msdn "ComboBox." id="mt2" xml:space="preserve">Questo evento viene utilizzato da un controllo ComboBox con disegno personalizzato. È possibile utilizzare questo evento per eseguire le attività necessarie per disegnare gli elementi nel controllo ComboBox." , nel tuo caso devi semplicemente cambiare il colore del testo e non disegnare elementi nel controllo  da quanto ho capito, per cui ti e sufficiente gestire l'evento SelectedIndexChanged e gestire al suo interno la valorizzazione della proprietà Foreground , per cui il tuo codice finale potrebbe essere così strutturato.

            private void Form1_Load(object sender, EventArgs e)
            {
                AddColorColumn();           
            }
    
            private void AddColorColumn()
            {
                var comboBoxColumn =
                    new DataGridViewComboBoxColumn();
                comboBoxColumn.Items.AddRange(
                    Color.Red, Color.Yellow, Color.Green, Color.Blue);
                comboBoxColumn.ValueType = typeof(Color);
                OpzionidataGrid.Columns.Add(comboBoxColumn);
                OpzionidataGrid.EditingControlShowing +=
                    new DataGridViewEditingControlShowingEventHandler(
                    OpzionidataGrid_EditingControlShowing);
            }
    
            private void OpzionidataGrid_EditingControlShowing(object sender,
                DataGridViewEditingControlShowingEventArgs e)
            {
                var combo = e.Control as ComboBox;
                if (combo != null)
                {
                    // Remove an existing event-handler, if present, to avoid 
                    // adding multiple handlers when the editing control is reused.
                    combo.SelectedIndexChanged -=
                        new EventHandler(ComboBox_SelectedIndexChanged);
    
                    // Add the event handler. 
                    combo.SelectedIndexChanged +=
                        new EventHandler(ComboBox_SelectedIndexChanged);
                }
            }
    
            private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
            {
                ((ComboBox)sender).ForeColor = (Color)((ComboBox)sender).SelectedItem;
            }

    Ti lascio per riferimento la pagine di msdn 

    http://msdn.microsoft.com/it-it/library/system.windows.forms.combobox.drawitem.aspx

    Ciao.



    • Modificato Carmelo La Monica venerdì 26 aprile 2013 17:42
    • Contrassegnato come risposta Nicola Mod domenica 5 maggio 2013 17:11
    • Contrassegno come risposta annullato Nicola Mod domenica 5 maggio 2013 17:11
    venerdì 26 aprile 2013 17:08
  • Ciao Carmelo,

    devo dissentire da te poichè io devo cambiare il colore del carattere in fase di disegno degli item del combobox così che quando clicco sul controllo gli items sono gia stati filtrati con il colore appropriato. In altre parole l'evento da utilizzare è prorio Drawitem. Nel mio caso se l'tem è contenuto in una lista avrà il carattere rosso altrimenti nero. Ti posto il codice e quindi la soluzione, dove ListaOpzioni2 è il form contenente il combobox:

     private void ListaOpzioni2_Load(object sender, EventArgs e)
            {
              AddEvents();
           }
    
            private void AddEvents()
            {
                OpzionidataGrid.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(
                    OpzionidataGrid_EditingControlShowing);
            }
    
            private void OpzionidataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                combo = e.Control as ComboBox;
    
                if (combo != null)
                {
                    combo.DrawMode = DrawMode.OwnerDrawFixed;
                    combo.DrawItem -= new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                    combo.DrawItem += new System.Windows.Forms.DrawItemEventHandler(combo_DrawItem);
                }
            }
    
    
            private void combo_DrawItem(object sender, DrawItemEventArgs e)
            {
                e.DrawBackground();
                ComboBox cmb = sender as ComboBox;
                
                if (e.Index > -1)
                {
                    Font oldFont = new Font("Arial", 10, FontStyle.Bold);
                    Font newFont = new Font("Arial", 10, FontStyle.Bold);
                    if (Lista.Contains(cmb.Items[e.Index].ToString()) == true)
                    {
                        e.Graphics.DrawString(cmb.Items[e.Index].ToString(),
                                     newFont,
                                     new SolidBrush(Color.Red),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                    else
                    {
                        e.Graphics.DrawString(cmb.Items[e.Index].ToString(),
                                     oldFont,
                                     new SolidBrush(Color.Black),
                                     new Rectangle(e.Bounds.Location, e.Bounds.Size));
                    }
                }
            }

    • Contrassegnato come risposta Nicola Mod domenica 5 maggio 2013 17:13
    domenica 5 maggio 2013 17:12
  • Ciao Nicola Mod,

    grazie per aver condiviso la soluzione con il resto della Community.

    Ciao.


    domenica 5 maggio 2013 17:15