Skip to content

Commit 3841b91

Browse files
committed
Recalculate the node position of the TreeView when DrawMode = TreeViewDrawMode.OwnerDrawText
1 parent a990c47 commit 3841b91

File tree

1 file changed

+68
-5
lines changed
  • src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView

1 file changed

+68
-5
lines changed

src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,6 +2735,13 @@ private unsafe void CustomDraw(ref Message m)
27352735
// as background color.
27362736
if (_drawMode == TreeViewDrawMode.OwnerDrawText)
27372737
{
2738+
if (node is { IsEditing: true })
2739+
{
2740+
nmtvcd->clrText = ColorTranslator.ToWin32(BackColor);
2741+
nmtvcd->clrTextBk = ColorTranslator.ToWin32(BackColor);
2742+
goto default;
2743+
}
2744+
27382745
nmtvcd->clrText = nmtvcd->clrTextBk;
27392746
m.ResultInternal = (LRESULT)(nint)(PInvoke.CDRF_NEWFONT | PInvoke.CDRF_NOTIFYPOSTPAINT);
27402747
return;
@@ -2793,6 +2800,11 @@ private unsafe void CustomDraw(ref Message m)
27932800
nmtvcd->clrTextBk = ColorTranslator.ToWin32(riBack);
27942801
}
27952802

2803+
if (node is { IsEditing: true })
2804+
{
2805+
nmtvcd->clrTextBk = ColorTranslator.ToWin32(BackColor);
2806+
}
2807+
27962808
if (renderinfo is not null && renderinfo.Font is not null)
27972809
{
27982810
// Mess with the DC directly...
@@ -2827,8 +2839,30 @@ private unsafe void CustomDraw(ref Message m)
28272839
{
28282840
Rectangle bounds = node.Bounds;
28292841
Size textSize = TextRenderer.MeasureText(node.Text, node.TreeView!.Font);
2830-
Point textLoc = new(LocalAppContextSwitches.MoveTreeViewTextLocationOnePixel ? bounds.X : bounds.X - 1, bounds.Y);
2831-
bounds = new Rectangle(textLoc, new Size(textSize.Width, bounds.Height));
2842+
Point textLocation = new(LocalAppContextSwitches.MoveTreeViewTextLocationOnePixel ? bounds.X : bounds.X - 1, bounds.Y);
2843+
bounds = new Rectangle(textLocation, new Size(textSize.Width, bounds.Height));
2844+
2845+
Rectangle fillRectangle = new Rectangle(textLocation, new(textSize.Width, bounds.Height));
2846+
Rectangle focusRectangle = new Rectangle(textLocation, new(textSize.Width, bounds.Height));
2847+
2848+
if (RightToLeft == RightToLeft.Yes && RightToLeftLayout)
2849+
{
2850+
// Reverse the X-axis drawing coordinates of the rectangle.
2851+
// Offset the text four pixels to the left to ensure that the text is centered on the fill rectangle.
2852+
int invertedX = Width - bounds.X - textSize.Width - 4;
2853+
2854+
// Subtract the scroll bar width when the scroll bar appears.
2855+
if (Height <= PreferredHeight)
2856+
{
2857+
float dpiScale = (float)DeviceDpi / (float)ScaleHelper.InitialSystemDpi;
2858+
invertedX -= (int)(SystemInformation.VerticalScrollBarWidth * Math.Round(dpiScale, 2));
2859+
}
2860+
2861+
// To ensure that the right side of the fillRectangle does not
2862+
// touch the left edge of the node prefix symbol, 1 pixel is subtracted here.
2863+
fillRectangle = new Rectangle(new Point(invertedX - 1, bounds.Y), new(textSize.Width, bounds.Height));
2864+
focusRectangle = new Rectangle(new Point(invertedX, bounds.Y), new(textSize.Width, bounds.Height));
2865+
}
28322866

28332867
DrawTreeNodeEventArgs e = new(g, node, bounds, (TreeNodeStates)(nmtvcd->nmcd.uItemState));
28342868
OnDrawNode(e);
@@ -2844,14 +2878,14 @@ private unsafe void CustomDraw(ref Message m)
28442878
// Draw the actual node.
28452879
if ((curState & TreeNodeStates.Selected) == TreeNodeStates.Selected)
28462880
{
2847-
g.FillRectangle(SystemBrushes.Highlight, bounds);
2848-
ControlPaint.DrawFocusRectangle(g, bounds, color, SystemColors.Highlight);
2881+
g.FillRectangle(SystemBrushes.Highlight, fillRectangle);
2882+
ControlPaint.DrawFocusRectangle(g, focusRectangle, color, SystemColors.Highlight);
28492883
TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default);
28502884
}
28512885
else
28522886
{
28532887
using var brush = BackColor.GetCachedSolidBrushScope();
2854-
g.FillRectangle(brush, bounds);
2888+
g.FillRectangle(brush, fillRectangle);
28552889

28562890
TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default);
28572891
}
@@ -2871,6 +2905,35 @@ private unsafe void CustomDraw(ref Message m)
28712905
}
28722906
}
28732907

2908+
private int PreferredHeight
2909+
{
2910+
get
2911+
{
2912+
int height = 0;
2913+
foreach (TreeNode node in Nodes)
2914+
{
2915+
height += GetNodeHeight(node);
2916+
}
2917+
2918+
return height;
2919+
}
2920+
}
2921+
2922+
private int GetNodeHeight(TreeNode node)
2923+
{
2924+
int height = ItemHeight;
2925+
2926+
if (node.IsExpanded)
2927+
{
2928+
foreach (TreeNode childNode in node.Nodes)
2929+
{
2930+
height += GetNodeHeight(childNode);
2931+
}
2932+
}
2933+
2934+
return height;
2935+
}
2936+
28742937
/// <summary>
28752938
/// Generates colors for each item. This can be overridden to provide colors on a per state/per node
28762939
/// basis, rather than using the ForeColor/BackColor/NodeFont properties on TreeNode.

0 commit comments

Comments
 (0)