0x49D1
0x49D1

Reputation: 8704

Create Event Handler for TreeViewItem in WPF

Im adding items to TreeView control via ItemsSource property and ItemTemplate property to set the template for TreeViewItem. How can i add an event handler to handle selection change event on TreeViewItems?
For now my ItemTemplate looks like this:

<Window.Resources><DataTemplate x:Key="PeerDetailTemplate">
        <TextBlock Text="{Binding DESCRIPTION}" Tag="{Binding ID}" GotFocus="GetModules"/>
</DataTemplate></Window.Resources>

But it doesnt work (GetModules is not called). Im new to WPF, so show me the right direction to do such things, please.

Upvotes: 5

Views: 17109

Answers (4)

LPGTE SOFTS
LPGTE SOFTS

Reputation: 175

There are different ways to Bind of the SelectedItemChanged event of TreeviewItem:

Method 1: Direct Attaching Event

The attachment of the event can be done in 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)
{

}

Or on code Behind

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

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

}

Method 2 Usage of Extended Class

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));
}

Next just create the Treeview with the new custom class object.

ExtendedTreeView  myTreeview = new ExtendedTreeView();

Method 3 Usage of Behavior

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;
        }
    }

Next just attach the Treeview to the Behavior On Xaml file

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

Or on Code Behind

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

Cordially

Upvotes: 0

Curt Nichols
Curt Nichols

Reputation: 2767

Selection and Selection and focus are two different concepts. It sounds like you're interested in selection, which in this case is a property of the TreeView. Event TreeView.SelectedItemChanged will notify you of selection changes and property TreeView.SelectedItem will tell you what is selected.

Upvotes: 1

Metro Smurf
Metro Smurf

Reputation: 38335

If you want to capture the SelectedItemChanged event in a TreeView, then you need to set the event handler on the parent node, i.e.,

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>

Code Behind:

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

Upvotes: 4

Robin
Robin

Reputation: 1022

You'll need to add an event handler to the TreeView's SelectedItemChanged event.

<TreeView x:Name="myTreeView"
          SelectedItemChanged="myTreeView_SelectedItemChanged"
          ItemTemplate="{StaticResource PeerDetailTemplate} />

Since this is fired after the selection is changed, you can use the TreeView's selected item property to access the tree view item:

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

Upvotes: 3

Related Questions