0

I have a WPF hierarchical TreeView with a TextBlock to show my list. I want to pass the selected string value as a parameter to my ViewModel. I am using MVVM.

Here is the TreeView:

 <TreeView ItemsSource="{Binding countryReportsHierarchy}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectedItemChanged">
                            <i:InvokeCommandAction Command="{Binding ArticleCategoryTitleSelectionChangedCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <TreeView.Resources>
                        <HierarchicalDataTemplate  DataType="{x:Type t:CountryReportsHierarchy}"
                                ItemsSource="{Binding ArticleCategoriesHierarchyCollection}">
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                        <HierarchicalDataTemplate  DataType="{x:Type t:ArticleCategoriesHierarchy}"
                                ItemsSource="{Binding ArticleTypesHierarchyCollection}">
                            <TextBlock Text="{Binding Name}"/>
                        </HierarchicalDataTemplate>
                        <DataTemplate  DataType="{x:Type t:ArticleTypesHierarchy}">
                            <TextBlock Text="{Binding ElementName= Name, Path=SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
                            </TextBlock>
                        </DataTemplate>
                    </TreeView.Resources>
                </TreeView>

And the part I am trying to get selected value from the TextBlock from:

<TextBlock Text="{Binding Name}"/>                         

This binds as expected, obviously without selected value. Is there any way to pass the selected value of a TextBlock? I've tried the following but the binding fails:

<TextBlock Text="{Binding ElementName= Name, Path=SelectedItem" />
Muds
  • 4,006
  • 5
  • 31
  • 53
Hardgraf
  • 2,566
  • 4
  • 44
  • 77
  • doesn't sound right, show us more code – Muds Mar 13 '15 at 12:20
  • You want the entire TreeView code? – Hardgraf Mar 13 '15 at 12:21
  • just 2 data templates , the first one u showed here is closed in first line itself – Muds Mar 13 '15 at 12:21
  • mvvm or code behing ? – Muds Mar 13 '15 at 12:24
  • MVVM, the DataContext is passed into the constructor – Hardgraf Mar 13 '15 at 12:25
  • 1
    There is no SelectedItem in textblock as its not itemscontrol – Muds Mar 13 '15 at 12:25
  • 1
    well you would need a behaviour, have a look [Here][1] for sample. [1]: http://stackoverflow.com/questions/11065995/binding-selecteditem-in-a-hierarchicaldatatemplate-applied-wpf-treeview – Muds Mar 13 '15 at 12:27
  • Yes, I have tried to extend the TreeVIew class to include SelectedItem functionality. I have got that to work however the issue is that the selected value of the treeView itself is the object it is bound to (countryReportsHierarchy) not the string value of the node selected. – Hardgraf Mar 13 '15 at 12:44

1 Answers1

0

Here's how I solved this. I extended the TreeView class to include SelectedItem functionality:

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

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

Here are my hierarchy classes for the TreeView:

   public class CountryReportsHierarchy
{
    IIsesServiceChannel IsesService;
    public ObservableCollection<tbArticleCategory> ArticleCategoryList;

    public ObservableCollection<ArticleCategoriesHierarchy> ArticleCategoriesHierarchyCollection { get; set; }
    public string Name { get; set; }

    public CountryReportsHierarchy(IIsesServiceChannel isesService)
    {
        this.IsesService = isesService;          
        ArticleCategoryList = new ObservableCollection<tbArticleCategory>(IsesService.GetArticleCatagoryTitles());           

        ArticleCategoriesHierarchyCollection = new ObservableCollection<ArticleCategoriesHierarchy>();

        foreach (var a in ArticleCategoryList)
        {
            ArticleCategoriesHierarchyCollection.Add(new ArticleCategoriesHierarchy(IsesService, a.Category) { Name = a.CategoryTitle });
        }
    } 
}

public class ArticleCategoriesHierarchy
{
    IIsesServiceChannel IsesService;

    public ObservableCollection<tbArticleType> ArticleTypeList;
    public ObservableCollection<ArticleTypesHierarchy> ArticleTypesHierarchyCollection { get; set; }
    public string Name { get; set; }
    public ArticleCategoriesHierarchy(IIsesServiceChannel isesService, string articleCategoryType)
    {
        this.IsesService = isesService;

        ArticleTypeList = new ObservableCollection<tbArticleType>(IsesService.GetArticleCategoryTypes(articleCategoryType));

        ArticleTypesHierarchyCollection = new ObservableCollection<ArticleTypesHierarchy>();

        foreach (var a in ArticleTypeList)
        {
            ArticleTypesHierarchyCollection.Add(new ArticleTypesHierarchy() { Name = a.ArticleTitle });
        }
    }
}

public class ArticleTypesHierarchy
{
    public string Name { get; set; }
}

I then bound my new ExtendedTreeView Selected item to a ArticleTypesHierarchy property in my ViewModel:

 <cntrls:ExtendedTreeView ItemsSource="{Binding countryReportsHierarchy}" SelectedItem_="{Binding SelectedArticleTitle, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >                       
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectedItemChanged">
                            <i:InvokeCommandAction Command="{Binding ArticleCategoryTitleSelectionChangedCommand}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <TreeView.Resources>
                        <HierarchicalDataTemplate  DataType="{x:Type t:CountryReportsHierarchy}"
                                ItemsSource="{Binding ArticleCategoriesHierarchyCollection}">
                            <TextBlock Text="{Binding Name}" />
                        </HierarchicalDataTemplate>
                        <HierarchicalDataTemplate  DataType="{x:Type t:ArticleCategoriesHierarchy}"
                                ItemsSource="{Binding ArticleTypesHierarchyCollection}">
                            <TextBlock Text="{Binding Name}"/>
                        </HierarchicalDataTemplate>
                        <DataTemplate  DataType="{x:Type t:ArticleTypesHierarchy}">                              
                            <TextBlock Text="{Binding Name}" />                  
                        </DataTemplate>
                    </TreeView.Resources>
                </cntrls:ExtendedTreeView>

ViewModel passing in the ArticleTypesHierarchy.Name (My selected TreeView string) argument:

    public ReportViewModel()
    {
        countryReportsHierarchy = new ObservableCollection<CountryReportsHierarchy>(new[]{
        new CountryReportsHierarchy(IsesService){Name = CountryReportTitle}});
    }


  private ArticleTypesHierarchy _SelectedArticleTitle;
    public ArticleTypesHierarchy SelectedArticleTitle
    {
        get { return _SelectedArticleTitle; }
        set
        {
            _SelectedArticleTitle = value;
            OnPropertyChanged("SelectedArticleTitle");
        }
    }      

    private void ArticleCategoryTitleSelectionChangedCommandAction()
    {
        GetData(SelectedArticleTitle.Name)
    }
Hardgraf
  • 2,566
  • 4
  • 44
  • 77