Search code examples
c#wpflistviewtreeviewdatatemplate

How to trigger the Listview behind when Treeview is click?


I have treeview inside my Listview like below

 <ListView  x:Name="LvItemDisplay" ItemsSource="{Binding itemDisplayList}" SelectionChanged="LvItemDisplay_SelectionChanged">

      <ListView.ItemTemplate>

            <DataTemplate x:Name="dtItemDisplay">

                    <TreeView x:Name="TvItemDisplay" Background="Transparent" ItemsSource="{Binding itemDisplayList}" MouseDown="TvItemDisplay_MouseDown_1" SelectedItemChanged="TvItemDisplay_SelectedItemChanged"  >
                        .
                        .
                        .

I have click event for both treeview and listview. both of it when click it will popup a dialog box that user can edit that will binding from them.

the problem is, whenever user want to click the treeview user need to click on the listview first to get the SelectedItem. if not nothing will happen since the SelectedItem will be null.

this is the code behind for listview

private void LvItemDisplay_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

                ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
                TreeView treeView = null;
                DialogHost dialogHost = null;

                if (LvItemDisplay.SelectedIndex != -1)
                {
                    if (listViewItem != null)
                    {
                        //get the listViewItem's template parent
                        ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);

                        //get the DataTemplate that treeview in.
                        DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;

                        if (dataTemplate != null && templateParent != null)
                        {

                            treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
                            if (treeView != null)
                            {
                                dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
                                dialogHost.IsOpen = true;
                            }

                        }

                    }
                }
        }

and for treeview

  private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));
        TreeView treeView = null;
        DialogHost dialogHost = null;

            if (listViewItem != null)
            {
               //get the listViewItem's template parent
                ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(listViewItem);

                //get the DataTemplate that treeview in.
                DataTemplate dataTemplate = LvItemDisplay.ItemTemplate;

                if (dataTemplate != null && templateParent != null)
                {
                    treeView = dataTemplate.FindName("TvItemDisplay", templateParent) as TreeView;
                }

                if (treeView != null)
                {
                    dialogHost = dataTemplate.FindName("dialogBoxEditQty", templateParent) as DialogHost;
                    dialogHost.IsOpen = true;
                }               
        }          
    }

save for dialogHost

private void ButtonSave_Click(object sender, RoutedEventArgs e)
    {

        try
        {

            // get the current selected item
            ListViewItem listViewItem = (ListViewItem)(LvItemDisplay.ItemContainerGenerator.ContainerFromItem(LvItemDisplay.SelectedItem));


            DialogHost dialogHost = null;
            if (listViewItem != null)
            {
            .
            .
            .

I want something like whenever user click on the treeview it will triggered the listview behind /click the listview as well. is it possible ?


Solution

  • You can manualy select the ListView Item

    TreeView Selection Changed

    private void TvItemDisplay_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
            {
                LvItemDisplay.SelectionChanged -= LvItemDisplay_SelectionChanged;
                ParentItemSelectionChange(sender, true);         
    
                // Your code
    
                ParentItemSelectionChange(sender, false);
                LvItemDisplay.SelectionChanged += LvItemDisplay_SelectionChanged;
    
            }
    

    Helper Methods

     private FrameworkElement ParentItemSelectionChange(object sender, bool selChange)
            {
                var frameworkElement = sender as FrameworkElement;
                if (frameworkElement != null)
                {
                    var item = FindParent<ListViewItem>(frameworkElement);
                    if (item != null)
                        item.IsSelected = selChange;
                }
                return frameworkElement;
            }
    
            public T FindParent<T>(DependencyObject child) where T : DependencyObject
            {
                DependencyObject parentObject = VisualTreeHelper.GetParent(child);
                if (parentObject == null) return null;
                T parent = parentObject as T;
                if (parent != null)
                    return parent;
                return FindParent<T>(parentObject);
            }