Я учусь использовать привязку данных в WPF для TreeView
. Я процедурно создаю объект Binding
, задаю свойства Source
, Path
и Converter
, чтобы они указывали на мои собственные классы. Я могу даже пойти до установки IsAsync
, и я вижу асинхронное обновление графического интерфейса при изучении дерева. Пока все хорошо!
Моя проблема в том, что WPF охотно оценивает части дерева, прежде чем они будут развернуты в графическом интерфейсе. Если оставить его достаточно долго, это приведет к оценке всего дерева (ну, на самом деле, в этом примере мое дерево бесконечно, но вы поняли идею). Я бы хотел, чтобы дерево оценивалось только по требованию, когда пользователь расширяет узлы. Возможно ли это с помощью существующего асинхронного связывания данных в WPF?
Помимо этого, я не выяснил, как ObjectDataProvider
относится к этой задаче.
Мой код XAML содержит только один объект TreeView, а мой код C #:
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»).