2010-01-12 18 views
8

Ho un'app che è collegata a un server remoto e dati di polling quando necessario. Ha una TreeView in cui i Nodi rappresentano gli oggetti disponibili e il colore del testo indica se i dati sono stati caricati o meno; grigio in corsivo indica che non è caricato, nero, viene caricato il testo normale.Problemi con TreeView.DrawNode - OwnerDrawText

Attualmente ho impostato la TreeView di essere OwnderDrawText e hanno la funzione di TreeView.DrawNode semplicemente disegnare il testo come così:

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e) 
{ 
    if (!e.Node.IsVisible) 
    { 
     return; 
    } 

    bool bLoaded = false; 

    if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0) 
    { 
     if(e.Node.Tag != null) 
     { 
      //... 
      // code determining whether data has been loaded is done here 
      // setting bLoaded true or false 
      //... 
     } 
     else 
     { 
      e.DrawDefault = true; 
      return; 
     } 

     Font useFont = null; 
     Brush useBrush = null; 

     if (bLoaded) 
     { 
      useFont = e.Node.TreeView.Font; 
      useBrush = SystemBrushes.WindowText; 
     } 
     else 
     { 
      useFont = m_grayItallicFont; 
      useBrush = SystemBrushes.GrayText; 
     } 
     e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location); 
    } 
} 

ho pensato che sarebbe sufficiente, tuttavia, questo ha causato alcuni problemi;

  1. Quando si seleziona un nodo, focalizzata o no, non si avvolgono tutto il testo, example (spero Imgur è ok).
  2. Quando il nodo è a fuoco, il contorno tratteggiato non viene visualizzato. Se lo confronti con questo example. I nodi con il "log" nel testo utilizzano e.DefaultDraw = true

Ho provato a seguire l'esempio indicato nella domanda this. Sembrava qualcosa di simile:

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e) 
{ 
    if (!e.Node.IsVisible) 
    { 
    return; 
    } 

    bool bLoaded = false; 

    if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0) 
    { 
    if(e.Node.Tag != null) 
    { 
     //... 
     // code determining whether data has been loaded is done here 
     // setting bLoaded true or false 
     //... 
    } 
    else 
    { 
     e.DrawDefault = true; 
     return; 
    } 

    //Select the font and brush depending on whether the property has been loaded 
    Font useFont = null; 
    Brush useBrush = null; 

    if (bLoaded) 
    { 
    useFont = e.Node.TreeView.Font; 
    useBrush = SystemBrushes.WindowText; 
    } 
    else 
    { 
    //member variable defined elsewhere 
    useFont = m_grayItallicFont; 
    useBrush = SystemBrushes.GrayText; 
    } 

    //Begin drawing of the text 

    //Get the rectangle that will be used to draw 
    Rectangle itemRect = e.Bounds; 
    //Move the rectangle over by 1 so it isn't on top of the check box 
    itemRect.X += 1; 

    //Figure out the text position 
    Point textStartPos = new Point(itemRect.Left, itemRect.Top); 
    Point textPos = new Point(textStartPos.X, textStartPos.Y); 

    //generate the text rectangle 
    Rectangle textRect = new Rectangle(textPos.X, textPos.Y, itemRect.Right - textPos.X, itemRect.Bottom - textPos.Y); 

    int textHeight = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Height; 
    int textWidth = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Width; 

    textRect.Height = textHeight; 

    //Draw the highlighted box 
    if ((e.State & TreeNodeStates.Selected) != 0) 
    { 
    //e.Graphics.FillRectangle(SystemBrushes.Highlight, textRect); 
    //use pink to see the difference 
    e.Graphics.FillRectangle(Brushes.Pink, textRect); 
    } 
    //widen the rectangle by 3 pixels, otherwise all of the text  won't fit 
    textRect.Width = textWidth + 3; 

    //actually draw the text 
    e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location); 

    //Draw the box around the focused node 
    if ((e.State & TreeNodeStates.Focused) != 0) 
    { 
    textRect.Width = textWidth; 
    Pen focusPen = new Pen(Color.Black); 
    focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; 
    e.Graphics.DrawRectangle(focusPen, textRect); 
    } 
    } 
} 

Tuttavia, i risultati erano this. (Nota, usato il rosa per differenziare i colori). Come puoi vedere, lo sfondo evidenziato non si estende fino a dove si trova la linea punteggiata focalizzata. E c'è anche un'altra scatola che viene disegnata.

Sono leggermente perplesso su come risolvere questo problema. Tutto quello che voglio è avere un testo in corsivo in grigio quando qualcosa viene caricato. Il primo e il più semplice approccio non funziona e il secondo metodo mi sembra che sto facendo troppo.

Dopo tutto ciò, qualcuno ha qualche suggerimento su come farlo correttamente, perché ci deve essere un modo più semplice.

Grazie in anticipo.

+0

Grazie mille per 'se (! E.Node.IsVisible) ritorno;' Ho avuto così tanti problemi senza di esso! – Daywalker

risposta

14

È necessario utilizzare TextRenderer.DrawText(). Questo è ciò che usa TreeView, rende il testo leggermente diverso da Graphics.DrawString().

+1

Beh, certo che sarà così facile! Ha funzionato totalmente, grazie mille. Ora, dove posso trovare queste informazioni su TreeView usando DrawText? –

+2

Questo ancora non sta correggendo tutti i problemi grafici. Anche se il mio gestore DrawNode imposta semplicemente DrawDefault su true e restituisce immediatamente, continua a causare residui dello sfondo del rettangolo di selezione che rimangono dopo che il nodo non è stato selezionato. Inoltre, il testo non è centrato (verticalmente) quando si utilizza DrawMode = OwnerDrawText, anche quando DrawDefault è tutto ciò che viene utilizzato. Deve essere spostato verso il basso di un pixel per far corrispondere ciò che viene reso quando DrawMode = Normal. Il problema è che i metodi di disegno del controllo sono un ibrido tra il codice di disegno nativo di Windows e il codice di disegno del framework e sono molto incoerenti. – Triynko