34

ゲームのシナリオを編集するためのインターフェイスを作成しています。基本的に、ネストされた条件とアクションを持つイベントで構成されます。そのため、2 つのツリービューを使用することを計画しました。1 つはイベントを選択するためのもので、もう 1 つは編集するイベント内の条件/アクションを選択するためのものです。

ここで、(左側のツリービューで) イベントを選択してから、右側のツリービューで何かを選択しようとすると、左側のツリービューに青い選択四角形が表示されなくなります。ユーザーは自分がどのイベントを編集しているかわからなくなるため、これは明らかに悪いことです。

現在の選択内容に関する何らかの情報を保持するために私が見つけた唯一の方法は、SelectedImageIndex を使用することですが、それは異なる 1 つの小さな画像にすぎません。

ツリービューにフォーカスがないときにツリーノードを強調表示する他の方法はありますか? Graphics.DrawRectangle などを使用できることはわかっていますが、ペイント イベントで描画を行う必要があり、ツリービューにはペイント イベントがないと聞いたので、フォーカスを失ったイベントで描画してからドラッグすると、画面の外に出たら「消される」のでは?

とにかく、アイデアがあれば教えてください(選択したツリーノードと選択していないツリーノードに別のアイコンを使用する以外に)。

4

6 に答える 6

17

それはまだ表示されていますが、画面と現在の設定によっては明るい灰色でのみ表示されます。

OnDrawNode イベントをオーバーライドします。したがって、新しいクラス (「SpecialTreeView」と呼びます) を作成して、MicrosoftTreeViewのようなから継承しますclass SpecialTreeView : TreeView。次に、次のイベント オーバーライドを追加します。

protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
    TreeNodeStates treeState = e.State;
    Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font;

    // Colors.
    Color foreColor = e.Node.ForeColor;
    string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC";
    Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor);
    Color deselectedColor = System.Drawing.ColorTranslator.FromHtml(strDeselectedColor);

    // New brush.
    SolidBrush selectedTreeBrush = new SolidBrush(selectedColor);
    SolidBrush deselectedTreeBrush = new SolidBrush(deselectedColor);

    // Set default font color.
    if (foreColor == Color.Empty)
        foreColor = e.Node.TreeView.ForeColor;

    // Draw bounding box and fill.
    if (e.Node == e.Node.TreeView.SelectedNode)
    {
        // Use appropriate brush depending on if the tree has focus.
        if (this.Focused)
        {
            foreColor = SystemColors.HighlightText;
            e.Graphics.FillRectangle(selectedTreeBrush, e.Bounds);
            ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                         foreColor, TextFormatFlags.GlyphOverhangPadding);
        }
        else
        {
            foreColor = SystemColors.HighlightText;
            e.Graphics.FillRectangle(deselectedTreeBrush, e.Bounds);
            ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                         foreColor, TextFormatFlags.GlyphOverhangPadding);
        }
    }
    else
    {
        if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)
        {
            e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, hotFont, e.Bounds,
                                         System.Drawing.Color.Black, TextFormatFlags.GlyphOverhangPadding);
        }
        else
        {
            e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                         foreColor, TextFormatFlags.GlyphOverhangPadding);
        }
    }
}

コードをコンパイルすると、デザイナーのツール ボックスに "SpecialTreeView" が表示されます。TreeView を同じ名前のこの新しいものに置き換えます。異なるのは選択色だけです。選択selectedColor時は 、非選択時は になりdeselectedColorます。

これが役立つことを願っています。

于 2012-04-05T19:33:09.980 に答える
8

絶対に完璧な解決策ではありませんが、ほぼ次のようになります。

treeView.HideSelection = false;
treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
treeView.DrawNode += (o, e) =>
{
    if (!e.Node.TreeView.Focused && e.Node == e.Node.TreeView.SelectedNode)
    {
        Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font;
        e.Graphics.FillRectangle(Brushes.Gray, e.Bounds);
        ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, SystemColors.HighlightText, SystemColors.Highlight);
        TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
    }
    else
        e.DrawDefault = true;
};
treeView.MouseDown += (o, e) =>
{
    TreeNode node = treeView.GetNodeAt(e.X, e.Y);
    if (node != null && node.Bounds.Contains(e.X, e.Y))
        treeView.SelectedNode = node;
};
于 2014-10-09T12:50:24.713 に答える