在Silverlight项目开发中,经常会把一个独立功能的控件封装成一个UserControl,然后供其他页面或者控件进行调用。前一段时间,在项目中遇到一个问题,需要在同一个页面重复调用多个相同的UserControl控件,然后在父页面中控制这些重复生成的子控件。由于很多控件是动态生成,数量也是动态控制,所以所有的操作都需要使用后台代码进行实现。
在上面的需求中需要用到Silverlight API中的VisualTreeHelper类,对于VisualTreeHelper类,有不少文章已经介绍过,该类可以对Silverlight可视化树进行遍历,该可视化树是逻辑对象树的一个子集。我们可以通过VisualTreeHelper提供的方法GetChild(),GetParent()和GetChildrenCount(),分别获取子控件,父控件以及子控件数量。
在实际项目中,为满足实际开发需求,对VisualTreeHelper的方法重新进行封装是非常必要的。
首先要介绍的Hleper方法是GetParentObject方法,获取父控件方法。该方法将根据当前控件,遍历查找其父控件是否存在。参数1是表示当前子控件名,参数2是要查询父控件名;使用VisualTreeHelper.GetParent方法获取当前父控件。
public T GetParentObject<T>(DependencyObject obj,string name) where T : FrameworkElement { DependencyObject parent = VisualTreeHelper.GetParent(obj); while (parent != null) { if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name))) { return (T)parent; } parent = VisualTreeHelper.GetParent(parent); } return null; }
另外一个Helper方法是GetChildobject,获取子控件方法。该方法将根据当前控件,遍历查找其子控件是否存在。参数1是表示当前父控件名,参数2是要查询子控件名;
public T GetChildobject<T>(DependencyObject obj,string name) where T : FrameworkElement { DependencyObject child = null; T grandChild = null; for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) { child = VisualTreeHelper.GetChild(obj,i); if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name))) { return (T)child; } else { grandChild = GetChildobject<T>(child,name); if (grandChild != null) return grandChild; } } return null; }
最后介绍一个Helper方法是GetChildobjects方法,该方法将把所有子控件作为List集合返回到客户端。其中第一个参数是父控件参数,而第二个参数是特定子控件名称,如果需要遍历全部子控件,第二个参数留空即可。
public List<T> GetChildobjects<T>(DependencyObject obj,string name) where T : FrameworkElement { DependencyObject child = null; List<T> childList = new List<T>(); for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) { child = VisualTreeHelper.GetChild(obj,i); if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name))) { childList.Add((T)child); } childList.AddRange(GetChildobjects<T>(child,"")); } return childList; }
使用方法很简单,首先创建基础控件:
<UserControl x:Class="SLVisualTreeHelper.MainPage" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDeFinitions> <RowDeFinition Height="Auto"></RowDeFinition> <RowDeFinition Height="*"></RowDeFinition> </Grid.RowDeFinitions> <StackPanel x:Name="spDemoPanel" Orientation="Vertical" Grid.Row="0"> <TextBlock Margin="5">获取子控件和父控件演示</TextBlock> <TextBlock Margin="5">专注Silverlight技术交流</TextBlock> <TextBlock Margin="5">博客:http//jv9.cnblogs.com</TextBlock> <Button x:Name="btDemoButton" Width="120" Height="40" Content="获取所有控件" Click="btDemoButton_Click" HorizontalAlignment="Left" Margin="5"/> <Button x:Name="btModifyChild" Width="120" Height="40" Content="修改布局控件背景" Click="btModifyChild_Click" HorizontalAlignment="Left" Margin="5"/> <Button x:Name="btModifyChilds" Width="120" Height="40" Content="批量修改控件字体尺寸" Click="btModifyChilds_Click" HorizontalAlignment="Left" Margin="5"/> </StackPanel> <StackPanel x:Name="spResult" Grid.Row="1"> <TextBlock x:Name="tbResult"/> </StackPanel> </Grid> </UserControl>
namespace SLVisualTreeHelper { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void btDemoButton_Click(object sender,RoutedEventArgs e) { Globals VTHelper = new Globals(); StackPanel sp = VTHelper.GetChildobject<StackPanel>(this.LayoutRoot,"spDemoPanel"); Grid layoutGrid = VTHelper.GetParentObject<Grid>(this.spDemoPanel,"LayoutRoot"); List<TextBlock> textblock = VTHelper.GetChildobjects<TextBlock>(this.LayoutRoot,""); if (sp != null) { if (layoutGrid != null) { if (textblock.Count > 0) { tbResult.Text = "包含TextBlock控件数量为: " + textblock.Count.ToString() + "\n"; } tbResult.Text += "获取父控件成功....\n" ; } tbResult.Text += "获取子控件成功....\n"; } } private void btModifyChild_Click(object sender,"spDemoPanel"); sp.Background = new SolidColorBrush(Colors.Purple); } private void btModifyChilds_Click(object sender,RoutedEventArgs e) { Globals VTHelper = new Globals(); List<TextBlock> textblock = VTHelper.GetChildobjects<TextBlock>(this.LayoutRoot,""); foreach (TextBlock tmpTextblock in textblock) { tmpTextblock.FontSize += 6; } } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。