1

VS 2015 を使用して C# でクライアント/サーバー WinForms アプリケーションを作成しています。

DrawItemイベントがオーナーによって描画されるListBoxコントロールがあります (はい、DrawModeプロパティをOwnerDrawFixedに設定します)。これは、新しいメッセージを受信するたびに再描画する必要があります。

このコールバックは、次の参照に従って使用します。

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();
}

これがMeasureItemメソッドです。

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;
 }

メッセージは を使用して受信および挿入ListBox.Add()され、デバッガーによって確認されて機能します。

しかし、ListBoxはクリックしたときにのみ再描画されます(フォーカスが発生すると思います)。

私はすでに試しました.Update()が、うまく.Refresh()いき.Invalidate() ませんでした。

DrawItem()コードからトリガーする方法はありますか?

4

1 に答える 1

1

いくつかの調査の後、解決策を見つけました。コントロールが変更されると、 DrawItemイベントが呼び出されます。

実際.Add()のところ、トリックを行います。これで更新機能を変更しました:

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

    chatLobby.Items.Add(" "); // Alters the listbox
}
于 2015-08-20T12:53:54.727 に答える