我使用MVVM来填充一个TreeView和它的所有子目录和文件。
然后,我想用LINQ .where()在treeview中搜索,但我只搜索顶部的目录,而不是文件。
我正在使用递归方法创建treeview/DirectoryInfo:
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的模型:
项目模型:
public class Item
{
public string Name { get; set; }
public string Path { get; set; }
public InteropBitmap FamImage { get; set; }
}DirectoryItem模型:
public class DirectoryItem : Item
{
public ObservableCollection<Item> Items { get; set; }
public DirectoryItem()
{
Items = new ObservableCollection<Item>();
}
}FamilyItem:
public class FamilyItem : Item
{
},我正在用:过滤集合
Items = new ObservableCollection<Item>(ItemsCache.Where(x => x.Name.ToLower().Contains(SearchText.ToLower())));我只得到匹配的顶级目录--我想得到所有匹配的“结束”文件--我该怎么做呢?
发布于 2022-05-18 14:36:12
您可以通过递归版本覆盖.Where(..):
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;
}
}发布于 2022-05-18 13:15:59
好的,修改答案。你必须把你的收藏品压平,用正手(或者把它弄平)。
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 }
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,它可以用于搜索包括子目录在内的文件。
https://stackoverflow.com/questions/72289575
复制相似问题