リモートサーバーに接続し、必要に応じてデータをポーリングするアプリがあります。これにはTreeViewがあり、ノードは使用可能なオブジェクトを表し、テキストの色はデータがロードされているかどうかを示します。灰色の斜体はロードされていないことを示し、黒の通常のテキストはロードされています。
現在、TreeViewをOwnderDrawTextに設定し、TreeView.DrawNode関数でテキストを次のように描画しています。
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);
}
}
それで十分だと思いましたが、これがいくつかの問題を引き起こしています。
- フォーカスされているかどうかに関係なく、ノードが選択されている場合、例のようにすべてのテキストが含まれているわけではありません(imgurが問題ないことを願っています)。
- ノードにフォーカスがある場合、点線の輪郭も表示されません。この例と比較すると。テキストに「log」が含まれるノードは、e.DefaultDraw=trueを使用しています。
この質問の例に従ってみました。次のようになりました。
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);
}
}
}
しかし、結果はこれでした。(色を区別するためにピンクを使用していることに注意してください)。ご覧のとおり、強調表示された背景は、フォーカスされた点線がある場所までは伸びていません。また、同様に描かれている別のボックスもあります。
私はこれを修正する方法に少し困惑しています。私が欲しいのは、何かがロードされたときに灰色のイタリック体のテキストを表示することです。最初の最も単純なアプローチは完全には機能せず、2番目の方法は私がやりすぎているように感じます。
結局のところ、もっと簡単な方法が必要なので、これを適切に行う方法について誰かが何か提案がありますか。
前もって感謝します。