Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5226870
  • 博文数量: 1696
  • 博客积分: 10870
  • 博客等级: 上将
  • 技术积分: 18357
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-30 15:16
文章分类
文章存档

2017年(1)

2016年(1)

2015年(1)

2013年(1)

2012年(43)

2011年(17)

2010年(828)

2009年(568)

2008年(185)

2007年(51)

分类: 嵌入式

2010-10-26 21:10:03

  过去一直有个Silverlight的技术疑难没有得到解决,那就是如果在Code Behind中获取模板中定义的各个对象的引用。参考一下Xaml代码:

 

代码
     <ListBox x:Name="lbx_listBox"
>

     
<ItemsPanelTemplate x:Key="fileListItemsPanelTemplate">
   
<controlsToolkit:WrapPanel x:Name="wrp_listWrapper"

                   Width
="450"

                   Orientation
="Horizontal" />
   
ItemsPanelTemplate>
ListBox.ItemPanel>
ListBox>

  这段代码定义了一个列表,列表中我选用WrapPanel作为列表项的容器,很明显是为了实现水平列表项自动换行的功能。但现在我是硬编码了 450这个宽度给WrapPanel,因此当列表控件变大或缩小时,WrapPanel不会自动跟随变化。由此,我必须实现一个自动更新的机制。可以使用 数据绑定,或者使用ListBox的SizeChanged事件。但无论使用哪种方式,我都必须获取这个WrapPanel对象的引用。

  我故意给这个WrapPanel一个Name属性(值为wrp_listWrapper),这样并不会引起编译错误或者运行时异常。但尽管拥有一个Name属性,我仍然无法从Code Behind中获取该WrapPanel的引用,因为它是定义在模板中的对象。

  实现获取引用的方式就是Loaded事件。参考以下改进代码:

代码
     <ListBox x:Name="lbx_listBox"
>

     
<ItemsPanelTemplate x:Key="fileListItemsPanelTemplate">
   
<controlsToolkit:WrapPanel x:Name="wrp_listWrapper"

                   Width
="450"

                   Orientation
="Horizontal"

                   Loaded
="wrp_listWrapper_Loaded"/>
   
ItemsPanelTemplate>
ListBox.ItemPanel>
ListBox>

  高亮的代码就是对WrapPanel的Loaded事件注册处理程序。该事件只会在列表加载完成时触发一次,仅一次。于是在Code Behind中,采用以下代码保存该WrapPanel的引用:

private WrapPanel m_listWrapper;

  
private void wrp_listWrapper_Loaded(object sender, RoutedEventArgs e)
{
m_listWrapper
= sender as WrapPanel;

  }

  就是这样简单的方式,就可以把这个定义在模板中的WrapPanel对象的引用保存下来了。对于其他类似的,定义在模板中的控件对象也能使用这种方式。但要注意,假如面对的是

DataTemplate这一类模板,一般会被多个数据项使用,例如一个ListBox中的DataTemplate会被该ListBox的所有列 表项使用。这种情况下,模板中定义的控件的Loaded事件会发生多次,每次是由不一样的列表项触发。但事件处理程序就只有一个,因此必须要在该程序代码 中想办法区分各个实例。

  例如:

代码
     <ListBox x:Name="lbx_listBox"
>

    
<DataTemplate>

      
<Image src={Binding} Loaded="Image_Loaded"/>

    
DataTemplate>
ListBox.ItemTemplate>
ListBox>

  该ListBox中的每个列表项都是一张图片。假如我们用同样的方法在Code Behide中获取该图片的引用:

  private IList<Image> m_imgs = new List<Image>();

  
private void Image_Loaded(object sender, RoutedEventArgs e)
{
m_imgs.Add(sender
as Image);  

  }

  这里要使用一个Image的List集合来保存模板中的Image,因为多个列表项会运行多次该处理程序。假如要选择指定的某一个Image,则必须添加筛选代码。

阅读(1065) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-12-02 11:39:51

public override void OnApplyTemplate() // Override OnApplyTemplate function, get template child from control templates declared in app.xaml or generic.xaml, and then assign to corresponding C# object declared in code-behind C# files. { base.OnApplyTemplate(); stackPanel = GetTemplateChild("StackPanel") as StackPanel; scrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer; }