Substituindo DrawItem para a caixa de Listagem - a desmarcada itens não são redesenhados

StackOverflow https://stackoverflow.com/questions/3274861

Pergunta

Este é um C# aplicativo de área de trabalho.O DrawStyle propriedade de meu ListBox é definido como OwnerDrawFixed.

O problema: Eu substituir DrawItem para desenhar o texto em diferentes fontes, e ele funciona.Mas quando eu começar a redimensionar o formulário em tempo de execução, o item selecionado é desenhado corretamente, mas os outros não são redesenhados, fazendo com que o texto procura corromper por não selecionados itens.

Aqui está o meu código:

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

    string textDevice = ((ListBox)sender).Items[e.Index].ToString();

    e.Graphics.DrawString(textDevice,
        new Font("Ariel", 15, FontStyle.Bold), new SolidBrush(Color.Black), 
        e.Bounds, StringFormat.GenericDefault);


    // Figure out where to draw IP
    StringFormat copy = new StringFormat(
        StringFormatFlags.NoWrap |
        StringFormatFlags.MeasureTrailingSpaces
    );
    copy.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, textDevice.Length)});

    Region[] regions = e.Graphics.MeasureCharacterRanges(
        textDevice, new Font("Ariel", 15, FontStyle.Bold), e.Bounds, copy);

    int width = (int)(regions[0].GetBounds(e.Graphics).Width);
    Rectangle rect = e.Bounds;
    rect.X += width;
    rect.Width -= width;

    // draw IP
    e.Graphics.DrawString(" 255.255.255.255",
        new Font("Courier New", 10), new SolidBrush(Color.DarkBlue),
        rect, copy);

    e.DrawFocusRectangle();
}

listDevices.Items.Add("Device001");
listDevices.Items.Add("Device002");

Além disso, o item que está desenhado corretamente (a selecionada) é cintilação no formulário de redimensionamento.Nada demais, mas se alguém sabe o porquê....tnx

Foi útil?

Solução

Coloque o seguinte código no evento Resize:

private void listDevices_Resize(object sender, EventArgs e) {
    listDevices.Invalidate();
}

Isso deve fazer de tudo para ser redesenhado.

Para parar a cintilação, você tem a memória intermédia dupla.

Para fazer isso, crie uma nova classe derivada de caixa de Listagem, e coloque o seguinte no construtor:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

Ou apenas cole-o em um arquivo de código:

using System.Windows.Forms;

namespace Whatever {
    public class DBListBox : ListBox {
        public DBListBox(): base() {
            this.DoubleBuffered = true;
            // OR
            // this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
    }
}

Substituir "o que" com o espaço de nomes usa seu projeto, ou fazer algo mais útil.Depois de compilar, você deve ser capaz de adicionar um DBListBox no designer de formulário.

Outras dicas

Eu reproduzem o problema.Há vários erros no código, o nome de tipo de letra é "Arial", você não deve ajustar rect.Largura, não se esqueça de chamar Dispose() na letra, pincéis e regiões.Mas eles não explicam o comportamento.Há algo de errado com a área de recorte que impede que o texto seja atualizado corretamente.Não vejo onde isso ocorre, o objeto Graphics estado está bem.

Gráficos.DrawString() é muito conturbado método, você deve realmente evitar.Todos os controlos de Formulários do Windows, incluindo a caixa de Listagem, use TextRenderer.DrawText().O que resolve o problema quando eu usá-lo.Eu sei medição é mais difícil, você pode trabalhar em torno disso, apresentar o endereço IP fixo deslocamento.Parece muito melhor, eles vão de linha em uma coluna que a forma.

Ele pisca, porque você usa e.DrawBackground().Que apaga o texto existente, você deve desenhar o texto para a direita de volta a ele.Eu não acho que a memória intermédia dupla vai corrigir isso, você iria ter que tirar o item inteiro, assim você não tem que desenhar o plano de fundo.Complicado se você não puder obter o tamanho exato do texto com a fonte grande, uma solução é desenhada em um mapa de bits em primeiro lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top