WPF MVVM FindVisualChildren get all elements, get element by name, get elements by type
public List<Visual> FindVisualChildren(DependencyObject dpObj) { List<Visual> childrenList = new List<Visual>(); int childrenCount = VisualTreeHelper.GetChildrenCount(dpObj); for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(dpObj, i) as Visual; if (child != null) { childrenList.Add(child); childrenList.AddRange(FindVisualChildren(child)); } } return childrenList; } public List<Visual> FindVisualChildrenByType(DependencyObject dpObj, string typeName) { List<Visual> visualsList = FindVisualChildren(dpObj)?.Where(x => x.GetType().Name == typeName).ToList(); return visualsList; } public Visual FindVisualChildrenByName(DependencyObject dpObj, string elementName) { var element = FindVisualChildren(dpObj)?.Where(x => ((FrameworkElement)x).Name == elementName).FirstOrDefault(); return element; }
Border AdornerDecorator ContentPresenter Grid ToolBar Grid,Grid Grid,OverflowGrid ToggleButton,OverflowButton Border,Bd Canvas Path Path Path Path Popup,OverflowPopup Border,MainPanelBorder DockPanel Thumb,ToolBarThumb Border Rectangle ContentPresenter,ToolBarHeader ToolBarPanel,PART_ToolBarPanel Button Border,Bd ContentPresenter TextBlock Button Border,Bd ContentPresenter TextBlock Button Border,Bd ContentPresenter TextBlock TextBox Border,Border ScrollViewer,PART_ContentHost Grid Rectangle ScrollContentPresenter TextBoxView AdornerLayer ScrollBar ScrollBar TextBox Border,Border ScrollViewer,PART_ContentHost Grid Rectangle ScrollContentPresenter TextBoxView AdornerLayer ScrollBar ScrollBar DataGrid Border ScrollViewer,DG_ScrollViewer Grid Button Grid Rectangle,Border Polygon,Arrow DataGridColumnHeadersPresenter,PART_ColumnHeadersPresenter Grid DataGridColumnHeader,PART_FillerColumnHeader Grid DataGridHeaderBorder ContentPresenter Thumb,PART_LeftHeaderGripper Border Thumb,PART_RightHeaderGripper Border ItemsPresenter DataGridCellsPanel ScrollContentPresenter,PART_ScrollContentPresenter ItemsPresenter DataGridRowsPresenter,PART_RowsPresenter AdornerLayer ScrollBar,PART_VerticalScrollBar Grid ScrollBar,PART_HorizontalScrollBar DataGrid,dg1 Border ScrollViewer,DG_ScrollViewer Grid Button Grid Rectangle,Border Polygon,Arrow DataGridColumnHeadersPresenter,PART_ColumnHeadersPresenter Grid DataGridColumnHeader,PART_FillerColumnHeader Grid DataGridHeaderBorder ContentPresenter Thumb,PART_LeftHeaderGripper Border Thumb,PART_RightHeaderGripper Border ItemsPresenter DataGridCellsPanel ScrollContentPresenter,PART_ScrollContentPresenter ItemsPresenter DataGridRowsPresenter,PART_RowsPresenter AdornerLayer ScrollBar,PART_VerticalScrollBar Grid ScrollBar,PART_HorizontalScrollBar Canvas ListBox,lv Border,Bd ScrollViewer Grid Rectangle ScrollContentPresenter ItemsPresenter VirtualizingStackPanel AdornerLayer ScrollBar ScrollBar AdornerLayer Total :123 frameworkelements!
//xaml <Window x:Class="WpfApp52.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" WindowState="Maximized" xmlns:local="clr-namespace:WpfApp52" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style x:Key="{x:Static ToolBar.ButtonStyleKey}" TargetType="{x:Type Button}"> <Setter Property="FontSize" Value="20"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="Width" Value="200"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Foreground" Value="Red"/> <Setter Property="FontSize" Value="30"/> <Setter Property="Width" Value="300"/> </Trigger> </Style.Triggers> </Style> <Style x:Key="{x:Static ToolBar.TextBoxStyleKey}" TargetType="{x:Type TextBox}"> <Setter Property="FontSize" Value="20"/> <Setter Property="Width" Value="200"/> <Setter Property="BorderBrush" Value="Blue"/> <Setter Property="BorderThickness" Value="5"/> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ToolBar Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> <Button Content="Find All Children" Command="{Binding FindAllChildrenCommand}"/> <Button Content="Find Children by Type" Command="{Binding FindChildrenByTypeCommand}"/> <Button Content="Find Children by Name" Command="{Binding FindChildrenByNameCommand}"/> <TextBox Text="{Binding ChildTypeName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ToolTip="Child Type Name" /> <TextBox Text="{Binding ChildName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ToolTip="Child Name"/> </ToolBar> <DataGrid Grid.Row="1" Grid.Column="0" BorderBrush="Blue" BorderThickness="5"/> <DataGrid x:Name="dg1" Grid.Row="1" Grid.Column="1" BorderBrush="Blue" BorderThickness="5"/> <Canvas Grid.Row="2" Grid.Column="0"/> <ListBox x:Name="lv" Grid.Row="2" Grid.Column="1" BorderBrush="Blue" BorderThickness="5"/> </Grid> </Window> //window.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp52 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var vm = new MainVM(this); this.DataContext = vm; } } } //viewmodel.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; namespace WpfApp52 { public class MainVM: INotifyPropertyChanged { private Window mainWin; public MainVM(Window win) { mainWin = win; InitCommands(); } private void InitCommands() { FindAllChildrenCommand = new DelCommand(FindAllChildrenCommandExecuted); FindChildrenByTypeCommand = new DelCommand(FindChildrenByTypeCommandExecuted, FindChildrenByTypeCommandCanExecute); FindChildrenByNameCommand = new DelCommand(FindChildrenByNameCommandExecuted, FindChildrenByNameCommandCanExecute); } private bool FindChildrenByNameCommandCanExecute(object obj) { if(!string.IsNullOrWhiteSpace(ChildName)) { return true; } return false; } private bool FindChildrenByTypeCommandCanExecute(object obj) { if(!string.IsNullOrWhiteSpace(ChildTypeName)) { return true; } return false; } private void FindChildrenByNameCommandExecuted(object obj) { var element = FindVisualChildren(mainWin).Where(x => (x as FrameworkElement)?.Name == ChildName)?.FirstOrDefault(); MessageBox.Show($"Name:{ChildName}"); } private void FindChildrenByTypeCommandExecuted(object obj) { var typedElemnts = FindVisualChildren(mainWin).Where(x => x.GetType().Name == ChildTypeName)?.ToList(); if(typedElemnts!=null && typedElemnts.Any()) { StringBuilder typeBuilder = new StringBuilder(); foreach(var element in typedElemnts) { typeBuilder.AppendLine(element.GetType().Name+" "+(element as FrameworkElement)?.Name); } Console.WriteLine(typeBuilder.ToString()); } } private void FindAllChildrenCommandExecuted(object obj) { var elements=FindVisualChildren(mainWin); if(elements!=null) { StringBuilder builder = new StringBuilder(); foreach(var element in elements) { var fe = element as FrameworkElement; if(fe!=null) { string info = $"{fe.GetType().Name}"; if(!string.IsNullOrWhiteSpace(fe.Name)) { info += $",{fe.Name}"; } builder.AppendLine(info); } Console.WriteLine(builder.ToString()); Console.WriteLine($"Total :{elements.Count} frameworkelements!"); } } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private string childName; public string ChildName { get { return childName; } set { if(value!=childName) { childName = value; OnPropertyChanged(nameof(ChildName)); } } } private string childTypeName; public string ChildTypeName { get { return childTypeName; } set { if(value!=childTypeName) { childTypeName = value; OnPropertyChanged(nameof(ChildTypeName)); } } } public DelCommand FindAllChildrenCommand { get; set; } public DelCommand FindChildrenByTypeCommand { get; set; } public DelCommand FindChildrenByNameCommand { get; set; } public List<Visual> FindVisualChildren(DependencyObject dpObj) { List<Visual> childrenList = new List<Visual>(); int childrenCount = VisualTreeHelper.GetChildrenCount(dpObj); for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(dpObj, i) as Visual; if (child != null) { childrenList.Add(child); childrenList.AddRange(FindVisualChildren(child)); } } return childrenList; } public List<Visual> FindVisualChildrenByType(DependencyObject dpObj, string typeName) { List<Visual> visualsList = FindVisualChildren(dpObj)?.Where(x => x.GetType().Name == typeName).ToList(); return visualsList; } public Visual FindVisualChildrenByName(DependencyObject dpObj, string elementName) { var element = FindVisualChildren(dpObj)?.Where(x => ((FrameworkElement)x).Name == elementName).FirstOrDefault(); return element; } } public class DelCommand : ICommand { private Action<object> execute; private Predicate<object> canExecute; public DelCommand(Action<object> executeValue, Predicate<object> canExecuteValue = null) { execute = executeValue; canExecute = canExecuteValue; } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public bool CanExecute(object parameter) { if (canExecute == null) { return true; } return canExecute(parameter); } public void Execute(object parameter) { execute(parameter); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现