Laden...

Wieso wird meine DataGridViewComboBoxCell im DataGridView grau dargestellt?

Erstellt von OXO vor 3 Jahren Letzter Beitrag vor 3 Jahren 665 Views
O
OXO Themenstarter:in
86 Beiträge seit 2020
vor 3 Jahren
Wieso wird meine DataGridViewComboBoxCell im DataGridView grau dargestellt?

Hallo zusammen,

ich hab in einem DataGridView eine Spalte mit DataGridViewComboBoxCell's


dataGridView.CellBorderStyle = DataGridViewCellBorderStyle.Single;
dataGridView.DefaultCellStyle.BackColor = System.Drawing.Color.White;
dataGridView.DefaultCellStyle.SelectionBackColor = System.Drawing.Color.White;
dataGridView.DefaultCellStyle.SelectionForeColor = System.Drawing.Color.Black;
dataGridView.BackgroundColor = System.Drawing.Color.White;
dataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;
dataGridView.EditMode = DataGridViewEditMode.EditOnEnter;


DataGridViewComboBoxCell comboBoxCell = new DataGridViewComboBoxCell();
...
comboBoxCell.Style.BackColor = System.Drawing.Color.White;
comboBoxCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
comboBoxCell.Style.SelectionBackColor = System.Drawing.Color.White;

Mich wundert es, warum per Default meine ComboBox so grau angezeigt wird, obwohl ich überall mit Weiß im Hintergrund arbeite. Auch der Innenraum stellt sich mir beim Ändern des Backgrounds an anderer Stelle nicht auf weiß.

Die Optik aus dem Screenshot links fände ich auch ganz schön, aber egal wo ich Properties ändere, das ändert sich nicht in so ne Optik. Was sollte ich denn da noch setzen, dass so ne schöne Optik raus kommt?

Ebenfalls würde mir gefallen, wenn nach dem Klick in eine Zelle, der Pfeil des DropDowns nach rechts in die Nachbarzelle verschoben ist (also das gesamte DropDown breiter). Finde, das gibt nen schönen optischen Effekt. Ich hab schon mit DisplayEditingControl der Cell etc. im CellPainting-Ereginis herum experimentiert aber es gelingt mir nicht, das zu machen, außerdem flackert es dabei im GridView extrem.

Wie könnte ich das DropDown denn Breiter malen, so dass es aus der Zelle rechts noch ein Stück raus ragt bzw. auch schön in der Zelle selbst eingepasst ist. Aktuell wirkt es ja so, als ob es leicht nach unten verschoben ist, wenn es den Fokus hat? Wo müsste ich schrauben, damit ich da was beeinflussen kann?

16.835 Beiträge seit 2008
vor 3 Jahren

Das nennt sich _unused spaced _und ist ein Standardverhalten vom Control (oder wars GDI?).

Kann aber eigentlich über die BackgroundColor Eigenschaft geändert werden.

O
OXO Themenstarter:in
86 Beiträge seit 2020
vor 3 Jahren

Muss gestehen, das hab ich jetzt leider noch nicht verstanden.

"Unused Spaced" habe ich in den Properties des DataGridView oder der DataGridViewComboBoxCell leider nicht gefunden. (?)

Die BackgroundColor-Eigenschaft des DataGridView hatte ich eigentlich schon auf White gesetzt, aber hat leider nicht den gewünschten Effekt auf die DataGridViewComboBoxCell gebracht. Die ComboBoxCell darunter bleibt leider grau und nicht weiß.

Hinweis von Abt vor 3 Jahren

Bitte keine Full Quotes
[Hinweis] Wie poste ich richtig?

O
OXO Themenstarter:in
86 Beiträge seit 2020
vor 3 Jahren

So, nach Experimentieren bin ich weiter gekommen. Ob das jetzt schön ist, darüber kann man auch geteilter Meinung sein, aber zumindest ein FlatStyle hat ein bisschen was von dem grauen Hintergrund aufgelöst und auch der Pfeil an der ComboBox wird erst einmal nicht mehr per Default angezeigt, sondern erst wenn ich den Fokus in die Zelle setze.


DataGridViewComboBoxCell comboBoxCell = new DataGridViewComboBoxCell();
...
comboBoxCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
comboBoxCell.Style.SelectionBackColor = System.Drawing.Color.White;
comboBoxCell.FlatStyle = FlatStyle.Flat;

Dann waren noch die weiteren Farben und das Highlightings im DropDown ein Problem. Per Default war die Zelle, wenn sie fokussiert war, mit einem blauen Balken und störendem Focus-Rectangle ausgestattet. Mit Selbstzeichnen im DrawItem-Event konnte ich das aufgelösen:


private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
	ComboBox cb = e.Control as ComboBox;
	if (cb != null)
	{
		cb.DropDownStyle = ComboBoxStyle.DropDownList;

		cb.DrawMode = DrawMode.OwnerDrawFixed;
		cb.DrawItem -= this.dataGridViewComboBoxCell_DrawItem;
		cb.DrawItem += this.dataGridViewComboBoxCell_DrawItem;
	}
}


private void dataGridViewComboBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
	if (e.Index == -1)
		return;

	e.DrawBackground();
	
	var comboBoxEditingControl = sender as DataGridViewComboBoxEditingControl;
	if (comboBoxEditingControl == null)
		return;

	Brush brush;
	if (comboBoxEditingControl.DroppedDown)
	{                
		if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
		{
			brush = new SolidBrush(e.BackColor);
			e.Graphics.FillRectangle(brush, e.Bounds);
		}
		else
		{
			brush = new SolidBrush(System.Drawing.Color.White);
			e.Graphics.FillRectangle(brush, e.Bounds);
		}
	}
	else
	{
		brush = new SolidBrush(System.Drawing.Color.White);
		e.Graphics.FillRectangle(brush, e.Bounds);
	}
			   

	var dataRowView = comboBoxEditingControl.Items[e.Index] as DataRowView;
	if (dataRowView == null)
		return;

	string itemText = dataRowView.Row.ItemArray[0].ToString();
	if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
	{
		if (comboBoxEditingControl.DroppedDown)
		{
			brush = Brushes.White;
		}
		else
		{
			brush = Brushes.Black;
		}
	}
	else
	{
		brush = Brushes.Black;
	}
				
	var font = new System.Drawing.Font("Calibri", 11);
	e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
	//e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
	e.Graphics.DrawString(itemText, font, brush, e.Bounds.X-1, e.Bounds.Y-1);
}

Wo ich noch verrückt werde, ist tatsächlich das Zeichnen des Textes mittetls DrawString.
Der AntiAlias bzw. AntiAliasGridFit haben zwar Veränderungen zum Positiven gebracht, aber der Text im fokussierten Zustand schaut trotzdem in der Vergrößerung anders aus. Im einen scheint es einen farbigen Schatten zu geben, wo im anderen die Farben auch fehlen. Ob das wirklich der Unterschied ist, oder was anderes, kann ich nicht sagen. Der Benutzer sieht, dass es zwischen Fokussiertem und nicht Fokussierten Zustand eine Änderung im Text gibt.

Ich hab schon mal ausprobiert, den Text mit dem TextRenderer.DrawString(...) zu zeichnen, aber auch da schaut das etwas komisch aus.

Habt Ihr mir noch Tipps, was ich machen kann, damit die Schrift in der selektierten DataGridViewComboBoxCell, der nicht selektierten und auch den anderen Zellen gleich gerendert werden? Hab ich da noch einen Einflussfaktor, oder muss ich mit selber Zeichnen damit leben?

O
OXO Themenstarter:in
86 Beiträge seit 2020
vor 3 Jahren

Also für meinen Fall hab ich die besten Ergebnisse doch mit dem TextRenderer. Falls jemand ähnliche "Probleme" hat, hier der Code im DrawItem, der für mich funktioniert:


private void dataGridViewComboBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
	if (e.Index == -1)
		return;

	e.DrawBackground();
	
	var comboBoxEditingControl = sender as DataGridViewComboBoxEditingControl;
	if (comboBoxEditingControl == null)
		return;

	Brush brush;
	if (comboBoxEditingControl.DroppedDown)
	{
		if ((e.State & DrawItemState.Focus) == DrawItemState.Focus)
		{
			brush = new SolidBrush(System.Drawing.Color.Transparent);
			e.Graphics.FillRectangle(brush, e.Bounds);
		}
		else
		{
			brush = new SolidBrush(System.Drawing.Color.White);
			e.Graphics.FillRectangle(brush, e.Bounds);
		}
	}
	else
	{
		brush = new SolidBrush(System.Drawing.Color.White);
		e.Graphics.FillRectangle(brush, e.Bounds);
	}


	var dataRowView = comboBoxEditingControl.Items[e.Index] as DataRowView;
	if (dataRowView == null)
		return;

	System.Drawing.Color fontColor;
	string itemText = dataRowView.Row.ItemArray[0].ToString();
	if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
	{
		if (comboBoxEditingControl.DroppedDown)
		{
			fontColor = System.Drawing.Color.White;
		}
		else
		{
			fontColor = System.Drawing.Color.Black;
		}
	}
	else
	{
		fontColor = System.Drawing.Color.Black;
	}

	var cellBounds = e.Bounds;
	cellBounds.X -= 2;
	cellBounds.Y -= 2;

	TextRenderer.DrawText(e.Graphics, itemText, 
		dataGridView.DefaultCellStyle.Font, 
		cellBounds, fontColor, 
		TextFormatFlags.NoPrefix | TextFormatFlags.VerticalCenter);
}