【问题标题】:WPF Binding listview checkboxes to display as favoritesWPF 绑定列表视图复选框以显示为收藏夹
【发布时间】:2015-10-22 16:47:31
【问题描述】:

在我当前的 WPF MVVM 设置中,我有一个从文件/文件夹目录填充的树视图。包括子文件夹和文件。但是我想实现一个简单的“收藏夹”功能。这意味着我可以单击树视图中每个文件的复选框,然后当我单击主“UI 中的复选框”时,它将过滤列表以仅显示“收藏夹”。

这似乎是一个普遍的问题,但我该怎么做呢?组织和绑定 UI?

我已将解决方案“visual studio 2013”​​发布到我的保管箱中,供任何愿意帮助我的人使用。

Download Dropbox Files

我的猜测是添加另一个 ObservableCollection,它将检查的节点存储为收藏夹,以及原始树视图节点。因此,当用户启用主复选框时,它会将收藏夹列表加载到 ui,当取消选中时,它会重新加载树视图。

// collection of nodes which you see in the image below on the left    
public ObservableCollection<INode> DisplayNodes //nodes displayed in UI
public ObservableCollection<INode> FavoriteNodes //nodes marked as favorites
public ObservableCollection<INode> StructureNodes //system node structure

下面的伪函数

public void PopulateUI()
{
    DisplayNodes.Clear();

    if (showFavorites.isChecked)
    {
        DisplayNodes = FavoriteNodes;//nodes displayed in UI
    }else{
        DisplayNodes = StructureNodes;
    }
}

【问题讨论】:

    标签: c# wpf mvvm treeview


    【解决方案1】:

    我无法从工作中下载您的项目,但我可以为此提供一些一般性指导。

    这可以通过修改您的 INode 实现(FileNode、DirectoryNode 等)以包含 IsFavorite bool 属性来完成。

    在您的视图模型中,添加一个名为FavoritesEnabled 的属性。在该属性的设置器中,您可以将 RootNodes 可观察集合替换为过滤后的 INode 集合。

    private bool favoritesEnabled;
    public bool FavoritesEnabled
    {
        get
        {
            return this.favoritesEnabled;
        }
        set
        {
            this.favoritesEnabled = value;
            this.RootNodes = value == true
                ? new ObservableCollection(this.FilterFavorites)
                : new ObservableCollection(this.CreateRootNodes);
        }
    }
    
    private IEnumerable<INode> FilterFavorites()
    {
        List<INode> nodes = new List<INode>();
        foreach(DirectoryNode directory in this.RootNodes.OfType<DirectoryNode>())
        {
            nodes.AddRange(this.filterFavorites(nodes, directory.Children.OfType<DirectoryNode>());
            nodes.AddRange(this.RootNodes.OfType<FileNode>().Where(item => item.IsFavorite);
        }
    }
    
    private List<INode> FilterFavorites(List<INode> filteredResults, IEnumerable<DirectoryInfo> directories)
    {
        // Recursively look up all favorites.
        foreach(DirectoryNode directory in directories)
        {
            filteredResults.AddRange(FilterFavorites(filteredResults, directory));
        }
            nodes.AddRange(this.RootNodes.OfType<FileNode>().Where(item => item.IsFavorite);
    
        return filteredResults;
    }
    

    然后您只需更新树视图的数据模板,以便每个项目的复选框数据绑定到 INode 实现上的 IsFavorite 属性。

    上面的递归代码或多或少是伪代码,因为我无法在不关闭您的项目的情况下对其进行测试。它应该可以帮助您朝着正确的方向开始。使用这种方法,您可以继续只维护一个集合。您需要将 RootNodes 属性的创建移出构造函数并移到可重用的方法中。这样,当您在视图模型中切换收藏夹属性时,您的 RootNodes 集合会生成收藏夹集合或“全部”集合。

    如果你不能让它工作,我今晚可以从家里拿你的东西并举一个合适的例子。

    【讨论】:

    • 好的,您的指导肯定有助于解决问题,正是我想要的。
    • 我实现了第一步,即视图模型的“favoritesEnabled”部分。相当简单。现在进入实际填充数据的下一步。
    • 您应该能够在您的数据模板中添加一个复选框,并将其数据绑定到模型上的 IsFavorite 属性。这将让您切换最喜欢的文件/文件夹并将该数据存储在您现有的可以过滤的节点集合中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 2014-08-23
    • 2014-01-24
    • 2014-12-22
    • 2013-12-17
    相关资源
    最近更新 更多