首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何判断TreeViewItem是在扩容中还是已经扩容

如何判断TreeViewItem是在扩容中还是已经扩容
EN

Stack Overflow用户
提问于 2011-02-01 20:51:18
回答 1查看 835关注 0票数 0

我有一个问题。我的树形视图中有一些项目位于层次结构的顶端。当我单击某个项目将其展开时,可能需要5秒钟才能加载选定节点中的所有项目。如何显示“请使用wait...expanding节点..”是否在此过程中发送消息?如何确定项是否仍在展开,还是所有嵌套项现在都已加载并显示?

我已经在这里问了非常类似的问题,Show "Please wait.." message when expanding TreeView in WPF,我甚至将答案标记为已接受,但是,我现在的解决方案并不令人满意,因为“请稍等..”对话框闪烁(它的显示和关闭次数与嵌套项的数量相同)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-01 23:47:17

正如我在评论你的帖子中提到的,我们可能存在两个需要解决的问题。

  1. 你有很多项目,所以当你展开node - wpf时,它会开始生成项目容器并将它们放入可视化树中。这可能会很烦人。
  2. 另一方面,我认为下一个场景-用户展开节点项,并向数据库/远程服务器发送请求,这可能会在一段时间内执行。

WPF不提供BeforeExpand事件,所以你应该使用视图数据,属性更改通知,数据绑定和可观察的集合。我将在简单的应用程序中说明这一点。

整个方法可以大致描述为:

  • 将视图数据的IsExpanded属性绑定到TreeViewItem
  • Listen的IsExpanded属性IsExpanded属性更改通知在某处(可能在模型中)
  • 设置IsLoading属性(在我的sapmle中是在视图数据中声明的)
  • 启动一些填充内部项的任务
  • 重置IsLoading属性

<>H117Put DataTrigger in xaml,这对IsLoading属性起反应。

我已经使用可观察的属性IsExpanded、IsLoaded、子项的可观察集合和将要显示的名称设计了我的树状项目ViewData类:

代码语言:javascript
复制
public class TreeItem : ObservableObject
{
    public TreeItem (string name)
    {
        this.Name = name;
    }

    public string Name 
    {
        get; 
        private set; 
    }

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

    private bool _isLoading;
    public bool IsLoading
    {
        get
        {
            return this._isLoading;
        }
        set
        {
            if (this._isLoading != value)
            {
                this._isLoading = value;
                this.OnPropertyChanged("IsLoading");
            }
        }
    }


    private ObservableCollection<TreeItem> _innerItems = new ObservableCollection<TreeItem>();
    public IEnumerable<TreeItem> InnerItems
    {
        get
        {
            return this._innerItems;
        }

    }

    public void LoadInnerItems()
    {
        this.IsLoading = true;
        var sc= SynchronizationContext.Current;
        new Thread(new ThreadStart(() => 
            {
                Thread.Sleep(5000);
                sc.Send(o =>
                    {
                        this._innerItems.Add(new TreeItem("1223"));
                        this._innerItems.Add(new TreeItem("2345"));
                        this._innerItems.Add(new TreeItem("666678"));
                        this.IsLoading = false;
                    }, null);
            }))
            .Start();
    }
}

下一步是开发表示模型。正如您所看到的,我们的模型侦听IsExpanded PropertyChanged事件,当它等于true时,启动LoadingInnerItems:

代码语言:javascript
复制
public class SampleModel : ObservableObject
{
    public SampleModel()
    {
        this._items.Add(new TreeItem("AAA"));
        this._items.Add(new TreeItem("BBB"));
        this._items.Add(new TreeItem("CCC"));

        foreach (var i in this._items)
        {
            i.PropertyChanged += new PropertyChangedEventHandler(Item_PropertyChanged);
        }

    }

    void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "IsExpanded")
        {
            var item = (TreeItem)sender;
            if(item.IsExpanded)
            {
                item.LoadInnerItems();
            }
        }
    }

    private ObservableCollection<TreeItem> _items = new ObservableCollection<TreeItem>();
    public IEnumerable<TreeItem> Items
    {
        get
        {
            return this._items;
        }
    }
}

用于TreeView的XAML。当我们加载内部项目时-我们的树的前景变成了红色:

代码语言:javascript
复制
<TreeView ItemsSource="{Binding Items}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding InnerItems}">
            <TextBlock Text="{Binding Name}"/>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded"
                    Value="{Binding IsExpanded, Mode=TwoWay}"/>
            <Setter Property="Foreground"
                    Value="Aqua"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsLoading}"
                             Value="True">
                    <Setter Property="Foreground" 
                            Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

别忘了在后台代码中将model设置为视图的datacontext:

代码语言:javascript
复制
    public MainWindow()
    {
        InitializeComponent();

        this.Model = new SampleModel();
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4862784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档