C# WinForms выделяет treenode, когда treeview не имеет фокуса
Gretings.
Я создаю интерфейс для редактирования сценариев игры. В основном он состоит из событий, которые имеют вложенные условия и действия. Итак, я планировал использовать два treeviews - один для выбора события, а другой для выбора условия/действия внутри события для редактирования.
теперь, вы видите, если я выберу событие (в левом treeview), а затем попытаюсь выбрать что-то в правом treeview, левый treeview перестанет показывать синий прямоугольник выбора. Это, очевидно, плохо, потому что теперь пользователь не знает, какое событие он редактирования!
единственный способ сохранить некоторую информацию о том, что такое текущий выбор, - это использовать SelectedImageIndex, но это только одно маленькое изображение, которое будет отличаться.
есть ли другой способ выделить treenode, пока нет фокуса на treeview? Я знаю, что могу только графики.DrawRectangle или что-то еще, но я слышал, что рисунок должен быть сделан в Paint event и у treeview нет события paint... Значит, если я нарисую его на случай потери фокуса, а затем вытащу форму из экрана или что-то еще, она будет "стерта"?
в любом случае, пожалуйста, скажите мне, если у вас есть идея (кроме использования отдельного значка для выбранного и не выбранного treenode)
спасибо!
4 ответов
то, что вы ищете-это HideSelection
собственности на TreeView
.
из MSDN:
получает или задает значение, указывающее, остается ли выделенным выбранный узел дерева, даже если представление дерева потеряло фокус.
ссылка: http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.hideselection.aspx
код:
TreeView.HideSelection = false;
он по-прежнему отображается, но только в светло-сером, который в зависимости от вашего экрана и текущей настройки может быть рядом в видимом!
переопределить событие OnDrawNode. Таким образом, вы создаете и новый класс (назовите его "SpecialTreeView"), наследуемый от Microsoft TreeView
как 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
.
надеюсь, это поможет.
быстрое решение:
установить свойства:
HideSelection = false;
DrawMode = TreeViewDrawMode.OwnerDrawText;
затем в обработчике событий DrawNode просто сделайте:
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) {
e.DrawDefault = true;
}
на Windwos 7 это восстанавливает старый рендеринг, включая пунктирное поле вокруг выбора (который на самом деле выглядит немного устаревшим). Текст будет белым с фокусом и черным без фокуса. Фон остается синим и видимым.
этот ответ не новый, другие также содержат эти шаги, но это минимально необходимое (по крайней мере, в Windows 7, не тестировал другие ОС).
Не совсем идеальное решение, но совсем рядом:
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;
};