我正在学习如何在 WPF 中为 TreeView
使用数据绑定(bind)。我正在程序上创建 Binding
对象,设置 Source
、Path
和 Converter
属性指向我自己的类.我什至可以设置 IsAsync
,当我探索树时,我可以看到 GUI 异步更新。到目前为止一切顺利!
我的问题是 WPF 在 GUI 中扩展之前急切地评估树的部分。如果留下足够长的时间,这将导致整个树被评估(实际上在这个例子中我的树是无限的,但你明白了)。 我希望仅在用户扩展节点时按需评估树。使用 WPF 中现有的异步数据绑定(bind)是否可行?
顺便说一句,我还没有弄清楚 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 事件处理程序并在事件处理程序被触发时直接添加项目来设法对树节点进行惰性计算。我正试图摆脱它并改用数据绑定(bind)(我理解这更符合“WPF 方式”的精神)。
最佳答案
通用解决方案(因为我不确定您的代码是否不是模拟的)
- 创建包含父项和子项的模型(在本例中它是一个 int 和一个 int 列表)
- 创建一个 ViewModel,除了 Model 的属性外,还具有 IsExpanded 属性
- 将您的 IsExpanded 属性绑定(bind)到 View (xaml) 中 TreeViewItem 的 IsExpanded 属性
- 在 IsExpanded 属性的 setter 中,使用 Dispatcher 填写您的 Children 列表,优先级为 Background。每次将项目添加到您的子列表中都应触发 PropertyChanged 事件。
查看 MVVM design pattern ,如果你不熟悉。这是一个good video by Jason
关于wpf - 如何使 WPF TreeView 数据绑定(bind)惰性和异步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2951015/