在WPF中为TreeViewItem创建事件处理程序

5
我正在通过ItemsSource属性和ItemTemplate属性向TreeView控件添加项,并设置TreeViewItem的模板。如何在TreeViewItems上添加事件处理程序以处理选择更改事件?
目前,我的ItemTemplate如下所示:
<Window.Resources><DataTemplate x:Key="PeerDetailTemplate">
        <TextBlock Text="{Binding DESCRIPTION}" Tag="{Binding ID}" GotFocus="GetModules"/>
</DataTemplate></Window.Resources>

但是它不起作用(GetModules 没有被调用)。我对 WPF 是新手,所以请指引我正确的方向来做这些事情。

4个回答

5
如果您想在TreeView中捕获SelectedItemChanged事件,则需要在父节点上设置事件处理程序,即:

XAML

<StackPanel>
    <TreeView SelectedItemChanged="OnTreeViewSelectedItemChanged">          
        <TreeViewItem Header="Desktop">
            <TreeViewItem Header="Computer" />
            <TreeViewItem Header="My Documents" />
            <TreeViewItem Header="c:\" />
        </TreeViewItem>
        <TreeViewItem Header="Recyle Bin" >
            <TreeViewItem Header="foo.txt" />
            <TreeViewItem Header="bar.txt" />
            <TreeViewItem Header="fizz.buzz" />
        </TreeViewItem>
        <TreeViewItem Header="Control Panel" >
            <TreeViewItem Header="Programs" />
            <TreeViewItem Header="Security" />
            <TreeViewItem Header="User Accounts" />
        </TreeViewItem>
    </TreeView>

    <TextBlock Margin="20" x:Name="MyTextBlock" />
</StackPanel>

代码后置:

private void OnTreeViewSelectedItemChanged( object sender, RoutedPropertyChangedEventArgs<object> e )
{
    MyTextBlock.Text = ( (TreeViewItem) ( (TreeView) sender ).SelectedItem ).Header.ToString();
}

3
您需要为TreeView的SelectedItemChanged事件添加事件处理程序。
<TreeView x:Name="myTreeView"
          SelectedItemChanged="myTreeView_SelectedItemChanged"
          ItemTemplate="{StaticResource PeerDetailTemplate} />

由于这是在选择更改后触发的,因此您可以使用TreeView的选定项目属性来访问树视图项:

private void myTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        TreeViewItem selectedItem = (TreeViewItem)myTreeView.SelectedItem;
        // do stuff
    }

1

选择和焦点是两个不同的概念。听起来你对选择感兴趣,在这种情况下,它是TreeView的一个属性。事件TreeView.SelectedItemChanged将通知您选择的更改,属性TreeView.SelectedItem将告诉您选择了什么。


是的,像之前的回答所说的那样做了。它有帮助。感谢大家的回答,但我会将第一个标记为答案。其他的我会点赞。 - 0x49D1
这是否意味着即使是深层嵌套在TreeView结构中的TreeViewItem也会显示在SelectedItem中? - 0x49D1
1
是的,无论TreeViewItem在TreeView中嵌套多深,SelectedItemChanged事件始终会捕获当前的SelectedItem(TreeViewItem)。 - Metro Smurf

0

绑定TreeViewItem的SelectedItemChanged事件有不同的方法:

方法1:直接附加事件

可以在Xaml中附加事件。

<TreeView x:Name="treeview1" HorizontalAlignment="Left" Height="243" Margin="30,211,0,0" VerticalAlignment="Top" Width="667" SelectedItemChanged="TreeView_SelectedItemChanged">
        <TreeViewItem Header="TreeViewItem"/>
</TreeView>
Private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{

}

或者在代码后面

myTreeview.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(TreeView_SelectedItemChanged);

private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{

}

方法二:使用扩展类

public class ExtendedTreeView : TreeView
{
    public ExtendedTreeView()
        : base()
    {
        this.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(TreeView_SelectedItemChanged);
    }

    void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (SelectedItem != null)
        {
            SetValue(SelectedItem_Property, SelectedItem);
        }
    }

    public object SelectedItem_
    {
        get { return (object)GetValue(SelectedItem_Property); }
        set { SetValue(SelectedItem_Property, value); }
    }
    public static readonly DependencyProperty SelectedItem_Property = DependencyProperty.Register("SelectedItem_", typeof(object), typeof(ExtendedTreeView), new UIPropertyMetadata(null));
}

接下来,使用新的自定义类对象创建Treeview。

ExtendedTreeView  myTreeview = new ExtendedTreeView();

行为的使用方法3

public class BindableSelectedItemBehavior : Behavior<TreeView>
{
    #region SelectedItem Property

    public object SelectedItem
    {
        get { return (object)GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register("SelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged));

    private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var item = e.NewValue as TreeViewItem;
        if (item != null)
        {
            item.SetValue(TreeViewItem.IsSelectedProperty, true);
        }
    }

    #endregion

    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        if (this.AssociatedObject != null)
        {
            this.AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
        }
    }

接下来只需将 Treeview 附加到 Xaml 文件的行为即可。

<TreeView>
    <e:Interaction.Behaviors>
        <behaviours:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
    </e:Interaction.Behaviors>
</TreeView>

或者在代码后台

BindableSelectedItemBehavior selectedItemBehavior = new BindableSelectedItemBehavior();
System.Windows.Interactivity.Interaction.GetBehaviors(treeview1).Add(selectedItemBehavior);

诚挚地

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接