.NET Framework - DataGridView flackert

Asked By Robert Oberholzer
20-Nov-09 12:05 PM
Hallo NG

Wenn ich CellFormatting Event folgenden Code habe so
flackert das DataGridView.
Kommentiere ich den Code aus verschwindet das flackern.
Kann mir da jemand helfen?

if
(Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) > 0)
{
if
(Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) >=
Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Richtlinie%"].Value))
{
col = Color.Red;

dgvMfsShareFlow.Rows[e.RowIndex].Cells["Richtlinie%"].Style.BackColor = col;

dgvMfsShareFlow.Rows[e.RowIndex].Cells["DiffNetto%"].Style.BackColor = col;
}
else if
(Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) >=
Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Toleranz%"].Value))
{
col = Color.DarkOrange;

dgvMfsShareFlow.Rows[e.RowIndex].Cells["Toleranz%"].Style.BackColor = col;
dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Style.BackColor
= col;
}
}
else if
(Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) < 0)
{
if
(-Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) >=
Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Richtlinie%"].Value))
{
col = Color.Red;

dgvMfsShareFlow.Rows[e.RowIndex].Cells["Richtlinie%"].Style.BackColor = col;
dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Style.BackColor
= col;
}
else if
(-Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Value) >=
Convert.ToDecimal(dgvMfsShareFlow.Rows[e.RowIndex].Cells["Toleranz%"].Value))
{
col = Color.DarkOrange;

dgvMfsShareFlow.Rows[e.RowIndex].Cells["Toleranz%"].Style.BackColor = col;
dgvMfsShareFlow.Rows[e.RowIndex].Cells["Diff%"].Style.BackColor
= col;
}
}
DataGridViewCellFormattingEventHandler
(1)
DontRepeatYourselfDRY
(1)
System.Windows.Forms
(1)
Convert.ToDecimal
(1)
Color.DarkOrange
(1)
ValueType
(1)
EventArgs
(1)
DataError
(1)
  Frank Dzaebel replied to Robert Oberholzer
20-Nov-09 02:37 PM
Hallo Robert,


Robert, Dein Quellcode missachtet zun??chst recht extrem
das DRY-Prinzip:

[CcdRoterGrad ??? clean-code-developer]
http://www.clean-code-developer.de/wiki/CcdRoterGrad#DontRepeatYourselfDRY

Daraus resultieren schon mal eine Menge zus??tzlicher
Aufrufe, die Du eigentlich alle schon gemacht hast, was
ggf. Performance kostet. Weiterhin wird es recht
un??bersichtlich. Ganz unten habe ein Beispiel, wie man
es etwas verbessern k??nnte.
________________

Das CellFormatting-Ereignis tritt jedesmal auf, wenn
eine Zelle gezeichnet wird. Du solltest deshalb
beim Behandeln dieses Ereignisses eine langwierige
Verarbeitung vermeiden.

________________

Es k??nnen ggf. Exceptions entstehen
Vielleicht behandelst Du das DataError Ereignis,
so dass Du sie nicht siehst, das kann enorm
verz??gern.
_______________

Um anzugeben, dass keine weitere Formatierung
von Werten erforderlich ist, solltest Du die
e.FormattingApplied-Eigenschaft auf true festlegen.
Ist aber wohl bei Dir nicht der Fall.
______________

Es ist merkw??rdig, dass Du jedesmal zu decimal
konvertieren musst, denn normal nimmt man dann
DataGridViewColumn's die schon decimal als ValueType
haben. Dadurch wird die Performance besser und der
Aufwand ebenfalls niedriger.
______________

// Beispiel: (grober Ansatz)
//
using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

DataGridView dgvMfsShareFlow = new DataGridView();
DataGridView dgv;

private void Form1_Load(object sender, EventArgs e)
{
dgv = dgvMfsShareFlow;
Controls.Add(dgv); dgv.Dock = DockStyle.Fill;
dgv.CellFormatting += new DataGridViewCellFormattingEventHandler(
dgv_CellFormatting);
dgv.AllowUserToAddRows = false;
DgvAddColumn("Diff%", typeof(decimal));
DgvAddColumn("Richtlinie%", typeof(decimal));
DgvAddColumn("Toleranz%", typeof(decimal));
DgvAddColumn("DiffNetto%", typeof(decimal));
for (int i = 0; i < 1000; i++)
dgv.Rows.Add(4000m + i, 300m + i, 20m + i, 1m + i);
this.Width = 500;
}

private void DgvAddColumn(string name, Type type)
{
DataGridViewColumn c = new DataGridViewTextBoxColumn();
c.ValueType = typeof(string); c.Name = name;
dgv.Columns.Add(c);
}

private void dgv_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
Color col;
var cells = dgv.Rows[e.RowIndex].Cells;
var diffCell = cells["Diff%"];
var richtlinieCell = cells["Richtlinie%"];
var toleranzCell = cells["Toleranz%"];
var diffNettoCell = cells["DiffNetto%"];

decimal diff = (decimal)diffCell.Value;
decimal richtlinie = (decimal)richtlinieCell.Value;
decimal toleranz = (decimal)toleranzCell.Value;
if (diff > 0)
{
if (diff >= richtlinie)
{
  Robert Oberholzer replied to Frank Dzaebel
25-Nov-09 05:37 AM
Hallo Frank,

Vielen Dank f??r Deine Antwort.
Werde Deine Anmerkungen in Zukunft beherzigen.
Habe meinen Code entsprechend angepasst.
Es funktioniert.

Robert Oberholzer
Create New Account
help
stack: [External Code] some_method(int index = 1) Line 325 + 0x9 bytes C# some_method(object sender = {System.Windows.Forms.TabControl}, System.EventArgs e = {System.EventArgs}) Line 221 + 0x9 bytes C# [External Code] Main() Line Transition] some_method(string text = "50 x 50") Line 346 + 0x9 bytes C# some_method(object sender = {System.Windows.Forms.TabControl}, System.EventArgs e = {System.EventArgs}) Line 233 + 0x3c bytes C# System.Windows.Forms.dll!System.Windows.Forms.TabControl.OnSelectedIndexChanged(System.EventArgs e) + 0x76 bytes System.Windows.Forms
code for each control at form level. Any help is greatly appreciated. BD C# Discussions System.Windows.Forms.ToolStripProgressBar (1) System.Windows.Forms.KeyPressEventHandler (1) System.Windows.Forms.ToolStripStatusLabel (1) System.Windows.Forms.ToolStripMenuItem (1) System.Windows.Forms.ToolStripSeparator (1) System.Windows
mean anything to anyone? Is there any way to track dow the cause of this? System.Windows.Forms.dll! System.Windows.Forms.Control.OnPaint(System.Windows.Forms.PaintEventArgs e) + 0x57 bytes C1.Win.C1FlexGrid.2.dll! C1.Win.C1FlexGrid.Util.BaseControls
void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InvoiceForm)); this.textBox17 = new System.Windows.Forms.TextBox(); this.textBox15 = new System.Windows.Forms.TextBox(); this.textBox7 = new System.Windows.Forms.TextBox(); this.textBox6 = new System.Windows.Forms.TextBox(); this.textBox5 = new System.Windows.Forms
MyProjectShell-API.dll!MyProject.API.UIControls.CodeTable.OnLoad(System.EventArgs e = {System.EventArgs}) Line 196 System.Windows.Forms.dll!System.Windows.Forms.UserControl.OnCreateControl() + 0x24 bytes System.Windows.Forms.dll!System.Windows.Forms.Control.CreateControl(bool fIgnoreVisible) + 0x172 bytes System.Windows.Forms.dll