WPF搜索设置窗口实现:匹配GroupBox及其子控件文本属性
解决方案
核心思路
要实现需求,需要递归检查GroupBox的Header及其所有子控件的目标文本属性(Text、Content、Header、ToolTip),只要任意一项匹配搜索关键词,就保持GroupBox可见,否则折叠。
完整代码实现
首先添加两个辅助方法,用于提取控件文本属性和递归检查匹配:
// 提取单个控件的所有目标文本属性 private IEnumerable<string> GetAllTextProperties(Control control) { var textProperties = new List<string>(); // 检查Text属性(如TextBox、Label) if (!string.IsNullOrEmpty(control.Text)) textProperties.Add(control.Text); // 检查Content属性(如Button、ToggleButton) if (control.Content != null) textProperties.Add(control.Content.ToString()); // 检查Header属性(如GroupBox、Expander) if (control is HeaderedContentControl headeredControl && headeredControl.Header != null) textProperties.Add(headeredControl.Header.ToString()); // 检查ToolTip属性 if (control.ToolTip != null) textProperties.Add(control.ToolTip.ToString()); return textProperties; } // 递归检查控件及其子控件是否匹配搜索关键词 private bool IsControlMatching(Control control, string searchTerm) { // 检查当前控件的属性 foreach (var text in GetAllTextProperties(control)) { if (text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) return true; } // 递归检查容器控件的子控件 if (control is Panel panel) { foreach (var child in panel.Children) { if (child is Control childControl && IsControlMatching(childControl, searchTerm)) return true; } } // 检查ContentControl的内容控件 if (control is ContentControl contentControl && contentControl.Content is Control contentChild) { if (IsControlMatching(contentChild, searchTerm)) return true; } return false; }
然后修改searchSettingsTextBox_TextChanged事件处理逻辑:
private void searchSettingsTextBox_TextChanged(object sender, TextChangedEventArgs e) { var searchBox = sender as TextBox; var searchTerm = searchBox?.Text.Trim() ?? string.Empty; // 搜索框为空时显示所有GroupBox if (string.IsNullOrEmpty(searchTerm)) { foreach (GroupBox gb in wrapPanel1.Children) gb.Visibility = Visibility.Visible; return; } foreach (GroupBox gb in wrapPanel1.Children) { bool isMatch = false; // 先检查GroupBox自身的Header if (gb.Header != null && gb.Header.ToString().IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0) { isMatch = true; } else { // 再检查所有子控件 if (gb.Content is Grid contentGrid) { foreach (var child in contentGrid.Children) { if (child is Control childControl && IsControlMatching(childControl, searchTerm)) { isMatch = true; break; } } } } gb.Visibility = isMatch ? Visibility.Visible : Visibility.Collapsed; } }
关键细节说明
- 空值处理:所有可能为null的属性(Header、Content、ToolTip)都做了非空判断,避免空引用异常。
- 不区分大小写:使用
StringComparison.OrdinalIgnoreCase实现大小写无关的搜索,比转小写更高效。 - 递归遍历:支持嵌套控件的检查(比如Grid里的StackPanel、StackPanel里的Button等),确保所有层级的控件都被搜索到。
- 空搜索优化:搜索框为空时直接显示所有GroupBox,无需执行多余检查。
内容的提问来源于stack exchange,提问作者captain_majid
相关产品推荐
相关产品推荐

