首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用LINQ过滤ObservableCollection of DirectoryInfo

用LINQ过滤ObservableCollection of DirectoryInfo
EN

Stack Overflow用户
提问于 2022-05-18 12:52:32
回答 2查看 73关注 0票数 2

我使用MVVM来填充一个TreeView和它的所有子目录和文件。

然后,我想用LINQ .where()在treeview中搜索,但我只搜索顶部的目录,而不是文件。

我正在使用递归方法创建treeview/DirectoryInfo:

代码语言:javascript
复制
  public class ItemProvider
    {
        public ObservableCollection<Item> GetItems(string path)
        {
            var items = new ObservableCollection<Item>();

            if (System.IO.Directory.Exists(path))
            {
                

                var dirInfo = new DirectoryInfo(path);

                foreach (var directory in dirInfo.EnumerateDirectories())
                {
                    var item = new DirectoryItem
                    {
                        Name = directory.Name,
                        Path = directory.FullName,
                        Items = GetItems(directory.FullName)
                    };

                    items.Add(item);
                }

                foreach (var file in dirInfo.EnumerateFiles())
                {
                    InteropBitmap thumbImg = ShellFile.FromFilePath(file.FullName).Thumbnail.BitmapSource as InteropBitmap;
                    thumbImg.Freeze();

                    var item = new FamilyItem
                    {
                        Name = file.Name,
                        Path = file.FullName,
                        FamImage = thumbImg
                    };

                    if (item.Name.Contains(".rfa"))
                    {

                    items.Add(item);

                    }

                }

                return items;
            }
            else
            {

                return items;
            }
        }

DirectoryItem和FamilyItem都继承了一个名为Item的模型:

项目模型:

代码语言:javascript
复制
public class Item
    {
        public string Name { get; set; }
        public string Path { get; set; }
        public InteropBitmap FamImage { get; set; }
    }

DirectoryItem模型:

代码语言:javascript
复制
public class DirectoryItem : Item

    {
        public ObservableCollection<Item> Items { get; set; }
    
        public DirectoryItem()
        {
        Items = new ObservableCollection<Item>();
        }
    }

FamilyItem:

代码语言:javascript
复制
 public class FamilyItem : Item
    {

    }

,我正在用:过滤集合

代码语言:javascript
复制
Items = new ObservableCollection<Item>(ItemsCache.Where(x => x.Name.ToLower().Contains(SearchText.ToLower())));

我只得到匹配的顶级目录--我想得到所有匹配的“结束”文件--我该怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-18 14:36:12

您可以通过递归版本覆盖.Where(..)

代码语言:javascript
复制
   public static class ExtenstioMethods
   {
      public static IEnumerable<Item> Where<Item>(this IEnumerable<Item> source, Func<Item, bool> predicate)
      {
         var result = new List<Item>();
         foreach (var item in source)
         {
            if ((item is FamilyItem) && predicate(item))
            {
               result.Add(item);
            }
            else if (item is DirectoryItem)
            {
               var newSourc = ((item as DirectoryItem).Items) as IEnumerable<Item>;
               result = result.Union(newSourc.Where(predicate)).ToList();
            }
         }
         return result;
      }
   }
票数 1
EN

Stack Overflow用户

发布于 2022-05-18 13:15:59

好的,修改答案。你必须把你的收藏品压平,用正手(或者把它弄平)。

代码语言:javascript
复制
public ObservableCollection<Item> GetItemsFlat(string path)
        {
            var items = new ObservableCollection<Item>();

            if (!System.IO.Directory.Exists(path))
                return items;
            
            var dirInfo = new DirectoryInfo(path);

            foreach (var directory in dirInfo.EnumerateDirectories())
            {
                var item = new DirectoryItem
                {
                    Name = directory.Name,
                    Path = directory.FullName,
                    Items = GetItems(directory.FullName)
                };

                items.Add(item);
                foreach (var item in GetItemsFlat(directory.FullName))
                    items.Add(item);
            }

            foreach (var file in dirInfo.EnumerateFiles("*.rfa"))
            {
                InteropBitmap thumbImg = ShellFile.FromFilePath(file.FullName).Thumbnail.BitmapSource as InteropBitmap;
                thumbImg.Freeze();

                var item = new FamilyItem
                {
                    Name = file.Name,
                    Path = file.FullName,
                    FamImage = thumbImg
                };
                items.Add(item)
            }
        }

使用Path (即。FullName)属性,用于筛选,以将文件包含在匹配的子目录中,即。

ItemsCache.Where(x => x.Path.ToLower().Contains(SearchText.ToLower()))

此外,重构您的代码使用“返回早期”策略。(https://dev.to/jpswade/return-early-12o5)

即。而不是if (System.IO.Directory.Exists(path)) { ...lots of code }

代码语言:javascript
复制
if (!System.IO.Directory.Exists(path)) return EmptyCollection;`

...lots of code

您还可以改进此代码以从集合中丢弃“空”目录子树。

还要检查GetFileSystemInfo https://learn.microsoft.com/en-us/dotnet/api/system.io.directoryinfo.getfilesysteminfos?view=net-6.0,它可以用于搜索包括子目录在内的文件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72289575

复制
相关文章

相似问题

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