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

原创 2012年03月22日 21:15:50

在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, RoutedEventArgs e)
         {
             Globals VTHelper = new Globals();
             StackPanel sp = VTHelper.GetChildObject<StackPanel>(this.LayoutRoot, "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;
             }
         }
     }
 }


 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

WPF中查找子控件、父控件的方法

/// /// 查找指定类型的子控件 /// /// 子控件类型 /// 父控件 /// publ...

子控件在父控件上的显示问题

创建了子控件,在父控件上或窗口上看不到: 1. 当前控件没有添加到父控件中 2. 当前控件的hidden = YES 3. 当前控件的alpha <= 0.01 4. 没有设置尺寸(frame.siz...

自定义根据屏幕宽度子控件根据父控件行宽自动换行的ViewGroup

自定义根据屏幕宽度子控件根据父控件行宽自动换行的ViewGroup import android.content.Context; import android.util.AttributeSet; ...

解决ViewFlow在Scrollview下滑动不灵敏的BUG(解决viewflow与父控件的滑动事件冲突问题)

转自http://www.oschina.net/question/778954_158470?sort=time   第一次在开源中国发分享贴,有点小紧张,把我最近遇到的问题和解决方法分享出来,...

使子控件超出父控件的限制

使根布局设置clipChildren =false,然后将要设置突出的布局位置设置固定,如android:layout_gravity=”bottom”代码如下 <LinearLayout xm...
  • g951dd
  • g951dd
  • 2016-03-03 20:03
  • 3912

#375 – 将Tooltip 于父控件的某个属性绑定(Binding Something in a Tooltip to a Property on the Parent Control)

你可以直接将简单的将控件的某个属性和Tooltip 进行绑定。但是如果Tooltip 的内容是自定义的的,如何使用数据绑定呢? 假设你的Tooltip 的内容中包含了若干个Label,而你想其中某个L...

android:layout_marginLeft指该控件距离边父控件的边距, android:paddingLeft指该控件内部内容,如文本距离该控件的边距。

android:layout_marginLeft指该控件距离边父控件的边距, android:paddingLeft指该控件内部内容,如文本距离该控件的边距。   如: 当按...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)