Laden...

ListBox mit verschiedenen Farben (Hintergrund oder Text)?

Erstellt von CaptainIglo vor 18 Jahren Letzter Beitrag vor 12 Jahren 16.934 Views
C
CaptainIglo Themenstarter:in
366 Beiträge seit 2005
vor 18 Jahren
ListBox mit verschiedenen Farben (Hintergrund oder Text)?

Hi,

wie kann ich in einer ListBox meinen Elementen verschiedene Farben zuordnen?
Egal ob jetzt der Text oder der Hintergrund anderst ist.
Sinn der Sache:
Ein Userliste: User Online -> Grün; User Offline -> Rot.

6 Beiträge seit 2004
vor 18 Jahren

Hi,
muss das eine ListBox sein?
ListView-Items kannst du Farben zuweisen:


lvi = new ListViewItem("Text" , 0, Color.Black, Color.Rot, font);
this.ListView1.Items.Add(lvi);

der Code macht die Schriftfarbe Schwarz, den Hintergrund Rot.

4.221 Beiträge seit 2005
vor 18 Jahren

Wenn es eine ListBox sein soll, dann muss man selber eine machen....


using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace ColorListBox
{
	/// <summary>
	/// Summary description for ColorListBox.
	/// </summary>
	public class ColorListBox : ListBox 
	{
		public ColorListBox():base()
		{
			//Default auf OwnerDrawFixed setzen
			base.DrawMode=DrawMode.OwnerDrawFixed;
		}

		#region Protected Methods
		protected override void OnDrawItem(DrawItemEventArgs e)
		{
			if (e.Index>-1 && e.Index<base.Items.Count)
			{
				//Element eruieren
				object item=this.Items[e.Index];
				//EventArgs aufbereiten
				DefineHowToDrawEventArgs eSetByUser=null;
				if ((e.State & DrawItemState.Selected)==DrawItemState.Selected)
				{
					//Standard für ein selektiertes Item
					eSetByUser= new DefineHowToDrawEventArgs(item,SystemColors.Highlight,SystemColors.HighlightText,this.Font,true);
				}
				else
				{
					//Standard für ein nicht selektiertes Item
					eSetByUser= new DefineHowToDrawEventArgs(item,this.BackColor,this.ForeColor,this.Font,false);
				}

				//Event werfen
				this.OnDefineHowToDraw(eSetByUser);

				//Zeichnen
				Graphics g=e.Graphics;
			
				//Hintergrund für jedes Item
				e.DrawBackground();

				//Hintergrund füllen mit der gewünschten Farbe
				g.FillRectangle(new SolidBrush( eSetByUser.BackColor),e.Bounds);

				//Text Zeichnen
				using (Brush b=new SolidBrush(eSetByUser.ForeColor))
				{
					g.DrawString(item.ToString(),eSetByUser.Font,b,e.Bounds);
				}
				
				//Focus-Rect um das current item ziehen
				e.DrawFocusRectangle();
			}
		}
		#endregion

		#region Private Methods
		private void OnDefineHowToDraw(DefineHowToDrawEventArgs pe)
		{
			if (this.DefineHowToDraw!=null)
			{
				this.DefineHowToDraw(this,pe);
			}
		}
		#endregion

		#region Events
		public event DefineHowToDrawEventHandler DefineHowToDraw;
		#endregion

		#region Properties
		//Default auch für den Designer setzen
		[DefaultValue(DrawMode.OwnerDrawFixed)]
		public override DrawMode DrawMode
		{
			get
			{
				return base.DrawMode;
			}
			set
			{
				base.DrawMode = value;
			}
		}
		#endregion
	}

	public delegate void DefineHowToDrawEventHandler(object sender, DefineHowToDrawEventArgs e);

	public class DefineHowToDrawEventArgs : EventArgs
	{
		#region Fields
		private readonly object _Item;
		private Color _BackColor;
		private Color _ForeColor;
		private Font _Font;
		private readonly bool _Selected;
		#endregion

		#region Constructor
		public DefineHowToDrawEventArgs(object pItem, Color pBackColor, Color pForeColor, Font pFont, bool pSelected):base()
		{
			this._Item=pItem;
			this._BackColor=pBackColor;
			this._ForeColor=pForeColor;
			this._Font=pFont;
			this._Selected=pSelected;
		}
		#endregion

		#region public Properties
		public object Item
		{
			get{return this._Item;}
		}
		public Color BackColor
		{
			get{return this._BackColor;}
			set{this._BackColor=value;}
		}
		public Color ForeColor
		{
			get{return this._ForeColor;}
			set{this._ForeColor=value;}
		}

		public Font Font
		{
			get{return this._Font;}
			set{this._Font=value;}
		}
		public bool Selected
		{
			get{return this._Selected;}
		}

		#endregion
	}
}

So nun muss man nur noch den Event anschnallen und kann jedes Item so pinseln wie man will



		private void colorListBox1_DefineHowToDraw(object sender, ColorListBox.DefineHowToDrawEventArgs e)
		{
			if (e.Selected)
			{
				//In diesem Fall ändere ich nichts... ausser dem FonsStyle kursiv
				//e.BackColor=SystemColors.Highlight;
				//e.BackColor=SystemColors.HighlightText;
				e.Font=new Font(e.Font.FontFamily,e.Font.Size,System.Drawing.FontStyle.Italic);
			}
			else
			{
				//in e.Item ist das Item drin.... wenn man es castet hat man wieder das Item
				//welches man geaddet oder per DataBinding angeschnallt hat
				//in meinem Beispiel ist es ein int 
				int value=int.Parse(e.Item.ToString());

				//wenn der Wert ohne Rest durch 3 teilbar ist, dann mache 
				//bei diesem Item die Schrift Rot
				if (value%3==0)
				{
					e.ForeColor=Color.Red;
				}

				//wenn der Wert ohne Rest durch 5 teilbar ist, dann mache 
				//bei diesem Item den Hintergrund Grün
				if (value%5==0)
				{
					e.BackColor=Color.Green;
				}
			}
		}

Edit: Code angepasst damit auch selektierte Items richtig gezeichnet werden.

Gruss Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

B
189 Beiträge seit 2004
vor 18 Jahren

Vielleicht möchtest du dir auch mal den Artikel ColorListBox bei CodeProject.com anschauen.

C
CaptainIglo Themenstarter:in
366 Beiträge seit 2005
vor 18 Jahren

Thx, hans Code funzt TipTop.

F
40 Beiträge seit 2007
vor 16 Jahren

die colorlistbox muss ich dann manuell einfügen in den code, aber wie kriege ich das hin, dass auch die events der ursprünglichen listbox wieder funktionieren?

bin leider noch ein newbe :>

i kenn mi hoid ned aus

Gelöschter Account
vor 15 Jahren

wie binde ich die box denn in mein windows form ein?

691 Beiträge seit 2007
vor 15 Jahren

Du findest das Control in der Toolbox. Ganz oben steht dann
"Projektname" Components.

mit freundlichen Grüßen,
Tomot

Projekte: www.gesellschaftsspieler-gesucht.de

U
37 Beiträge seit 2008
vor 15 Jahren

Hallo, bin grad über diese farbige ListBox gestolpert und wollte Sie ausprobieren. Das Problem meines Vorgängers habe auch ich. Wie kommt denn die ColorListBox in die ToolBox, damit ich sie von dort auf die WindowsForm ziehen kann?

239 Beiträge seit 2008
vor 15 Jahren

Hallo Minz,

binde die Assembly, die von der ColorListBox geliefert wird, in dein Projekt ein. Meistens checkt VS dann, dass es ein neues Control gibt, und zeigt es sofort in der Toolbox an. Wenn nicht, kannst du in der Toolbox mit einem Rechtsklick und dann "Elemente auswählen" die Assembly suchen, in der sich die ColorListBox befindet und diese einbinden.

Gruß Michbeck1983

Neulich im Computerkurs:
Mein Computer kennt Else nicht! 😁


[URL]XING-Profil[/URL]

U
37 Beiträge seit 2008
vor 15 Jahren

Danke für deine Antwort. Jetzt wollte ich es grad mit Rechtsklick machen und siehe da, nun hat er die ColorListBox irgendwie doch schon in die ToolBox gepackt. Meeeerchwürdig!

J
47 Beiträge seit 2010
vor 13 Jahren

Super Listbox hans!

Hab nur ein Problem: Ich kann irgendwie keine Zeile selektieren bzw. der "blaue selektiert Hintergrund" wird nicht angezeigt.

Weiß jemand eine Lösung dafür? Wäre sehr dankbar über Hilfe!

MfG
Johann

5.299 Beiträge seit 2008
vor 13 Jahren

Mir scheint, das wird zunächst mal so nicht gehen. Dazu müsste nämlich DrawItemEventArgs.State ausgewertet werden, obs System.Windows.Forms.DrawItemState.Selected ist, und dann entsprechend coloriert werden.
Dazu müssten die DefineHowToDrawEventArgs also erstmal entsprechend erweitert werden.

Der frühe Apfel fängt den Wurm.

J
47 Beiträge seit 2010
vor 13 Jahren

Kann es sein dass der Fehler hier liegt?

protected override void OnDrawItem(DrawItemEventArgs e)
        {
           .
.
.

                if (this.SelectedIndices.Contains(e.Index))  // Hier und
                {
                    e.DrawFocusRectangle();                  // hier
                }         .
.
.
            }
        }

Wenn ich nämlich eine Zeile anklicke und mit Breakpoint debugge wird die if-Anweisung immer mit false ausgewertet. Weiß aber nicht wieso.
hans hat auch keine idee oder?

mfg

4.221 Beiträge seit 2005
vor 13 Jahren

Ich habe immer Ideen 😃

Aber das kriegt ihr auch ohne meine Hilfe zum Laufen

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

4.221 Beiträge seit 2005
vor 13 Jahren

Code angepasst (siehe oben) damit auch selektierte Items richtig gezeichnet werden.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

J
47 Beiträge seit 2010
vor 13 Jahren

Vielen herzlichen Dank!

O
449 Beiträge seit 2005
vor 12 Jahren

Hi,


       MyListBoxItem item1 = new MyListBoxItem("Test1", Color.Red);
       MyListBoxItem item2 = new MyListBoxItem("Test1", Color.Green);
       MyListBoxItem item3 = new MyListBoxItem("Test1", Color.Blue);

       lb.Items.Add(item1);
       lb.Items.Add(item2);
       lb.Items.Add(item3);

        public class MyListBoxItem
        {
            public Color Color{get;set;}
            public string Data { get; set; }

            public MyListBoxItem(string data, Color color)
            {
                Color = color;
                Data = data;
            }

            public override string ToString()
            {
                return Data;
            }
        }

        void lb_DefineHowToDraw(object sender, DefineHowToDrawEventArgs e)
        {
            MyListBoxItem item = (MyListBoxItem)e.Item;
            e.ForeColor = item.Color;
        }

Kleine Erweiterung, um die Listbox zu füllen. Hier kann vorher die Farbe definiert werden. Brauchte ich für eine Status-Box, Fehler rot, normal grün usw...

Aber Danke für den Code, sehr hilfreich!

Grüße Oli

Viele Grüße, Oli