Rudi
Rudi

Reputation: 936

Selected TreeViewItem is null

I wanted to create a ContextMenu for my TreeView. TreeView XAML:

<helper:ExtendedTreeView Grid.Row="5" ItemsSource="{Binding OCFrage, Mode=TwoWay}" SelectedItem_="{Binding SelectedItem, Mode=TwoWay}" SelectedItemChanged="treeView1_SelectedItemChanged" x:Name="treeView1" Height="205" Width="215">
    <helper:ExtendedTreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type model:T_Frage}" ItemsSource="{Binding Wertung, Mode=TwoWay}">
            <TextBlock Text="{Binding Text}"/>
        </HierarchicalDataTemplate>
    </helper:ExtendedTreeView.Resources>
</helper:ExtendedTreeView>

while helper:ExtendedTreeView is this class:

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

    void self(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));
}

I'm using this for binding the SelectedItem and use it in my ViewModel.

My TreeView has "Headers" which are of type T_Frage and their nodes are of type T_Wertung, so it would be

I wanted to create a ContextMenu for the Headers. So if the user clicks on the TreeViewItem of type T_Frage, a ContextMenu should popup. I've followed this guide http://canhandre.wordpress.com/2012/01/14/wpf-treeview-with-contextmenu/ and I'm doing it currently in the CodeBehind just to test it. The problem is that when this code is being executed: TreeViewItem selectedItem = treeView1.SelectedItem as TreeViewItem; treeView1.SelectedItem is of type T_Frage and has it's values, but when I assign to selectedItem, selectedItem is still null... Why?

Edit: Removing the ItemsSource and creating normal TreeViewItems in XAML

  <TreeViewItem Header="Edit" Name="Edit">
       <TreeViewItem Header="Text"/>
       <TreeViewItem Header="Image"/>
       <TreeViewItem Header="Table"/>
  </TreeViewItem>

will assign the value here TreeViewItem selectedItem = treeView1.SelectedItem as TreeViewItem;. This means I can't assign a Item in my TreeView, which is of type T_Frage, to a variable of type TreeViewItem. How am I supposed to create a ContextMenu for a Item in my TreeView which is not of type TreeViewItem? Like you can see above, assigning the type of T_Frage to TreeViewItem will result as null.

Upvotes: 0

Views: 1512

Answers (1)

Rudi
Rudi

Reputation: 936

I know that it's MVVM now and not CodeBehind, but I just wanted to test it in CodeBehind first and then do it all in MVVM, because I thought doing it right away in MVVM would be harder... Anyway, this is what I wanted:

<helper:ExtendedTreeView Grid.Row="5" ItemsSource="{Binding OCFrage, Mode=TwoWay}" SelectedItem_="{Binding SelectedItem, Mode=TwoWay}" SelectedItemChanged="treeView1_SelectedItemChanged" x:Name="treeView1" Height="205" Width="215">
    <TreeView.ContextMenu>
        <ContextMenu ItemsSource="{Binding OCContext}"/>
    </TreeView.ContextMenu)
    <helper:ExtendedTreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type model:T_Frage}" ItemsSource="{Binding Wertung, Mode=TwoWay}">
            <TextBlock Text="{Binding Text}"/>
        </HierarchicalDataTemplate>
    </helper:ExtendedTreeView.Resources>
</helper:ExtendedTreeView>

ViewModel:

private object _selecteditem;
public object SelectedItem
{
    get { return _selecteditem; }
    set
    {
        OCContext = new ObservableCollection<T_Wertung>();
        if (value is T_Frage)
        {
            T_Frage selected = (T_Frage)value;
    //do something with selected
    OCContext.Add(new T_Wertung(1,"Test",100));
            }
        }
        RaisePropertyChanged(() => SelectedItem);
    }
}

private ObservableCollection<T_Wertung> _occontext;
public ObservableCollection<T_Wertung> OCContext
{
    get
    {
        if (_occontext == null)
            _occontext = new ObservableCollection<T_Wertung>();
        return _occontext;
    }
    set
    {
        _occontext = value;
        RaisePropertyChanged(() => OCContext);
    }
}

Since I'm binding to the SelectedItem of the TreeView, I can ask if the SelectedItem is of type T_Frage. If it's true, I'll create a new variable of type T_Frage and set it's context to the value of the SelectedItem. Now I can do something with this item and then add an item to the List of the ContextMenu named OCContext. When I right click the item, the ContextMenu is being popped up and it shows the items of OCContext.

Upvotes: 0

Related Questions