0

Ich habe dieses Problem. Es beginnt wie folgt aus:Ausnahme beim Hinzufügen einer neuen Zeile zu meinem DataGridView

Begin

Ich kann doppelklicken Sie auf den Dropdown-Pfeil und eine Farbe OK wählen:

Pick colour

An diesem Punkt kann ich das Drop-down erneut auf und es ist richtig gewählt:

Selected

Das Problem ist, wenn ich t wollen o füge eine neue Zeile hinzu. Auch wenn ich nur auf der neuen Zeile Zelle gehen zu klicken:

Click new row

ich dann Daten ein Datenfehler Ausnahme:

Exception

Danach wird die vorherige Zelle zieht falsch:

enter image description here

Ich kann nicht ganz herausfinden, wie man das löst.

Mein Code:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Xml.Linq; 
using Teigha.Core; 
using Teigha.TD; 

namespace Viewer 
{ 
    public partial class Editor : Form 
    { 
     uint[] _CurPalette = Teigha.Core.AllPalettes.getDarkPalette(); 

     public Editor() 
     { 
      InitializeComponent(); 
     } 

     private void Editor_Load(object sender, EventArgs e) 
     { 
      DataGridViewComboBoxColumn cboColumn = new DataGridViewComboBoxColumn(); 
      cboColumn.Name = "Color"; 

      List<ushort> listColors = new List<ushort>(); 
      listColors.Add(1); 
      listColors.Add(2); 
      listColors.Add(3); 
      listColors.Add(4); 
      listColors.Add(5); 
      listColors.Add(6); 
      listColors.Add(7); 
      listColors.Add(8); 
      listColors.Add(9); 
      listColors.Add(250); 
      listColors.Add(251); 
      listColors.Add(252); 
      listColors.Add(253); 
      listColors.Add(254); 
      listColors.Add(255); 

      foreach (ushort iColorIndex in listColors) 
      { 
       using (OdCmColor oColor = new OdCmColor()) 
       { 
        oColor.setColorIndex(iColorIndex); 
        ComboboxColorItem oColorItem = new ComboboxColorItem(
         oColor.colorNameForDisplay(), 
         iColorIndex, 
         Color.FromArgb(oColor.red(), oColor.green(), oColor.blue())); 
        cboColumn.Items.Add(oColorItem); 
       } 
      } 

      this.DataGridView1.Columns.Add(cboColumn); 
     } 

     private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
     { 
      if (e.Control is ComboBox) 
      { 
       ComboBox theCB = (ComboBox)e.Control; 
       theCB.DrawMode = DrawMode.OwnerDrawFixed; 
       try 
       { 
        theCB.DrawItem -= new DrawItemEventHandler(this.combobox1_DrawItem); 
       } 
       catch { } 
       theCB.DrawItem += new DrawItemEventHandler(this.combobox1_DrawItem); 
      } 
     } 

     private void combobox1_DrawItem(object sender, DrawItemEventArgs e) 
     { 
      Graphics g = e.Graphics; 
      Color c = Color.Empty; 
      string s = ""; 
      Brush br = SystemBrushes.WindowText; 
      Brush brBack; 
      Rectangle rDraw; 
      bool bSelected = Convert.ToBoolean(e.State & DrawItemState.Selected); 
      bool bValue = Convert.ToBoolean(e.State & DrawItemState.ComboBoxEdit); 

      rDraw = e.Bounds; 
      rDraw.Inflate(-1, -1); 

      if (bSelected & !bValue) 
      { 
       brBack = Brushes.LightBlue; 
       g.FillRectangle(Brushes.LightBlue, rDraw); 
       g.DrawRectangle(Pens.Blue, rDraw); 
      } 
      else 
      { 
       brBack = Brushes.White; 
       g.FillRectangle(brBack, e.Bounds); 
      } 

      try 
      { 
       //s = ((ComboBox)sender).Items[e.Index].ToString(); 
       ComboboxColorItem oColorItem = (ComboboxColorItem)((ComboBox)sender).Items[e.Index]; 
       s = oColorItem.ToString(); 
       c = oColorItem.Value; 
      } 
      catch 
      { 
       s = "red"; 
       c = Color.Red; 
      } 

      SolidBrush b = new SolidBrush(c); 
      Rectangle r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 3, 10, 10); 
      g.FillRectangle(b, r); 
      g.DrawRectangle(Pens.Black, r); 
      g.DrawString(s, Form.DefaultFont, Brushes.Black, e.Bounds.Left + 25, e.Bounds.Top + 1); 

      b.Dispose(); 
      g.Dispose(); 
     } 

     private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) 
     { 
      MessageBox.Show(e.Exception.ToString()); 
     } 
    } 

    public class ComboboxColorItem 
    { 
     public string Name { get; } 
     public ushort Index { get; } 
     public Color Value { get; } 

     public ComboboxColorItem(string Name, ushort Index, Color Value) 
     { 
      this.Name = Name; 
      this.Index = Index; 
      this.Value = Value; 
     } 
     public override string ToString() 
     { 
      return Name; 
     } 
    } 
} 

Update:

Wenn ich diesen Code in das Ereignis Form Last gelegt:

this.DataGridView1.Rows.Add(new ComboboxColorItem("red", 1, Color.Red)); 

Dann habe ich sofort die Ausnahme erhalten.

Ich habe versucht, einen sekundären Standardkonstruktors hinzufügen und es machte keinen Unterschied:

public class ComboboxColorItem 
{ 
    public string Name { get; set; } 
    public ushort Index { get; set; } 
    public Color Value { get; set; } 

    public ComboboxColorItem() 
    { 
     this.Name = "red"; 
     this.Index = 1; 
     this.Value = Color.Red; 
    } 
    public ComboboxColorItem(string Name, ushort Index, Color Value) 
    { 
     this.Name = Name; 
     this.Index = Index; 
     this.Value = Value; 
    } 
    public override string ToString() 
    { 
     return Name; 
    } 
} 

Ich habe auch versucht, dies zu dem Load-Ereignis hinzu:

cboColumn.ValueType = typeof(ComboboxColorItem); 

keinen Unterschied gemacht haben.

Update:

ich die CellParsing Antwort verwendet haben, und ich scheine nicht mehr gab Abstürze:

CellParsing results

Mein einziger Kommentar ist jetzt, dass ich hatte gehofft, dass der Block der Farbe bleiben würde sichtbar in der Zelle. Aber ich sehe nur den Farbblock, wenn ich auf den Drop-Pfeil klicke. Ist das eine separate Frage?

Antwort

1

DataGridView hat Probleme mit Parsing das ausgewählte Farbelement. Ich schlage vor, dass Sie benutzerdefinierte Parsing-Logik auf diese Spalte anwenden:

DataGridView1.CellParsing += ColorCellParsing; 

private void ColorCellParsing(object sender, DataGridViewCellParsingEventArgs e) 
{ 
    var grid = (DataGridView)sender; 
    var column = grid.Columns[e.ColumnIndex] as DataGridViewComboBoxColumn; 
    if (column == null || column.Name != "Color") 
     return; 
    foreach (ComboboxColorItem item in column.Items) 
    { 
     if (item.Name == (string) e.Value) 
     { 
      e.Value = item; 
      e.ParsingApplied = true; 
      break; 
     }  
    } 
} 
+0

Danke. Das scheint auch nicht zu funktionieren. Ich dachte, es half zuerst. –

+0

Ich merke, dass in Ihrem Beispiel und in meinem Debuggen wir nur auf den Text Wert suchen. Aber wir haben auch das eigentliche Objekt Farbe. Wie analysieren wir das? –

+0

@AndrewTruckle, Name der Farbe ist, dass 'e.Value' (wegen ToString() - Implementierung zurückgibt. aber es ist möglich, ValueMember der Spalte' cboColumn.ValueMember = "Index" zu ändern; ' – ASh

0

Wenn Sie etwas wollen andere als Zeichenketten bekommen, die ValueType der Säule typeof(<data type>)
zum Beispiel gesetzt, wenn es

int
this.gridViewSettings.Columns("columnName").ValueType= typeof(Int32); 

oder

this.ComboboxCellcolumnName.ValueType = typeof(int); 
+0

Danke. Ich habe gerade versucht, den Stern zu treffen und den gleichen Fehler zu bekommen. –

+0

Danke. Ich habe versucht sowohl 'cboColumn.ValueType = typeof (Color);' und 'cboColumn.ValueType = typeof (ComboboxColorItem);' und es scheint keinen Unterschied zu machen. :( –