|
I often reference the W3Cschools (except it's blocked at work ). I also carry a copy of "XSLT 1.0 Pocket Reference" (O'Reilly) with me, but it has very little information on XPath. At home I have a copy of the XML Bible, but it's more than ten years old now.
My best tool is a console application I call XpathTester which allows me to specify an XML file and an XPath and it generally tells me I'm an idiot. I used it to determine the XPath you were seeking.
I really need to write an article on XPath...
|
|
|
|
|
PIEBALDconsult wrote: I really need to write an article on XPath...
Please do..
I'v got 20+ years of of dev experience, but honestly, I'v only worked with XMl a few time, and that was with Visual FoxPro years ago.
If it's not broken, fix it until it is
|
|
|
|
|
OK, now I've tried it.
You only use @ when ContactId is an attribute; try [ContactId and watch your capitalization.
modified 28-Aug-12 18:12pm.
|
|
|
|
|
Hi,
I'm not well versed on event handling and I'd like to pass a color to this method, instead of having it choose the color based on the value of e.index. Can anyone tell me how to change the method below to do that?
Thanks for reading.
void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index > -1)
{
if (e.Index == 0)
e.Graphics.FillRectangle(Brushes.Red, e.Bounds);
else if (e.Index == 1)
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);
}
}
}
|
|
|
|
|
There is no way to change the signature of an event handler that handles an event from the framework.
You'll have to write a separate function that determines what color to use, then call that function from within the event handler.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
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
|
|
|
|
|