How can I bind WPF TreeView data to lazy and asynchronous?

I am learning how to use data binding in WPF for TreeView. I am procedurally creating an object Binding, setting properties Source, Pathand Converterto point to my own classes. I can even get to the installation IsAsync, and I can see the GUI update asynchronously when I examine the tree. So far so good!

My problem is that WPF eagerly evaluates parts of the tree before expanding them in the GUI. If left long enough, this will lead to an evaluation of the whole tree (well, in fact, in this example, my tree is infinite, but you get the idea). I would like the tree to be evaluated only on demand when the user expands the nodes. Is this possible using existing asynchronous data binding material in WPF?

As a side, I did not understand how it ObjectDataProviderrelates to this task.


My XAML code contains only one TreeView object, and my C # code:

public partial class Window1 : Window
{
    public Window1() {
        InitializeComponent();

        treeView.Items.Add( CreateItem(2) );
    }

    static TreeViewItem CreateItem(int number)
    {
        TreeViewItem item = new TreeViewItem();
        item.Header = number;

        Binding b = new Binding();
        b.Converter = new MyConverter();
        b.Source = new MyDataProvider(number);
        b.Path = new PropertyPath("Value");
        b.IsAsync = true;
        item.SetBinding(TreeView.ItemsSourceProperty, b);

        return item;
    }

    class MyDataProvider
    {
        readonly int m_value;

        public MyDataProvider(int value) {
            m_value = value;
        }

        public int[] Value {
            get {
                // Sleep to mimick a costly operation that should not hang the UI
                System.Threading.Thread.Sleep(2000);
                System.Diagnostics.Debug.Write(string.Format("Evaluated for {0}\n", m_value));
                return new int[] {
                    m_value * 2, 
                    m_value + 1,
                };
            }
        }
    }

    class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            // Convert the double to an int.
            int[] values = (int[])value;
            IList<TreeViewItem> result = new List<TreeViewItem>();
            foreach (int i in values) {
                result.Add(CreateItem(i));
            }
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
            throw new InvalidOperationException("Not implemented.");
        }
    }    
}

. , WPF . (, , " WPF" ).

+3
1

( , )

  • , ( int int)
  • ViewModel, IsExpanded
  • IsExpanded TreeViewItem IsExpanded (xaml)
  • IsExpanded "", , "". "" PropertyChanged.

MVVM, .

+3

Source: https://habr.com/ru/post/1748002/


All Articles