Jak pokolorować text pojedynczych item'ów w listbox'ie ?
Dzięki !
Mam jeszcze pytanie jak zrobić aby to cały czas zmieniło kolor a nie tylko w momencie kliknięcia w listbox?
Chodzi Ci o to?
listBox1.ForeColor = System.Drawing.Color.Blue;
Chodzi mi to o to, że ta funkcja działa ale tylko w momencie kliknięcia w listbox. A ja odbieram dane z urządzeń zewnętrznych i muszę w zależności od odebranych zmienić kolor konkretnego itemu na bieżąco a nie jak użytkownik kliknie listbox..
Coś w tym stylu:
if(odebrane_dane[3] == 1)
{
listBox1.items[1] = Color.Red.
}
Łap przykład:
public struct ItemData
{
public Color ItemColor;
public string ItemCaption;
public ItemData(string _ItemCaption, Color _ItemColor)
{
ItemColor = _ItemColor;
ItemCaption = _ItemCaption;
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ListBox_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
ItemData Data = (ItemData)((ListBox)sender).Items[e.Index];
Font myFont = e.Font;
Brush myBrush = new SolidBrush(Data.ItemColor);
e.DrawBackground();
e.Graphics.DrawString(Data.ItemCaption, myFont, myBrush, e.Bounds, StringFormat.GenericDefault);
}
private void button1_Click(object sender, EventArgs e)
{
Random randonGen = new Random();
listBox1.DrawMode = DrawMode.OwnerDrawFixed;
listBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(ListBox_DrawItem);
listBox1.BeginUpdate();
for (int i = 1; i <= 10; i++)
{
Color randomColor = Color.FromArgb(randonGen.Next(255), randonGen.Next(255), randonGen.Next(255));
listBox1.Items.Add(new ItemData("test", randomColor));
}
listBox1.EndUpdate();
}
}
EDIT// jak chcesz modyfikować dane item (np. kolor) w dowolnym momencie to zmień ItemData strukturę na klasę:
public class ItemData
{
public ItemData(string _ItemCaption, Color _ItemColor)
{
ItemColor = _ItemColor;
ItemCaption = _ItemCaption;
}
public Color ItemColor {get; set;}
public string ItemCaption {get; set;}
}
i prosty przykład modyfikacji danych:
if (listBox1.SelectedIndex >= 0) {
ItemData Data = (ItemData)listBox1.Items[listBox1.SelectedIndex];
Data.ItemColor = Color.FromArgb(0, 0, 0);
Data.ItemCaption = "dupa";
listBox1.Refresh();
}
adam_c napisał(a):
Chodzi mi to o to, że ta funkcja działa ale tylko w momencie kliknięcia w listbox. A ja odbieram dane z urządzeń zewnętrznych i muszę w zależności od odebranych zmienić kolor konkretnego itemu na bieżąco a nie jak użytkownik kliknie listbox..
Coś w tym stylu:
if(odebrane_dane[3] == 1)
{
listBox1.items[1] = Color.Red.
}
Prawie. Generalnie jak zmieniasz coś w tle, to musisz dać znać, że to może wymagać odświeżenia
if(odebrane_dane[3] == 1)
{
listBox1.Items[1] = Color.Red; //czy jak tam powinno być ;)
listBox1.Invalidate();
}
Dzięki @kAzek, działa ładnie ale mam jeszcze jedno pytanie.
Podczas gdy odbieram dane analizuje to co przyszło i zmieniam kolor tak :
// KOLORY
if (transmisja.odebrane_dane[9] == 145)
{
ItemData Data = (ItemData)listBox1.Items[0];
Data.ItemColor = Color.Red;
listBox1.Refresh();
}
else
{
ItemData Data = (ItemData)listBox1.Items[0];
Data.ItemColor = Color.Black;
listBox1.Refresh();
}
Problem w tym, że za każdym razem jak odbieram dane to efektem ubocznym jest migotanie okna. Jak można to wyeliminować ?
Nie wiem gdzie odbierasz te dane ale całkowicie usuń listBox1.Refresh();
a jak nie będzie się prawidłowo odświeżało zmień to na:
Rectangle r = listBox1.GetItemRectangle(IndexItem);
listBox1.Invalidate(r);
EDIT// @adam_c tak poza tym być może niepotrzebnie zbyt często zmieniasz kolor sprawdzaj przed zmianą czy item nie ma już ustawionego właściwego koloru (po prostu odczytujesz Data.ItemColor
i porównujesz z potrzebnym) i dopiero jeżeli nie ma to zmieniaj.
Problem był ze zbyt częsta zmianą koloru. Zapytanie o dane jest co 0,2s więc dane wracają bardzo szybko co skutkowało częstym migotaniem.
Zrobiłem tak jak radziłeś aby sprawdzać kolor i to rozwiązało sprawę.
Bardzo Ci dziękuję za pomoc w rozwiązaniu problemu.
Dziękuje i pozdrawiam !