Wizard
Wizard

Reputation: 1162

How to print next line on Listbox

I have been tearing my hair out with this problem, my ToString is repeating straight after each other rather than dropping to the next line.

as shown on this image, the second Event name should be on the line below.

the problem

//ToString method in Event Class
public override string ToString()
    {
        return "\nEvent name : " + m_evName + "\n Date :" + m_evDate + "\n";
    }

//print method in class
 public String PrintEvents()
    {
        StringBuilder retev = new StringBuilder("");

        foreach (Event e in m_events)
        {
            retev.Append(e.ToString() + "\n");
        }
        return retev.ToString();
    }



//Foreach that displays the text
private void cboListEv_SelectedIndexChanged(object sender, EventArgs e)
    {
        String SelectedVenue = cboListEv.Text;

        List<Venue> found = plan.selectVen(SelectedVenue);

        lstEvents.Items.Clear();

        foreach (Venue v in found)
        {
                lstEvents.Items.Add(v.PrintEvents());
        }
    }

Upvotes: 0

Views: 8731

Answers (4)

AKX
AKX

Reputation: 169051

ListBox items don't support multiline strings. However, you can make the ListBox's DrawMode OwnerDrawVariable, then hook up something like the following to its MeasureItem and DrawItem events:

    internal int CountOccurrences(string haystack, string needle) {
        int n = 0, pos = 0;
        while((pos = haystack.IndexOf(needle, pos)) != -1) {
            n++;
            pos += needle.Length;
        }
        return n;
    }

    void ListBox1MeasureItem(object sender, MeasureItemEventArgs e)
    {
        e.ItemHeight = (int)((CountOccurrences(((ListBox)sender).Items[e.Index].ToString(), "\n") + 1) * ((ListBox)sender).Font.GetHeight() + 2);
    }

    void ListBox1DrawItem(object sender, DrawItemEventArgs e)
    {
        string text = ((ListBox)sender).Items[e.Index].ToString();
        e.DrawBackground();
        using(Brush b = new SolidBrush(e.ForeColor)) e.Graphics.DrawString(text, e.Font, b, new RectangleF(e.Bounds.Left, e.Bounds.Top, e.Bounds.Width, e.Bounds.Height));
        e.DrawFocusRectangle();
    }

-- will end up something like this:

Upvotes: 2

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112392

Add an Events property to the Venue class if not already there

public List<Event> Events
{
    get { return m_events; }
}

Then add the items like this

foreach (Venue v in found) {
    foreach (Event e in v.Events) {
        lstEvents.Items.Add(e);
    }
}

Upvotes: 1

qJake
qJake

Reputation: 17139

It's not possible to print multiple text lines per ListBox item with the standard ListBox. Try using a TextBox instead, with Multiline = true, and in read-only mode. It will achieve a similar effect.

Beyond that, you'll need to draw up your own custom ListBox control with customized item templates that support multiple lines of data.

Upvotes: 3

Bazzz
Bazzz

Reputation: 26922

If you provide the PrintEvents() method with the item collection of the ListBox you can have it add an item for every found event. Something like this:

//print method in class
public String PrintEvents(ObjectCollection items)
{
    foreach (Event e in m_events)
        items.Add(e.ToString());
}

//Foreach that displays the text
private void cboListEv_SelectedIndexChanged(object sender, EventArgs e)
{
    String SelectedVenue = cboListEv.Text;

    List<Venue> found = plan.selectVen(SelectedVenue);

    lstEvents.Items.Clear();

    foreach (Venue v in found)
       v.PrintEvents(lstEvents.Items);
}

Upvotes: 1

Related Questions