Поиск на сайте
Главная Журнал Форум Wiki DRKB Страны мира

Жирный шрифт в TreeView с помощью VB.NET

В этой статье описывается применение техники пользовательской прорисовки в TreeView с помощью Visual Basic.NET, в частности рассказывается как выделить жирным шрифтом некоторые части текста узлов дерева.

В исходнике, прилагаемом к статье имеется класс TreeNodeEx (наследованный от TreeNode), который позволяет указать в конструкторе текст узла, начальную позицию текста, который будет выделен жирным шрифтом, и длина выделенной части.

Ниже представлена вспомогательная функция, предназначенная для добавления узлов в TreeView:

Private Function AddNodeToTreeView(ByVal colNodes As TreeNodeCollection, _
     ByVal sText As String, ByVal iBoldTextInitialPosition As Integer, _
     ByVal iBoldTextLength As Integer) As TreeNodeEx
 
   Dim objTreeNodeEx As TreeNodeEx
 
   objTreeNodeEx = New TreeNodeEx(sText, _
                   iBoldTextInitialPosition, iBoldTextLength)
   colNodes.Add(objTreeNodeEx)
 
   Return objTreeNodeEx
 
End Function

Класс TreeViewEx используется следующим образом:

Private m_ctlTreeViewEx As TreeViewEx
 
Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
 
   Dim objRootTreeNodeEx As TreeNodeEx
 
   m_ctlTreeViewEx = New TreeViewEx()
   Me.Controls.Add(m_ctlTreeViewEx)
   m_ctlTreeViewEx.Left = 0
   m_ctlTreeViewEx.Top = 0
   m_ctlTreeViewEx.Dock = DockStyle.Fill
 
   objRootTreeNodeEx = AddNodeToTreeView(m_ctlTreeViewEx.Nodes, _
                       "Это первая нода", 12, 5)
 
   AddNodeToTreeView(objRootTreeNodeEx.Nodes, "Вторая нода", 4, 6)
   AddNodeToTreeView(objRootTreeNodeEx.Nodes, "Третья нода", 0, 5)
   AddNodeToTreeView(objRootTreeNodeEx.Nodes, "Нода 4", 5, 1)
   AddNodeToTreeView(objRootTreeNodeEx.Nodes, "Последняя нода", -1, 0)
 
   objRootTreeNodeEx.Expand()
 
End Sub

Важные моменты

Давайте подробнее рассмотрим следующие моменты кода:

1) Элементы управления в Windows отправляют в родительское окно уведомления NM_CUSTOMDRAW через сообщения WM_NOTIFY. Таким образом, нам необходимо перехватить это сообщение за пределами нашего TreeView, который нарушает правила инкапсуляции. К счастью, .NET Framework даёт элементам управления возможность получать это сообщение "отраженным" (reflected). Для этого Фреймворк добавляет значение 0x2000 к значению сообщения WM_NOTIFY и отправляет его элементу управления. В итоге, TreeView может получать сообщение WM_NOTIFY, отправленное его родительскому окну, используя следующий код в своей процедуре WndProc:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
 
   Const WM_NOTIFY As Integer = &H4E
 
   Dim iResult As Integer
   Dim bHandled As Boolean = False
 
   If m.Msg = (&H2000 Or WM_NOTIFY) Then
   ' Это отражённое сообщение WM_NOTIFY, отправленное родительскому окну

      If m.WParam.Equals(Me.Handle) Then
         iResult = HandleNotify(m)
         m.Result = New IntPtr(iResult)
         bHandled = True
      End If
 
   End If
 
   If Not bHandled Then
      MyBase.WndProc(m)
   End If
 
End Sub

2) Чтобы нарисовать частично выделенный жирным шрифтом текст ноды, нам надо будет нарисовать сперва невыделенную часть текста, потом выделенную и затем невыделенную. Для этого необходимо знать длину каждой части в пикселях, чтобы установить координату Х очередной порции, при этом желательно очень точно измерить, чтобы избежать "дырок" между двумя частями. Бывает, что при использовании функции Graphics.MeasureCharacterRanges для измерения рисуемой строки, к результату добавляются некоторые пикселы. Так как нам нужно точный результат (с тем чтобы следующий текст шёл сразу после предыдущего), мы можем использовать следующий трюк: измерим длину текста и длину продублированного текста (то есть "ТекстТекст"): поскольку в обоих случаях добавятся дополнительные пиксели, то разница между этими измерениями даст точную длину.

Скачать демонстрационный проект - 8 кб




Основные разделы сайта


 

Реклама Как и где купить билет на чартер http://www.charterok.ru/.