• Silverlight获取子控件和父控件方法


    在Silverlight项目开发中,经常会把一个独立功能的控件封装成一个UserControl,然后供其他页面或者控件进行调用。前一段时间,在项目中遇到一个问题,需要在同一个页面重复调用多个相同的UserControl控件,然后在父页面中控制这些重复生成的子控件。由于很多控件是动态生成,数量也是动态控制,所以所有的操作都需要使用后台代码进行实现。

    在上面的需求中需要用到Silverlight API中的VisualTreeHelper类,对于VisualTreeHelper类,有不少文章已经介绍过,该类可以对Silverlight可视化树进行遍历,该可视化树是逻辑对象树的一个子集。我们可以通过VisualTreeHelper提供的方法GetChild(),GetParent()和GetChildrenCount(),分别获取子控件,父控件以及子控件数量。

    在实际项目中,为满足实际开发需求,对VisualTreeHelper的方法重新进行封装是非常必要的。

    首先要介绍的Hleper方法是GetParentObject方法,获取父控件方法。该方法将根据当前控件,遍历查找其父控件是否存在。参数1是表示当前子控件名,参数2是要查询父控件名;使用VisualTreeHelper.GetParent方法获取当前父控件。

     1  public T GetParentObject<T>(DependencyObject obj, string name) where T : FrameworkElement
     2         {
     3             DependencyObject parent = VisualTreeHelper.GetParent(obj);
     4 
     5             while (parent != null)
     6             {
     7                 if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
     8                 {
     9                     return (T)parent;
    10                 }
    11 
    12                 parent = VisualTreeHelper.GetParent(parent);
    13             }
    14 
    15             return null;
    16         }
    17 

    另外一个Helper方法是GetChildObject,获取子控件方法。该方法将根据当前控件,遍历查找其子控件是否存在。参数1是表示当前父控件名,参数2是要查询子控件名;

     1 public T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
     2         {
     3             DependencyObject child = null;
     4             T grandChild = null;
     5 
     6             for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
     7             {
     8                 child = VisualTreeHelper.GetChild(obj, i);
     9 
    10                 if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
    11                 {
    12                     return (T)child;
    13                 }
    14                 else
    15                 {
    16                     grandChild = GetChildObject<T>(child, name);
    17                     if (grandChild != null)
    18                         return grandChild;
    19                 }
    20             }
    21 
    22             return null;
    23 
    24         }

    最后介绍一个Helper方法是GetChildObjects方法,该方法将把所有子控件作为List集合返回到客户端。其中第一个参数是父控件参数,而第二个参数是特定子控件名称,如果需要遍历全部子控件,第二个参数留空即可。

     1 public List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
     2         {
     3             DependencyObject child = null;
     4             List<T> childList = new List<T>();
     5 
     6             for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
     7             {
     8                 child = VisualTreeHelper.GetChild(obj, i);
     9 
    10                 if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name)))
    11                 {
    12                     childList.Add((T)child);
    13                 }
    14 
    15                 childList.AddRange(GetChildObjects<T>(child,""));
    16             }
    17 
    18             return childList;
    19 
    20         }

    下面用一个例程演示使用方法:

    使用方法很简单,首先创建基础控件:

     1 <UserControl x:Class="SLVisualTreeHelper.MainPage"
     2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     5     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     6     mc:Ignorable="d"
     7     d:DesignHeight="300" d:DesignWidth="400">
     8 
     9     <Grid x:Name="LayoutRoot" Background="White">
    10         <Grid.RowDefinitions>
    11             <RowDefinition Height="Auto"></RowDefinition>
    12             <RowDefinition Height="*"></RowDefinition>
    13         </Grid.RowDefinitions>
    14         <StackPanel x:Name="spDemoPanel" Orientation="Vertical" Grid.Row="0">
    15             <TextBlock Margin="5">获取子控件和父控件演示</TextBlock>
    16             <TextBlock Margin="5">专注Silverlight技术交流</TextBlock>
    17             <TextBlock Margin="5">博客:http//jv9.cnblogs.com</TextBlock>
    18             <Button x:Name="btDemoButton" Width="120" Height="40" Content="获取所有控件" Click="btDemoButton_Click" HorizontalAlignment="Left" Margin="5"/>
    19             <Button x:Name="btModifyChild" Width="120" Height="40" Content="修改布局控件背景" Click="btModifyChild_Click" HorizontalAlignment="Left" Margin="5"/>
    20             <Button x:Name="btModifyChilds" Width="120" Height="40" Content="批量修改控件字体尺寸" Click="btModifyChilds_Click" HorizontalAlignment="Left" Margin="5"/>
    21         </StackPanel>
    22         
    23         <StackPanel x:Name="spResult" Grid.Row="1">
    24             <TextBlock x:Name="tbResult"/>
    25         </StackPanel>
    26 
    27     </Grid>
    28 </UserControl>
    29 

    然后在后台代码,声明实例进行调用,

     1 namespace SLVisualTreeHelper
     2 {
     3     public partial class MainPage : UserControl
     4     {
     5         
     6         public MainPage()
     7         {
     8             InitializeComponent();
     9         }
    10 
    11         private void btDemoButton_Click(object sender, RoutedEventArgs e)
    12         {
    13             Globals VTHelper = new Globals();
    14             StackPanel sp = VTHelper.GetChildObject<StackPanel>(this.LayoutRoot, "spDemoPanel");
    15             Grid layoutGrid = VTHelper.GetParentObject<Grid>(this.spDemoPanel, "LayoutRoot");
    16             List<TextBlock> textblock = VTHelper.GetChildObjects<TextBlock>(this.LayoutRoot, "");
    17          
    18            
    19             if (sp != null)
    20             {
    21                 if (layoutGrid != null)
    22                 {
    23                     
    24                     if (textblock.Count > 0)
    25                     {
    26                         tbResult.Text = "包含TextBlock控件数量为: " + textblock.Count.ToString() + "\n";
    27                     }
    28                     tbResult.Text += "获取父控件成功....\n" ;
    29                 }
    30                 tbResult.Text += "获取子控件成功....\n";
    31             }
    32         }
    33 
    34         private void btModifyChild_Click(object sender, RoutedEventArgs e)
    35         {
    36             Globals VTHelper = new Globals();
    37             StackPanel sp = VTHelper.GetChildObject<StackPanel>(this.LayoutRoot, "spDemoPanel");
    38             sp.Background = new SolidColorBrush(Colors.Purple); 
    39         }
    40 
    41         private void btModifyChilds_Click(object sender, RoutedEventArgs e)
    42         {
    43             Globals VTHelper = new Globals();
    44             List<TextBlock> textblock = VTHelper.GetChildObjects<TextBlock>(this.LayoutRoot, "");
    45             foreach (TextBlock tmpTextblock in textblock)
    46             {
    47                 tmpTextblock.FontSize += 6;
    48             }
    49         }
    50     }
    51 }

    其中Globals类中包含前文介绍的几个获取代码。

    在线演示:

     
    最后是源代码下载,项目是VS2010+Silverlight 4,点击下载
     

    欢迎大家加入"专注Silverlight" 技术讨论群:

    32679955(六群)
    23413513(五群)
    32679922(四群)
    100844510(三群)

    37891947(二群)

    22308706(一群)

  • 相关阅读:
    IOS中的国际化的使用(Xcode 6.0之后的使用步骤)
    KVC,KVO的区别和使用
    通知,代理,block 单例的使用和区别
    NSoperation的使用
    多线程之Nsthread的使用方法
    多线程的之GCD的介绍
    IOS中生成证书、真机调试、上线发布程序的步骤
    IOS之NavigationController跳转到指点的界面
    IOS之截取字符串的使用方法
    ios 之定时器的使用的技巧(结合runloop)使用
  • 原文地址:https://www.cnblogs.com/jv9/p/1766459.html
Copyright © 2020-2023  润新知