none
Treeview node cropping RRS feed

  • 質問

  • Does anyone know how to prevent a Windows.Forms.Treeview node's text being cropped if the node's font size is increased or changed to bold? The text seems to be cut off roughly where the text would have displayed to if it were in the treeview's font -  the final letter is often chopped off part-way through, even though there is plenty of space following.

    The only work-around I have found is to set the Treeview's font to bold (or larger) and then set the font of all the other nodes (the ones I don't want emphasized) to the regular/smaller font. The problem with this is that the nodes' tooltips display in the treeview's font (ie bold/larger).

    2006年10月20日 0:47

回答

  • This is a fix but you probably won't like it much, it is very slow and causes a very visible flicker.  Add a new class to your project and paste this code:

    using System;
    using System.Drawing;
    using System.Windows.Forms;

    class BoldTreeView : TreeView {
      public void BoldNode(TreeNode node, bool on) {
        node.NodeFont = new Font(this.Font, on ? FontStyle.Bold : FontStyle.Regular);
        this.RecreateHandle();
      }
    }

    Build and drop a BoldTreeView from the top of the toolbox on your form.  Try it before you buy it.
    2006年10月20日 20:21
    モデレータ

すべての返信

  • This is a fix but you probably won't like it much, it is very slow and causes a very visible flicker.  Add a new class to your project and paste this code:

    using System;
    using System.Drawing;
    using System.Windows.Forms;

    class BoldTreeView : TreeView {
      public void BoldNode(TreeNode node, bool on) {
        node.NodeFont = new Font(this.Font, on ? FontStyle.Bold : FontStyle.Regular);
        this.RecreateHandle();
      }
    }

    Build and drop a BoldTreeView from the top of the toolbox on your form.  Try it before you buy it.
    2006年10月20日 20:21
    モデレータ
  • Cancel that, I found a quick way:

        private void button1_Click(object sender, EventArgs e) {
          TreeNode node = treeView1.Nodes[0];
          node.NodeFont = new Font(treeView1.Font, FontStyle.Bold);
          node.Text = node.Text;
        }

    Re-assigning the node's Text property is the fix.

    • 回答の候補に設定 Ravindra.PC 2012年11月9日 12:18
    2006年10月21日 0:38
    モデレータ
  • You nearly had it there. But here's the crazy thing - your fix only works on the first call. If you have more than one 'header' node to display in the bold font, the others are still cropped. I've played around with setting and resetting the nodefont and even the tree font, coupled with your node.Text = node.Text, but it still only works for number one.
    2006年10月24日 14:12
  • That was just demo code, only handling the first node in the tree.  Note the statement
      TreeNode node = treeView1.Nodes[0];   // Do this for the first node, just to demo

    You need to use the node whose NodeFont you're changing.
    2006年10月24日 21:58
    モデレータ
  • Well, of course I didn't just try it on the first node(!) My point is that, for some strange reason, however many times the node-creating routine is called, the fix only seems to work on the first call. I can't easily supply working code but here is the main routine in which nodes are created for my treeview. I have reverted to my orginal version.
    BrowserNode inherits TreeNode with a few extra properties added.
    vHeaderFont is the bold font (also used for the TreeView, for the reason given in my original post).
    vMainFont is the normal font.

        Private Function CreateNode(ByVal dr As DataRowView, ByVal Expanded As Boolean, ByVal MakeSubHeaders As Boolean, Optional ByVal CurrentRootNode As BrowserNode = Nothing, Optional ByVal CurrentLevel As Integer = -1) As BrowserNode
            'Also creates SubHeaders as required
            'vSortFieldPreviousValue(CurrentLevel) should be set to vBlankKey before calling this routine on each of a set of nodes
            'CurrentRootNode is used for adding SubHeaders. Normal nodes are added to parent's node collection back in calling routine, often after extra properties have been set.
            Dim n As BrowserNode = Nothing
            Dim EAOP_Name As String = dr(vColName).ToString
            Dim EAOP_StringDateFrom As String = dr(vColStringDateFrom).ToString
            Dim EAOP_StringDateTo As String = dr(vColStringDateTo).ToString
            Dim EAOP_Type As String = dr(vColType).ToString
            Dim EAOP As String = dr(vColEAOP).ToString

            Try
                If MakeSubHeaders Then
                    'If new main value
                    If (vSortFieldPreviousValue(CurrentLevel) = vBlankKey) OrElse (vSortFieldPreviousValue(CurrentLevel) <> EAOP_Type) Then
                        n = MakeSubHeader(EAOP_Type, CurrentLevel)
                        CurrentRootNode.Nodes.Add(n)
                    End If
                End If

                If vDataSourceType = DataSourceType.CalendarList AndAlso EAOP <> "D" Then
                    If EAOP_Name.Length = 0 Then
                        n = New BrowserNode(String.Format("[{0}]", EAOP_Type))
                    Else
                        n = New BrowserNode(EAOP_Name)
                    End If
                Else
                    n = New BrowserNode(String.Format("{0} {1}", EAOP_StringDateFrom, EAOP_Name).Trim)
                End If

                Dim tii As Integer = dr(vColIconIndex)
                n.EAOP_Type = EAOP_Type

                Dim Info As New StringBuilder(EAOP_Type)
                n.Name = dr(vColID).ToString
                n.RootPerson = dr(vcolRootPsn)
                Select Case EAOP
                    Case "D"
                        With Info
                            .AppendLine()
                            .AppendLine(EAOP_Name)
                        End With
                        n.NodeFont = vHeaderFont
                        n.ForeColor = Color.White
                        n.BackColor = DataTypeColours(vDataSourceType)
                        n.ImageIndex = BrowserImageIndex.Day
                        n.SelectedImageIndex = BrowserImageIndex.Day
                    Case "E"
                        With Info
                            .AppendLine()
                            .AppendLine(EAOP_Name)
                            .AppendFormat("{0} - {1}", dr(vColCountry).ToString, dr(vColArea))
                            .AppendLine()
                            .AppendFormat("{0} (#{1})", EAOP_StringDateFrom, dr(vColSequence))
                            .AppendFormat(" - {0}", EAOP_StringDateTo)
                        End With
                        n.NodeFont = vMainFont
                        n.ImageIndex = tii
                        n.SelectedImageIndex = tii
                    Case "A"
                        With Info
                            .AppendLine()
                            .AppendLine(EAOP_Name)
                            .AppendFormat("{0} - {1}", dr(vColCountry).ToString, dr(vColArea))
                            .AppendLine()
                            If EAOP_StringDateFrom.Length > 0 Then
                                .AppendFormat("{0} (#{1})", EAOP_StringDateFrom, dr(vColSequence))
                                If EAOP_StringDateTo.Length > 0 Then
                                    .AppendFormat(" - {0}", EAOP_StringDateTo)
                                End If
                            End If
                            .AppendLine()
                            .Append(dr(vColResult).ToString)
                            If vDataSourceType = DataSourceType.CalendarList Then
                                If EAOP_Type = "Overnight" Then
                                    n.BackColor = Color.Khaki
                                End If
                            End If
                        End With
                        n.NodeFont = vMainFont
                        n.ImageIndex = tii
                        n.SelectedImageIndex = tii
                    Case "O"
                        With Info
                            .AppendLine()
                            .AppendLine(EAOP_Name)
                            .AppendFormat("{0} - {1}", dr(vColCountry).ToString, dr(vColArea))
                        End With
                        n.NodeFont = vMainFont
                        n.ImageIndex = tii
                        n.SelectedImageIndex = tii
                    Case "P"
                        With Info
                            .AppendLine()
                            .Append(EAOP_Name)
                        End With
                        n.NodeFont = vMainFont
                        If tii = 0 Then tii = BrowserImageIndex.Person
                        n.ImageIndex = tii
                        n.SelectedImageIndex = tii
                    Case Else
                        Stop
                End Select

                n.ToolTipText = Info.ToString
                n.ContextMenuStrip = Me.mnuNode
                If Expanded Then n.Expand()
                Return n
            Catch ex As Exception
                'May be required if Background is being shut down
                Return Nothing
            End Try
        End Function


    2006年10月25日 15:24
  • Reassigning text property won't fix the cropping problem? I did the text reassigning when creating the tree nodes. Any ideas?

    Thanks,
    Alan

    2006年10月26日 16:25
  • I have had the same problem here recent.

    2006年10月27日 10:33
  • I wrote a test VB program that exercises the node Text property reassignment technique.  Drop a treeview and a timer on a form, then paste this code.  It worked well...

    Public Class Form1
      Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs)
        Dim ix As Integer = CInt(Fix(TreeView1.Nodes.Count * Rnd()))
        Dim node As TreeNode = TreeView1.Nodes(ix)
        If node.NodeFont Is Nothing OrElse ((node.NodeFont.Style And FontStyle.Bold) = FontStyle.Regular) Then
          node.NodeFont = New Font(TreeView1.Font, FontStyle.Bold)
        Else
          node.NodeFont = New Font(TreeView1.Font, FontStyle.Regular)
        End If
        node.Text = node.Text
      End Sub
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For ix As Integer = 1 To 10
          TreeView1.Nodes.Add("Node" + CStr(ix))
        Next
        Timer1.Interval = 200
        Timer1.Enabled = True
        AddHandler Timer1.Tick, AddressOf Timer1_Tick
      End Sub
    End Class

    2006年10月27日 12:28
    モデレータ
  • Worked for me, just set node.Text = node.Text (after you set the font).  Thanks for this solution.
    2010年2月1日 1:07
  • It's resolves the problem like below image..


    Ravindra.PC

    2012年11月9日 12:20
  • I know this is a pretty old Thread, but just in case I also found the following workaround:

    First enable LabelEdit on the TreeView, then call BeginEdit() and EndEdit(false) and reset LabelEdit back to false. Worked fine for me:

    private void setNodeFontStyle(TreeNode node, FontStyle style, Color foreColor) {
        node.ForeColor = foreColor;
        node.NodeFont = new Font((node.NodeFont != null ? node.NodeFont : node.TreeView.Font), style);
    
        node.TreeView.LabelEdit = true;
        node.BeginEdit();
        node.EndEdit(false);
        node.TreeView.LabelEdit = false;
    } 

    2013年3月26日 8:55
  • This last suggestion worked for me
    2019年9月28日 15:37