在Completed
的{{1}}事件的处理程序中,如何获取故事板应用于的元素?
我的故事板是ItemTemplate的一部分:
Storyboard
在<ListBox x:Name="MyListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="Container" Height="30" >
<Grid.Resources>
<Storyboard x:Name="FadeOut" BeginTime="0:0:7" Completed="FadeOut_Completed">
<DoubleAnimation From="1.0" To="0.0" Duration="0:0:3" Storyboard.TargetName="Container" Storyboard.TargetProperty="Opacity" />
</Storyboard>
</Grid.Resources>
[...snip...]
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
事件中,我想抓住名为 Container 的网格,以便我可以使用其DataContext进行讨厌的事情。可以这样做,还是我错误的方式?
谢谢:)
答案 0 :(得分:2)
答案是,这是不可能的 - 不管是在Silverlight 3中。
使用调试器我能够找到故事板的私有属性,当我走到对象树时,我得到了包含模板项 - 但由于安全限制,我无法使用反射从代码中触摸它放在silverlight应用程序上(尽管这可能在WPF中可能)。
我的最终解决方案涉及使用Dictionary<Storyboard, Grid>
和一些事件处理程序。使用模板我附加了Loaded
处理程序,这意味着每次创建和加载模板的实例时(即对于绑定到列表框的每个数据项),都会调用我的处理程序。此时,我有一个模板的物理实例的引用,所以我可以搜索其子代的故事板:
private void ItemTemplate_Loaded(object sender, RoutedEventArgs e)
{
Storyboard s = getStoryBoard(sender);
if (s != null)
{
if (!_startedStoryboards.ContainsKey(s))
_startedStoryboards.Add(s, (Grid)sender);
}
}
private Storyboard getStoryBoard(object container)
{
Grid g = container as Grid;
if (g != null)
{
if (g.Resources.Contains("FadeOut"))
{
Storyboard s = g.Resources["FadeOut"] as Storyboard;
return s;
}
}
return null;
}
private Dictionary<Storyboard, Grid> _startedStoryboards = new Dictionary<Storyboard, Grid>();
然后当故事板的Completed
事件被触发时,我可以轻松地使用这个字典作为查找来检索它所托管的项目模板,从那里我可以得到项目的DataContext
模板并做我计划的令人讨厌的事情:
private void FadeOut_Completed(object sender, EventArgs e)
{
if (_startedStoryboards.ContainsKey((Storyboard)sender))
{
Grid g = _startedStoryboards[(Storyboard)sender];
if (g.DataContext != null)
{
MyDataItem z = g.DataContext as MyDataItem;
if (z != null)
{
... do my thing ...
}
}
}
}
[注意:此代码已经过清理以供公众查看,请原谅您可能发现的任何小差异或语法错误]