WPF依赖属性-需要在GUI上进行即时反射

WPF依赖属性-需要在GUI上进行即时反射,wpf,data-binding,treeview,Wpf,Data Binding,Treeview,简单介绍一下依赖属性。我有一个treeview,我正在懒洋洋地加载,绑定一个MVVM模型。在绑定属性IsExpanded上,我有以下代码 public bool IsExpanded { get { return _isExpanded; } set { if (value != _isExpanded) {

简单介绍一下依赖属性。我有一个treeview,我正在懒洋洋地加载,绑定一个MVVM模型。在绑定属性IsExpanded上,我有以下代码

public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root
                if (_isExpanded && _parent != null)
                    if (!_parent.IsExpanded) _parent.IsExpanded = true;

                // Lazy load the child items, if necessary
                if (HasDummyChild)
                {
                    LoadChildren();
                }
            }
        }
当您单击节点上的展开图标时,将触发该命令,然后加载子节点,完成后,将显示展开的子节点

问题是这可能需要一点时间来加载,因此在加载时,我希望有一个孩子说“请稍候,加载…”之类的话,然后当LoadChildren()方法完成时,它会显示实际的孩子

默认情况下,我将向子列表添加一个虚拟节点,该节点具有此显示文本,然后调用LoadChildren并将该虚拟列表替换为实际列表,但问题是当您单击展开图标时,setter首先触发,这需要在调用GET data绑定以显示子列表之前完全完成

因此,虚拟项从未显示,它存在于子列表中,但在setter完成时,它已被替换,唯一显示的是完整列表,在打开它之前有一个暂停


是否有一种方法可以让您在单击图标时,它会首先用现有的虚拟子节点直观地展开节点,然后尝试获取并加载实际的子节点?

您需要在后台线程中执行加载。但是,将加载的子级添加到列表中需要在UI线程上执行

大概是这样的:

public void AddChildrenAsync()
{
    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.Run(() => LongOperationThatReturnsTheChildren(); )
                .ContinueWith(t =>
                              {
                                  Children.AddRange(t.Result);
                                  Children.RemoveAt(0);
                              }, uiScheduler);
}
在setter中:

// Lazy load the child items, if necessary
if (HasDummyChild)
{
    LoadChildrenAsync();
}

您需要在后台线程中执行加载。但是,将加载的子级添加到列表中需要在UI线程上执行

大概是这样的:

public void AddChildrenAsync()
{
    var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.Run(() => LongOperationThatReturnsTheChildren(); )
                .ContinueWith(t =>
                              {
                                  Children.AddRange(t.Result);
                                  Children.RemoveAt(0);
                              }, uiScheduler);
}
在setter中:

// Lazy load the child items, if necessary
if (HasDummyChild)
{
    LoadChildrenAsync();
}

好的,非常感谢。因此,无法将GUI线程上下文切换到getter或强制从集合中执行绑定get更新?@user1122909:否。只有一个UI线程。在代码中,它忙于设置
IsExpanded
属性。只有在属性设置程序返回后,UI线程才能对同时发生的任何事情做出反应。好的,非常感谢。因此,无法将GUI线程上下文切换到getter或强制从集合中执行绑定get更新?@user1122909:否。只有一个UI线程。在代码中,它忙于设置
IsExpanded
属性。只有在属性设置程序返回后,UI线程才能对同时发生的任何事情做出反应。