[c#] Data binding to SelectedItem in a WPF Treeview

I suggest an addition to the behavior provided by Steve Greatrex. His behavior doesn't reflects changes from the source because it may not be a collection of TreeViewItems. So it is a matter of finding the TreeViewItem in the tree which datacontext is the selectedValue from the source. The TreeView has a protected property called "ItemsHost", which holds the TreeViewItem collection. We can get it through reflection and walk the tree searching for the selected item.

private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var behavior = sender as BindableSelectedItemBehaviour;

        if (behavior == null) return;

        var tree = behavior.AssociatedObject;

        if (tree == null) return;

        if (e.NewValue == null) 
            foreach (var item in tree.Items.OfType<TreeViewItem>())
                item.SetValue(TreeViewItem.IsSelectedProperty, false);

        var treeViewItem = e.NewValue as TreeViewItem; 
        if (treeViewItem != null)
        {
            treeViewItem.SetValue(TreeViewItem.IsSelectedProperty, true);
        }
        else
        {
            var itemsHostProperty = tree.GetType().GetProperty("ItemsHost", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            if (itemsHostProperty == null) return;

            var itemsHost = itemsHostProperty.GetValue(tree, null) as Panel;

            if (itemsHost == null) return;

            foreach (var item in itemsHost.Children.OfType<TreeViewItem>())
                if (WalkTreeViewItem(item, e.NewValue)) break;
        }
    }

    public static bool WalkTreeViewItem(TreeViewItem treeViewItem, object selectedValue) {
        if (treeViewItem.DataContext == selectedValue)
        {
            treeViewItem.SetValue(TreeViewItem.IsSelectedProperty, true);
            treeViewItem.Focus();
            return true;
        }

        foreach (var item in treeViewItem.Items.OfType<TreeViewItem>())
            if (WalkTreeViewItem(item, selectedValue)) return true;

        return false;
    }

This way the behavior works for two-way bindings. Alternatively, it is possible to move the ItemsHost acquisition to the Behavior's OnAttached method, saving the overhead of using reflection every time the binding updates.

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to wpf

Error: the entity type requires a primary key Reportviewer tool missing in visual studio 2017 RC Pass command parameter to method in ViewModel in WPF? Calling async method on button click Setting DataContext in XAML in WPF How to resolve this System.IO.FileNotFoundException System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll? Binding an Image in WPF MVVM How to bind DataTable to Datagrid Setting cursor at the end of any text of a textbox

Examples related to mvvm

Vue.js—Difference between v-model and v-bind Pass command parameter to method in ViewModel in WPF? [Vue warn]: Cannot find element Binding an Image in WPF MVVM Binding ComboBox SelectedItem using MVVM What is difference between MVC, MVP & MVVM design pattern in terms of coding c# How to make all controls resize accordingly proportionally when window is maximized? Add directives from directive in AngularJS Wpf DataGrid Add new row Close Window from ViewModel

Examples related to treeview

Is there any publicly accessible JSON data source to test with real world data? How to select a node of treeview programmatically in c#? Data binding to SelectedItem in a WPF Treeview adding child nodes in treeview

Examples related to selecteditem

Getting selected value of a combobox Difference between SelectedItem, SelectedValue and SelectedValuePath android listview get selected item Get selected row item in DataGrid WPF WPF binding to Listbox selectedItem WPF Datagrid set selected row Data binding to SelectedItem in a WPF Treeview