Hi Leute,
ich hab eine Listbox in deren OnDrawItem-Ereigniss ich die Items zeichne. Soweit so gut, nur ist mir aufgefallen, dass das selektierte Item, wärend der Laufzeit, flackert. Sehr gut zu beobachten ist dies wenn ganz nach unten scrollt und man nicht mehr weiter scrollen kann das selektierte Item noch sichtbar ist und trozdem weiter nach unten scrollt (mit dem Mausrad). AllPaintingInWmPaint ist gesetzt und OptimizedDoubleBuffer auch. Kann jemand dieses Verhalten bestätigen? Hat das jemand vllt schon beobachtet? Ist da vllt was zu machen?
Hier mal ein grobes Beispiel:
protected override void OnDrawItem(DrawItemEventArgs e)
{
Pen p = new Pen(Color.Transparent);
SolidBrush b = new SolidBrush(Color.Transparent);
Graphics dc = e.Graphics;
dc.CompositingQuality = CompositingQuality.HighSpeed;
dc.InterpolationMode = InterpolationMode.HighQualityBicubic;
dc.SmoothingMode = SmoothingMode.HighQuality;
dc.SetColorTableWindowsVista(_clTable);
dc.FillRectangle(new SolidBrush(BackColor), e.Bounds);
dc.DrawVistaButtonBackground(e.Bounds, 2,
true,
false,
(e.State & DrawItemState.Selected) == DrawItemState.Selected
/*(e.State & DrawItemState.Focus) == DrawItemState.Focus*/);
FileData fd = null;
if (e.Index > -1 && e.Index < Items.Count)
fd = Items[e.Index] as FileData;
if (fd != null)
{
if (fd.FileIco != null)
dc.DrawIcon(fd.FileIco, new Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 35, 35));
SizeF sz = dc.MeasureString(fd.FileName, e.Font);
RectangleF rc = new RectangleF(
e.Bounds.Left + 37,
e.Bounds.Top + 5,
e.Bounds.Width - 5,
sz.Height);
StringFormat sf = new StringFormat();
sf.FormatFlags = StringFormatFlags.NoWrap;
sf.Trimming = StringTrimming.EllipsisCharacter;
dc.DrawString(fd.FileName, e.Font, Brushes.White, rc, sf);
sz = dc.MeasureString(fd.FileName, e.Font);
rc = new RectangleF(
e.Bounds.Left + 37,
e.Bounds.Bottom - sz.Height + 2,
e.Bounds.Width - 40,
sz.Height);
sf = new StringFormat();
sf.FormatFlags = StringFormatFlags.NoWrap;
sf.Trimming = StringTrimming.EllipsisPath;
dc.DrawString(fd.File, new Font(e.Font.FontFamily, 6), new SolidBrush(Color.FromArgb(100, 255, 255, 255)),
rc, sf);
}
}
Hi KaiPlain,
ich denke mal das du dir ein eigenes Steuerelement geschrieben hast. Hier musst du nämlich die Double-Buffer-Technik einsetzen die bei einer PictureBox schon standartmäßig aktiv ist.
Grüße
Hallo Chrisi,
Hier musst du nämlich die Double-Buffer-Technik einsetzen
hat KainPlan ja schon.
Hallo KainPlan,
vielleicht hilft aber einer der anderen Tipps aus [FAQ] Flackernde Controls vermeiden / Schnelles, flackerfreies Zeichnen.
herbivore
Da hab ich natürlich schon reingeguckt. Es flackert auch nur das selektierte Item alles andere wird komplett "flüssig" gezeichnet. Man sieht das auch seh schön wenn man einfach Arrow-Down gedrückt hält wärend die LB den fokus hat... ich teste das jetzt gleich mal an einer anderen LB.
Sehr gut zu beobachten ist dies wenn ganz nach unten scrollt und man nicht mehr weiter scrollen kann das selektierte Item noch sichtbar ist und trozdem weiter nach unten scrollt (mit dem Mausrad)
Das kann ich bestätigen. Und das DoubleBuffering des Controls selbst bringt nichts.
Da ich das Problem gerade auch habe, hier meine Lösung: BufferedGraphics.
protected override void OnDrawItem(DrawItemEventArgs e)
{
using (BufferedGraphics bufferedGraphics = BufferedGraphicsManager.Current.Allocate(e.Graphics,e.Bounds))
using (Graphics graphics = bufferedGraphics.Graphics)
{
// Achtung: Zeichenbereich verschiebt sich
Rectangle bounds = new Rectangle(0,0,e.Bounds.Width,e.Bounds.Height);
// entspricht e.DrawBackground()
using (Brush brush = new SolidBrush(e.BackColor))
graphics.FillRectangle(brush,e.Bounds);
// entspricht e.DrawFocusRectangle()
if (e.State.HasFlag(DrawItemState.Focus) && !e.State.HasFlag(DrawItemState.NoFocusRect))
ControlPaint.DrawFocusRectangle(graphics,e.Bounds,this.ForeColor,this.BackColor);
// Checkbox zeichnen (Achtung: Zum Platzieren die ursprünglichen e.Bounds verwenden)
CheckState checkState = this.GetItemCheckState(e.Index);
CheckBoxState checkBoxState = (checkState==CheckState.Checked) ? CheckBoxState.CheckedNormal : (checkState==CheckState.Unchecked) ? CheckBoxState.UncheckedNormal : CheckBoxState.MixedNormal;
Size glyphSize = CheckBoxRenderer.GetGlyphSize(graphics,checkBoxState);
CheckBoxRenderer.DrawCheckBox(graphics,new Point(e.Bounds.X+this.Margin.Left,e.Bounds.Y+(e.Bounds.Height-glyphSize.Height)/2),checkBoxState);
// Text
TextRenderer.DrawText(graphics,...
// alles auf einmal in e.Graphics übertragen
bufferedGraphics.Render();
}
}