From a3282538425ce9576408a6544d731f5777015290 Mon Sep 17 00:00:00 2001 From: Ben Nordick Date: Thu, 24 Jun 2021 21:31:19 -0400 Subject: [PATCH] Improve supported product filter tree --- PolicyPlus/FilterOptions.Designer.vb | 2 +- PolicyPlus/FilterOptions.vb | 36 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/PolicyPlus/FilterOptions.Designer.vb b/PolicyPlus/FilterOptions.Designer.vb index ab8f3db..3358d82 100644 --- a/PolicyPlus/FilterOptions.Designer.vb +++ b/PolicyPlus/FilterOptions.Designer.vb @@ -31,7 +31,7 @@ Partial Class FilterOptions Me.OkButton = New System.Windows.Forms.Button() Me.ResetButton = New System.Windows.Forms.Button() Me.RequirementsBox = New System.Windows.Forms.GroupBox() - Me.AllowedProductsTreeview = New System.Windows.Forms.TreeView() + Me.AllowedProductsTreeview = New PolicyPlus.DoubleClickIgnoringTreeView() Me.MatchBlankSupportCheckbox = New System.Windows.Forms.CheckBox() Me.AlwaysMatchAnyCheckbox = New System.Windows.Forms.CheckBox() Me.SupportedCheckbox = New System.Windows.Forms.CheckBox() diff --git a/PolicyPlus/FilterOptions.vb b/PolicyPlus/FilterOptions.vb index 42f9480..289f095 100644 --- a/PolicyPlus/FilterOptions.vb +++ b/PolicyPlus/FilterOptions.vb @@ -58,6 +58,19 @@ Next AlwaysMatchAnyCheckbox.Checked = Configuration.AlwaysMatchAny MatchBlankSupportCheckbox.Checked = Configuration.MatchBlankSupport + ' Expand to show all products with a different check state than their parent + Dim expandIfNecessary As Action(Of TreeNode) + expandIfNecessary = Sub(Node As TreeNode) + For Each subnode As TreeNode In Node.Nodes + expandIfNecessary(subnode) + If subnode.IsExpanded Or subnode.Checked <> Node.Checked Then + Node.Expand() + End If + Next + End Sub + For Each node As TreeNode In AllowedProductsTreeview.Nodes + expandIfNecessary(node) + Next End If End Sub Private Sub SupportedCheckbox_CheckedChanged(sender As Object, e As EventArgs) Handles SupportedCheckbox.CheckedChanged @@ -110,11 +123,15 @@ AllowedProductsTreeview.BackColor = If(AllowedProductsTreeview.Enabled, SystemColors.Window, SystemColors.Control) End Sub Private Sub AllowedProductsTreeview_AfterCheck(sender As Object, e As TreeViewEventArgs) Handles AllowedProductsTreeview.AfterCheck - If e.Node.Checked Then - For Each subnode As TreeNode In e.Node.Nodes - subnode.Checked = True - Next - End If + ' Recursively set the check state on child products only in response to the user + If e.Action = TreeViewAction.Unknown Then Return + PropogateCheckStateDown(e.Node) + End Sub + Sub PropogateCheckStateDown(Node As TreeNode) + For Each subnode As TreeNode In Node.Nodes + subnode.Checked = Node.Checked + PropogateCheckStateDown(subnode) + Next End Sub End Class Public Enum FilterPolicyState @@ -130,4 +147,13 @@ Public Class FilterConfiguration Public AllowedProducts As List(Of PolicyPlusProduct) Public AlwaysMatchAny As Boolean Public MatchBlankSupport As Boolean +End Class +' The TreeView control has a bug: the displayed check state gets out of sync with the Checked property when the checkbox is double-clicked +' Fix adapted from https://stackoverflow.com/a/3174824 +Friend Class DoubleClickIgnoringTreeView + Inherits TreeView + Protected Overrides Sub WndProc(ByRef m As Message) + ' Ignore WM_LBUTTONDBLCLK + If m.Msg <> &H203 Then MyBase.WndProc(m) + End Sub End Class \ No newline at end of file