farzin parsa
farzin parsa

Reputation: 547

Highlight multiple items/rows in listBox

I have a list box that show some positions of (X,Y) in each row.

Somehow the user could enter a few (X,Y) pairs in a text box, and press the button.

Now What I want to do is: every time the user entered 3 or 4 (X,Y) pairs, my algorithm finds the matched pairs and those corresponding pairs should get highlighted (lets say with pink/red/any color) same time all together in the list Box.

How could I highlight those pairs( same indexes) with my desired colors?


1st Edition:

As NikolaD - Nick guided, I changed my DrawMode to OwnerDrawVariable and in lsBoxFeature_DrawItem method, I added following code:

private void lsBoxFeature_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawFocusRectangle();
        Bitmap bmp = new Bitmap(e.Bounds.Width, e.Bounds.Height);
        Graphics g = Graphics.FromImage(bmp);


            foreach (var item in globalDataForAllMatchedFrames[globalDataForAllMatchedFrames.Count - 1].featureNumber)
            {
                if (lsBoxFeature.Items[e.Index].Equals(item))//your method that determines should current item be highlighted 
                {
                    g.Clear(Color.Red);
                }
                else
                {
                    g.Clear(lsBoxFeature.BackColor);
                }

                g.DrawString(lsBoxFeature.Items[e.Index].ToString(), lsBoxFeature.Font, new SolidBrush(lsBoxFeature.ForeColor), e.Bounds);
                e.Graphics.DrawImage(bmp, e.Bounds);
                g.Dispose();
            }

    }

item is an object which is a PointF, now every time the item is equal to those members in listBoxFeature, it should highlight them in Red.

There are two issues:

I) it seems methos .Equals doesnt work properly in if-condition to check if the pointF item is equal to the members in listBoxFeature ===> As a result nothing is shown in my listBoxFeature

II) Even when I run the code I get an error message as following:

enter image description here


2nd Edition:

I followed NikolaD - Nick advice, and it worked!!!.But there is a small piece to be solved, it doesnt show the text(PointF Coordinates) for each row in lsBoxFeature.

Here is how it looks now:

enter image description here

and Here is how the output is supposed to be:

enter image description here

How could I take the row's tex back in lsBoxFeature?

Upvotes: 0

Views: 2085

Answers (1)

Nikola Davidovic
Nikola Davidovic

Reputation: 8666

You should add ListView's DrawItem event handler and draw highlighting upon checking which Items should be colored. Something like this:

        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
                e.DrawFocusRectangle();
                Bitmap bmp = new Bitmap(e.Bounds.Width, e.Bounds.Height);
                Graphics g = Graphics.FromImage(bmp);

                if (MeetsCriterion(listBox1.Items[e.Index]))//your method that determines should current item be highlighted 
                {
                    g.Clear(Color.Red);
                }
                else
                {
                    g.Clear(listBox1.BackColor);
                }
                g.DrawString(listBox1.Items[e.Index].ToString() , listBox1.Font, new SolidBrush(listBox1.ForeColor), e.Bounds);
                e.Graphics.DrawImage(bmp, e.Bounds);
                g.Dispose();
        }

Check this question, there is a more detailed answer how you can do it: How do i add same string to a ListBox in some lines?

**EDIT:**This edit is after you have edited your question. lsBoxFeature_DrawItem event handler is called for each item in listBox not once for all items. The first problem was that Equals() method is called for object (Item in ListBox is object) effectively comparing other object's reference, not the value of PointF.The second problem was that you disposed Graphic object and after that called g.Clear() on disposed object. I have rewritten your code and I think that it will work now.

private void lsBoxFeature_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawFocusRectangle();
            Bitmap bmp = new Bitmap(e.Bounds.Width, e.Bounds.Height);
            Graphics g = Graphics.FromImage(bmp);

            bool found = false;
            int count = 0;
            PointF pF1 = (PointF)lsBoxFeature.Items[e.Index];
            while (!found && count < globalDataForAllMatchedFrames[globalDataForAllMatchedFrames.Count - 1].featureNumber.Count)
            {
                //next two lines are here to show you the problem with equals!!!!

                PointF pF2 = (PointF)globalDataForAllMatchedFrames[globalDataForAllMatchedFrames.Count - 1].featureNumber[count];
                if(pF1.Equals(pF2))
                {
                    found = true;
                }
                count++;
            }

            if (found)//your method that determines should current item be highlighted 
            {
                g.Clear(Color.Red);
            }
            else
            {
                g.Clear(lsBoxFeature.BackColor);
            }
            g.DrawString(lsBoxFeature.Items[e.Index].ToString(), lsBoxFeature.Font, new SolidBrush(lsBoxFeature.ForeColor),  new Rectangle(e.Bounds.X,0,e.Bounds.Width,e.Bounds.Height));
            e.Graphics.DrawImage(bmp, e.Bounds);
            g.Dispose();

        } 

Upvotes: 3

Related Questions