Nomid
Nomid

Reputation: 91

DrawItem event is fired only when the user clicks the ListBox

I'm writing a client/server WinForms application in C# using VS 2015.

I have a ListBox control whose DrawItem event is owner-drawn (yes, I set the DrawMode property to OwnerDrawFixed), which has to be redrawn every time a new message is recieved.

I use this callback following this reference:

private void chatLobby_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();

    int ItemMargin = 0;
    string last_u = "";

    foreach(Message m in ChatHistory[activeChatID])
    {
        // Don't write the same user name
        if(m.from.name != last_u)
        {
            last_u = m.from.name;

            e.Graphics.DrawString(last_u, ChatLobbyFont.Username.font, ChatLobbyFont.Username.color, e.Bounds.Left, e.Bounds.Top + ItemMargin);
                ItemMargin += ChatLobbyFont.Message.font.Height;
        }

        e.Graphics.DrawString("  " + m.message, ChatLobbyFont.Message.font, ChatLobbyFont.Message.color, e.Bounds.Left, e.Bounds.Top + ItemMargin);

        ItemMargin += ChatLobbyFont.Message.font.Height;
    }

    e.DrawFocusRectangle();
}

And this is the MeasureItem method:

private void chatLobby_MeasureItem(object sender, MeasureItemEventArgs e)
{
    // No messages in the history
    if(ChatHistory[activeChatID][0] == null)
    {
        e.ItemHeight = 0;
        e.ItemWidth = 0;
    }

    string msg = ChatHistory[activeChatID][e.Index].message;

    SizeF msg_size = e.Graphics.MeasureString(msg, ChatLobbyFont.Message.font);

    e.ItemHeight = (int) msg_size.Height + 5;
    e.ItemWidth = (int) msg_size.Width;
 }

The message is recieved and inserted using ListBox.Add() and it does work, confirmed by the debugger.

But the ListBox redraws only when I click it (I think it fires a focus).

I already tried .Update(), .Refresh() and .Invalidate() with no luck.

Is there a way to trigger DrawItem() from code?

Upvotes: 1

Views: 2044

Answers (1)

Nomid
Nomid

Reputation: 91

After some research, I found the solution: the DrawItem event is called when the control gets altered.

As a matter of fact, .Add() does the trick. I changed my update function with this:

private void getMessages()
{
    // ... <--- connection logic here

    chatLobby.Items.Add(" "); // Alters the listbox
}

Upvotes: 1

Related Questions