4

標準の System.Windows.Forms.TreeView コントロールの要素にさらにいくつかのアイコンを追加しようとしています。

ツリービュー コントロールのラベル領域のみを変更する予定でしたが、奇妙な動作を示します。ノードをクリックして選択すると、マウス ボタンが押されたときに背景がハイライト カラーで正しく描画されます。ただし、マウスボタンを離すまで、テキストは選択されていない間違った色になります。e.Stateマウスボタンが押されてから離されるまでの間に間違った状態が含まれているかのようです。

私がやっていることは次のとおりthis.DrawMode = TreeViewDrawMode.OwnerDrawTextですthis.DrawNode += LayoutTreeView_DrawNode。ハンドラーは次のとおりです。

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{

    Color color = (e.State & TreeNodeStates.Selected) != 0 ?
        SystemColors.HighlightText : SystemColors.WindowText;

    TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
       TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

    TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, flags);
}

ハンドラーをデフォルトのケースに設定すると...

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    e.DefaultDraw = true;
}

...同じことが起こります。これは、ウィンドウが実際に描画しているため、奇妙です。この動作は、Windows XP with .Net 3.5 にあります。

この奇妙な動作を回避する方法はありますか?

4

1 に答える 1

3

変化する

Color color = (e.State & TreeNodeStates.Selected) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

Color color = (e.State & TreeNodeStates.Focused) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

これは、.Net 3.5 を使用する Vista x64 および VS 2008 で機能しました。それがあなたのために働くかどうか私に知らせてください。

デフォルトのウィンドウの動作を見ているときに観察したことは、ノードが選択されてフォーカスされるまで、テキストとハイライトが描画されないことでした。ということで、文字色を変更するために合焦状態をチェックしてみました。ただし、これは、マウスが離されるまで新しい色が使用されない Widows の動作を正確に模倣するものではありません。所有者描画モードとウィンドウの描画モードで青いハイライトステータスの変化を描画することを選択したときのポイントが表示されます...確かに混乱しています。

編集 ただし、独自の派生ツリービューを作成すると、すべてがいつ描画されるかを完全に制御できます。

public class MyTreeView : TreeView
{
    bool isLeftMouseDown = false;
    bool isRightMouseDown = false;
    public MyTreeView()
    {
        DrawMode = TreeViewDrawMode.OwnerDrawText;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseUp(e);
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseMove(e);
    }

    private void TrackMouseButtons(MouseEventArgs e)
    {
        isLeftMouseDown = e.Button == MouseButtons.Left;
        isRightMouseDown = e.Button == MouseButtons.Right;
    }

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        // don't call the base or it will goof up your display!
        // capture the selected/focused states
        bool isFocused = (e.State & TreeNodeStates.Focused) != 0;
        bool isSelected = (e.State & TreeNodeStates.Selected) != 0;
        // set up default colors.
        Color color = SystemColors.WindowText;
        Color backColor = BackColor;

        if (isFocused && isRightMouseDown)
        {
            // right clicking on a 
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }
        else if (isSelected && !isRightMouseDown)
        {
            // if the node is selected and we're not right clicking on another node.
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }

        using (Brush sb = new SolidBrush(backColor))
            e.Graphics.FillRectangle(sb,e.Bounds);

        TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
           TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

        TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, backColor, flags);
    }
}
于 2010-03-10T21:18:00.320 に答える