Replies
And here is approximately the same code in VB.Net.
I haven't used/verified this actual code since I did something different, but figured I'd post this as a starter help for anyone in the need for it.
Partial Public Class MyComboEditor
Inherits UltraComboEditor
''' <summary>
''' Occurs when the value is about to be changed
''' </summary>
Public Event ValueChanging As EventHandler(Of CancelEventArgs)
''' <summary>
''' Holds the previous value in order to allow rollback
''' </summary>
Protected _OldValue As Object
Private _SkipValueChanging As Boolean
Public Sub New()
InitializeComponent()
Me._OldValue = Nothing
End Sub
''' <summary>
''' Rollbacks the value changing if ValueChanging was cancelled
''' </summary>
Protected Overrides Sub OnValueChanged(ByVal args As EventArgs)
If Me._SkipValueChanging Then Return
Dim e As CancelEventArgs = New CancelEventArgs()
OnValueChanging(e)
If e.Cancel Then 'Roll back the value change if ValueChanging was cancelled
Me._SkipValueChanging = True
If Me._OldValue Is Nothing Then
Me.SelectedItem = Nothing
Else
Me.Value = _OldValue
End If
Me._SkipValueChanging = False
End If
MyBase.OnValueChanged(args)
End Sub
Protected Overridable Sub OnValueChanging(ByVal args As CancelEventArgs)
RaiseEvent ValueChanging(Me, args)
End Sub
Public Overrides Property Value As Object
Get
Return MyBase.Value
End Get
Set(ByVal value As Object)
MyBase.Value = value
Me._OldValue = value
End Set
End Property
End Class
@genvej and GoDaddy
I don't know what GoDaddy's implementation looked like, but if someone is looking for code (as I was) I'd like to share the implementation I came up with, based on the Knowledge Base article. Feel free to use as you wish and to improve it. 🙂
The checkbox/selection tree view behaves the way I expect it to:
If a node's CheckState changes, then all child nodes (recursively) are updated to the same state (Checked or Unchecked), and also the CheckState of the parent nodes (recursively) are recalculated (to Checked, Unchecked or Indeterminate).
(Of course just put this in a class as GoDaddy suggests.)
—
Imports Infragistics.Win.UltraWinTree
Public Class Form1
Inherits System.Windows.Forms.Form
''' <summary>
''' The updatingLock is used because we only want to take
''' special actions (HandleTreeCheckedStateChanges(…))
''' on Check changes caused by user actions (e.g. clicks)
''' and ignore programmatic CheckState changes.
''' </summary>
Private updatingLock As Boolean = False
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents baseTree As Infragistics.Win.UltraWinTree.UltraTree
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.baseTree = New Infragistics.Win.UltraWinTree.UltraTree()
CType(Me.baseTree, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'ultraTree1
'
Me.baseTree.Dock = System.Windows.Forms.DockStyle.Fill
Me.baseTree.Location = New System.Drawing.Point(0, 0)
Me.baseTree.Name = "baseTree"
Me.baseTree.Size = New System.Drawing.Size(292, 266)
Me.baseTree.TabIndex = 1
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.baseTree)
Me.Name = "Form1"
Me.Text = "Form1"
CType(Me.baseTree, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CreateExampleTree()
' Add checkboxes to tree
Me.baseTree.Override.NodeStyle = NodeStyle.CheckBoxTriState
End Sub
Private Sub CreateExampleTree()
Dim i, j, k As Integer
For i = 1 To 5
Dim rootNode As UltraTreeNode = Me.baseTree.Nodes.Add("Node " + i.ToString())
For j = 1 To 5
Dim childNode As UltraTreeNode
childNode = rootNode.Nodes.Add(rootNode.Key + " Child " + j.ToString())
For k = 1 To 5
Dim childchildNode As UltraTreeNode
childchildNode = childNode.Nodes.Add(childNode.Key + " Child " + k.ToString())
Next k
Next j
Next i
End Sub
Private Sub baseTree_BeforeCheck(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinTree.BeforeCheckEventArgs) Handles baseTree.BeforeCheck
Dim treeNode As UltraTreeNode = e.TreeNode
' Do not allow Indeterminate state for leaves.
If IsLeafNode(treeNode) Then treeNode.Override.NodeStyle = NodeStyle.CheckBox
End Sub
Private Sub baseTree_AfterCheck(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinTree.NodeEventArgs) Handles baseTree.AfterCheck
If updatingLock Then Return 'Because the Check change was caused programatically in HandleTreeCheckedStateChanges(…)
Dim treeNode As UltraTreeNode = e.TreeNode
updatingLock = True 'Begin handling checked state changes of the tree
HandleTreeCheckedStateChanges(TreeNode)
updatingLock = False 'End handling checked state changes of the tree
End Sub
''' <summary>
''' When a tree node has been clicked and its CheckState has
''' changed we need to update the CheckState of the nodes
''' below and above in the tree.
''' </summary>
Private Sub HandleTreeCheckedStateChanges(ByVal treeNode As UltraTreeNode)
' Each time a non-leaf node's CheckState changes
' 1) Make sure it is Checked or Unchecked – we should not be able to make it indeterminate by clicking!
If treeNode.CheckedState = CheckState.Indeterminate Then treeNode.CheckedState = CheckState.Unchecked ' Since NodeStates: Unchecked => Checked => Indeterminate
' 2) Set all child nodes to same state.
SetChildNodesCheckStatesToSameAs(treeNode)
UpdateParentNodeCheckState(treeNode)
End Sub
Private Sub SetChildNodesCheckStatesToSameAs(ByVal treeNode As UltraTreeNode)
If IsLeafNode(treeNode) Then Return 'End recursion
For Each childNode As UltraTreeNode In treeNode.Nodes
childNode.CheckedState = treeNode.CheckedState
SetChildNodesCheckStatesToSameAs(childNode)
Next
End Sub
''' <summary>
''' Verifies the CheckState of the parent node for the
''' specified treeNode, by setting the parent node's
''' CheckState property based on whether none, some,
''' or all of its child nodes are currently checked.
''' </summary>
''' <param name="treeNode"></param>
''' <remarks>This method only has relevance for non root-level nodes</remarks>
Private Sub UpdateParentNodeCheckState(ByVal treeNode As UltraTreeNode)
Dim parentNode As UltraTreeNode = treeNode.Parent
If parentNode Is Nothing Then Return 'End recursion
' Get the nodes collection to which the specified childNode belongs
Dim nodesCollection As TreeNodesCollection = treeNode.ParentNodesCollection
' count of the number of checked nodes
Dim checkedNodesCount As Integer = 0
Dim indeterminateCount As Integer = 0
For Each node As UltraTreeNode In nodesCollection
If node.CheckedState = CheckState.Checked Then checkedNodesCount += 1
If node.CheckedState = CheckState.Indeterminate Then indeterminateCount += 1
Next
' Set appropriate CheckState of the parentNode
If checkedNodesCount = nodesCollection.Count Then
parentNode.CheckedState = CheckState.Checked
ElseIf checkedNodesCount = 0 AndAlso indeterminateCount = 0 Then
parentNode.CheckedState = CheckState.Unchecked
Else
parentNode.CheckedState = CheckState.Indeterminate
End If
' Traverse up the tree…
UpdateParentNodeCheckState(parentNode)
End Sub
Private Function IsLeafNode(ByVal treeNode As UltraTreeNode) As Boolean
Return treeNode.Nodes.Count = 0
End Function
End Class