Tengo una aplicación que está conectada a un servidor remoto y datos de sondeo cuando es necesario. Tiene un TreeView donde los Nodos representan los objetos que están disponibles y el color del texto indica si los datos han sido cargados o no; gris-cursiva indica que no está cargado, negro, el texto normal está cargado.Problemas con TreeView.DrawNode - OwnerDrawText
Actualmente tengo presente al TreeView ser OwnderDrawText y tienen la función TreeView.DrawNode simplemente dibujar el texto como tal:
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);
}
}
que pensé que sería suficiente, sin embargo, esto ha causado algunos problemas;
- Cuando se selecciona un nodo, centrado o no, que no envuelve todo el texto, example (espero imgur está bien).
- Cuando el nodo está enfocado, el contorno punteado tampoco aparece. Si lo compara con este example. Los nodos con el "registro" en el texto están utilizando el e.DefaultDraw = verdadero
Intenté seguir el ejemplo dado en la pregunta this. Parecía algo como esto:
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);
}
}
}
Sin embargo, los resultados fueron this. (Nota, usó rosa para diferenciar los colores). Como puede ver, el fondo resaltado no se extiende hasta donde está la línea de puntos enfocada. Y también hay otra caja que también se dibuja.
Estoy un poco perplejo sobre cómo solucionar esto. Todo lo que quiero es tener texto en cursiva gris cuando se carga algo. El primer y más simple enfoque no funciona del todo y el segundo método parece que estoy haciendo demasiado.
Después de todo eso, ¿alguien tiene alguna sugerencia sobre cómo hacer esto correctamente, porque tiene que haber una manera más simple.
Gracias de antemano.
Muchas gracias por 'if (! E.Node.IsVisible) return;' ¡Tenía tantos problemas sin él! – Daywalker