将事件处理程序附加到动态创建的TreeViewItems

时间:2012-08-03 16:43:21

标签: .net silverlight data-binding silverlight-4.0 treeview

序言

我有以下XAML:

<controls:TreeView x:Name="tv">
    <controls:TreeViewItem x:Name="tvi" Header="RootNodeTitle" IsExpanded="True">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <controls:TreeViewItem Header="{Binding TextToBindTo}" Selected="TreeViewItem_Selected" />
            </DataTemplate>
         </ItemsControl.ItemTemplate>
     </controls:TreeViewItem>
</controls:TreeView>

以下.NET代码隐藏:

_viewCollection = New CollectionViewSource()
_viewCollection.Source = _data.RoleList
tvi.ItemsSource = _viewCollection.View

问题:

我想将事件处理程序附加到Selected个孩子的tvi事件(基于数据绑定动态生成。

我尝试在Selected="..."中使用ItemTemplate标记(如XAML中所示),但这不起作用。

问题:

如何做到这一点?

1 个答案:

答案 0 :(得分:1)

我不确定为什么没有在嵌套的TreeViewItem上处理Selected事件,但如果我们稍微更改它以在TreeView上设置ItemsSource,它就会被处理:

<controls:TreeView x:Name="tv"  SelectedItemChanged="tv_SelectedItemChanged">
        <controls:TreeView.ItemTemplate>
            <DataTemplate>
                <!-- this Selected event handler does get called -->
                <controls:TreeViewItem Header="{Binding Name}" Selected="TreeViewItem_Selected" >
...

然而,引发的事件不包含任何有关该项目的有用信息,因此您无法明智地从该事件中获得任何有用的信息。

Setting a handler for the SelectedItemChanged event on the TreeView works and also contains the usual OldValue and NewValue properties in the EventArgs.

该事件还会触发所有TreeViewItems - 嵌套与否。

试试这个:

<controls:TreeView x:Name="tv"  SelectedItemChanged="tv_SelectedItemChanged">
    <controls:TreeViewItem x:Name="tvi" Header="RootNodeTitle" IsExpanded="True" Selected="TreeViewItem_Selected" >
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <controls:TreeViewItem Header="{Binding}" Selected="TreeViewItem_Selected" >
                    <Border Background="Black" Height="25" Width="25" />
                </controls:TreeViewItem>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </controls:TreeViewItem>
</controls:TreeView>

...

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    tvi.ItemsSource = GetItems();

}

private IEnumerable GetItems()
{
    for (int i = 0; i < 10; i++)
    {
        yield return i;
    }
}

private void tv_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    var oldItem = e.OldValue;
    var newItem = e.NewValue;
}