|
Hi Richard,
Thanks for the reply.
I tried altering the DrawItemEventArgs e but could not and tried using something like:
void listBox_DrawItem(object sender, DrawItemEventArgs e, string color)
but that wouldn't work either, so I'm a little stumped.
How can I pass an additional variable to void listBox_DrawItem? If I can figure out how to do that, I'll be able to do the rest.
|
|
|
|
|
And how do you suppose you'll pass the additional parameter? Isn't it the framework that calls your handler (listBox_DrawItem ) ?
As I said, you cannot change the signature of the function from what the framework expects it to be.
The way to solve your problem is to have a separate function that gets called from within the event handler:
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
Color drawColor = GetColorFromItem(e.Index);
.....
}
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hi Richard,
Yes you confirmed my earlier failures , I was hoping you could help prod me in the direction of success with some elaboration on your suggested solution.
If I cannot pass a variable to the method, do I need to have the method check some global variables for it to be able to know which color? Is that what you were thinking?
|
|
|
|
|
Oh I see. Well, I would say the solution really depends upon how you determine what color needs to be used.
Is it from a lookup table? Is it computed from some numerical values? Or maybe it's from an enumeration?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hi Richard,
I don't have the code here at home, I'd like to set the color each time I call the event and then set it back to the default with the following line of code. Maybe something like
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index > -1)
{
if (globalFlag == "red")
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
else if (globalFlag == "green")
e.Graphics.FillRectangle(Brushes.Green, e.Bounds);
else
e.DrawBackground();
using (Brush textBrush = new SolidBrush(e.ForeColor))
{
e.Graphics.DrawString(lbxOutput.Items[e.Index].ToString(), e.Font, textBrush, e.Bounds.Location);
}
}
}
but I tried the above before and I couldn't get the line
e.Graphics.DrawString(lbxOutput.Items[e.Index].ToString(), e.Font, textBrush, e.Bounds.Location);
to function properly, so I was hoping for some wisdom with that.
|
|
|
|
|
turbosupramk3 wrote: to function properly
What was it doing wrong?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I can't pass the string, of what I want to write to the list box, in the event handler it uses [e.index].ToString() to pass text, but I'm back at my original problem of not being able to pass any additional variables to the listBox_DrawItem method so that I can tell it not only which color to use, but what string I want it to write to the listbox.
Any ideas on how to get around this limitation?
|
|
|
|
|
turbosupramk3 wrote: Any ideas on how to get around this limitation?
Yes, you implement a separate function that returns the correct string to use, and then you call that function from within the event handler.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
So is this what you envision? I've never encountered this before today, so there may be a better way to do this, but this is the first idea that comes to mind?
public string globalFlag = "";
public string globalListBoxText = "";
private void someFunction()
{
}
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index > -1)
{
if (globalFlag == "red")
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
else if (globalFlag == "green")
e.Graphics.FillRectangle(Brushes.Green, e.Bounds);
else
e.DrawBackground();
using (Brush textBrush = new SolidBrush(e.ForeColor))
{
e.Graphics.DrawString(lbxOutput.Items[e.Index].ToString(), e.Font, textBrush, e.Bounds.Location);
}
}
}
|
|
|
|
|
More like:
private string GetColorForItem( int Index )
{
}
private string GetStringForItem( int Index )
{
}
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index > -1)
{
string colorToUse = GetColorForItem(e.Index);
string textToUse = GetStringForItem(e.Index);
if (colorToUse == "red")
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
else if (colorToUse == "green")
e.Graphics.FillRectangle(Brushes.Green, e.Bounds);
else
e.DrawBackground();
using (Brush textBrush = new SolidBrush(e.ForeColor))
{
e.Graphics.DrawString(textToUse, e.Font, textBrush, e.Bounds.Location);
}
}
}
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Thanks for the code, I will try that tomorrow.
One more question, with the code block below, how do I integrate or manipulate the e.index portion of it, so I can set it before calling the two method examples you provided?
public FormMain()
{
InitializeComponent();
listBox.DrawMode = DrawMode.OwnerDrawFixed;
listBox.DrawItem += new DrawItemEventHandler(listBox_DrawItem);
listBox.Items.AddRange(new object[] { "A", "B", "C" });
}
Quote: private string GetColorForItem( int Index )
{
// return correct color name
}
private string GetStringForItem( int Index )
{
// return correct string
}
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index > -1)
{
string colorToUse = GetColorForItem(e.Index);
string textToUse = GetStringForItem(e.Index);
if (colorToUse == "red")
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
else if (colorToUse == "green")
e.Graphics.FillRectangle(Brushes.Green, e.Bounds);
else
e.DrawBackground();
using (Brush textBrush = new SolidBrush(e.ForeColor))
{
e.Graphics.DrawString(textToUse, e.Font, textBrush, e.Bounds.Location);
}
}
}
|
|
|
|
|
I believe the Index property is set by the framework before it calls your DrawItem event handler, so it's already set for you.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Richard, thanks for the help you gave. I tried what we spoke about yesterday and still failed. Everything on that control hinges on that integer and that wrecks everything I'd like to do so I'm giving up on that method, it's just too closely intertwined with the e.index.
|
|
|
|
|
Having read the subthread I'm going to propose something a bit different. I guess you are putting strings into the list box at the moment? Instead, put in an object which knows what colour it should be.
Pseudocode:
class ColouredLine {
string Text;
Color Color;
}
void fillListBox(){
myListBox.Items.Add(new ColouredLine("Liverpool", Color.Red));
myListBox.Items.Add(new ColouredLine("Everton", Color.Blue));
}
void listBox_DrawItem(object sender, DrawItemEventArgs e){
if(e.Index < 0) return;
ColouredLine line = (ColouredLine)myListBox.Items[e.Index];
e.Graphics.FillRectangle(new SolidBrush(line.Color), e.Bounds);
e.Grapics.DrawString(line.Text, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Location);
}
Also, have a look at my LineEditor control[^] because it sounds like you are trying to do something pretty similar.
|
|
|
|
|
Hi Bob,
Thanks for the reply, this looked promising, but I cannot get it to work after having put a couple of hours into this. It seems to change the text color, not the background color, it splits the row and creates a column and it creates a scroll bar of its own for some reason.
I'm sure it works well for you, I just cannot seem to get it to do what I want. I want it to look like the first image from this article, but I'm not sure I can leech this project as it is designed for html/aspx/webpages. I'm not sure why this is proving to be so difficult.
Coloring items in a ListBox[^]
|
|
|
|
|
What did you try? The pseudo code I posted or the control I linked you to? The code I posted should alter the background colour. If you used the LineEditor it should be straightforward to make a Line subclass that overrides Paint and does the background instead of the foreground (yes, the default line there changes the foreground because that's usually what I want, and it implements scrolling).
|
|
|
|
|
Hi Bob,
I tried both sets of code, but in my post I was referring to your class, I only referenced the other link/set of code because it has a picture of how I would like my listbox to appear.
It is changing the text color and I would like the background color changed instead, and omit the scroll bar it attaches. I didn't see that function/option.
Here is what I am seeing ... is that what I should be seeing?
http://img404.imageshack.us/img404/8830/lineeditor1.jpg[^]
private void testFunction()
{
try
{
LineEditor lineEditor = new LineEditor();
lbxOutput.Controls.Add(lineEditor);
lineEditor.ShowSelection = false;
lineEditor.BottomAligned = false;
lineEditor.Selectable = false;
lineEditor.Lines.Add(new Line(Color.Red, "Liverpool"));
lineEditor.Lines.Add(new Line(Color.Red, "Another test2"));
lineEditor.Lines.Add(new Line(Color.Green, "Another test3"));
lineEditor.Lines.Add(new Line(Color.Black, "Another test4"));
lineEditor.Lines.Add(new Line(Color.Orange, "Another test5"));
lineEditor.Lines.Add(new EditableLine(Color.Green, "Editable text"));
lineEditor.Lines.Insert(new Line(Color.Black, "At the front"), 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " " + ex.StackTrace + " " + ex.Source);
}
}
|
|
|
|
|
Thank you for the help Bob.
Here is what I ended up doing
And here is how it looks, I'm going to try and make the colors softer so the black text is easier to read, but I'm happy with it besides that.
http://img690.imageshack.us/img690/8922/lineeditor2.png[^]
public class MyListBoxItem
{
public MyListBoxItem(Color t, string m, Color c)
{
BackgroundColor = c;
Message = m;
TextColor = t;
}
public Color BackgroundColor { get; set; }
public string Message { get; set; }
public Color TextColor { get; set; }
}
private void testFunction()
{
try
{
lbxOutput.DrawMode = DrawMode.OwnerDrawFixed;
lbxOutput.DrawItem += new DrawItemEventHandler(listBox_DrawItem);
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Validated data successfully", Color.Green));
lbxOutput.Items.Add(new MyListBoxItem(Color.Black, "Failed to validate data", Color.Red));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " " + ex.StackTrace + " " + ex.Source);
}
}
private void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
MyListBoxItem item = lbxOutput.Items[e.Index] as MyListBoxItem;
Graphics g = e.Graphics;
if (item != null)
{
g.FillRectangle(new SolidBrush(item.BackgroundColor), e.Bounds);
e.Graphics.DrawString(
item.Message,
lbxOutput.Font,
new SolidBrush(item.TextColor),
0,
e.Index * lbxOutput.ItemHeight
);
}
else
{
}
}
|
|
|
|
|
Glad you got it sorted out!
|
|
|
|
|
Thanks
I've broken the scrolling now somehow, so I have to figure out what is causing that
|
|
|
|
|
Hi Bob,
Hopefully you are still following this.
My scrolling is broken, when I scroll to the bottom of the results, it will erase all text from the listbox . When I scroll back up to the very top, the text will come back, but if I move the scroll bar the slightest bit, the form listbox goes all white.
I'm sure this has to do with me taking manual control of the event, do you have any idea that I can try to fix this with?
Thanks for reading.
|
|
|
|
|
I am trying to use the SpeechSynthesizer as QMS for calling token number same like what is there in hospitals and other counters but the calling is going too fast for something like:
Ticket number 2 Please proceed to Counter 7
|
|
|
|
|
See the SpeechSynthesizer.Rate property.
/ravi
|
|
|
|
|
I have MDI parent.
I want to have a fixed side bar panel in the right left side (docked to right) and then everytime an MDI child is shown it will docked to fill which means it will take the entire mdi parent area - (minus) - the side bar area.
how can I do this?
|
|
|
|
|
|