WPF 面包屑文件夹文本框






4.41/5 (9投票s)
本文提供了一个 WPF 面包屑控件的实现,并说明了如何开发一个。

引言
本文提供了一个 WPF Breadcrumb
控件的实现,并说明了如何开发一个。
背景
Vista 发布时,它的一个主要功能是 Breadcrumb
资源管理器栏,我一直想做一个,但一直缺乏自行开发的知识。
Nesher 在几个月前创建了一个 breadcrumb 组件,它是一个功能齐全的组件,但它是一个 XAML 密集型解决方案,代码对我来说太复杂,无法理解,更不用说我想要修改它并添加功能了,所以我使用 MVP 模式(模型是 string
)编写了自己的。
他的实现给了我开发面包屑的想法,并且我从他的实现中借鉴了一些样式。除此之外,我的实现是完全重写的,它们之间有几个不同之处
- 它是完全基于
string
的,这意味着- 子文件夹轮询是手动完成的。您不能绑定
HierarchicalDataModel
并期望它自动工作。
- 子文件夹轮询是手动完成的。您不能绑定
- 您可以使用两个或多个不同的“
Root
”,例如演示中的Folder
和Animal
,这可以在运行时更改。 - 展开器支持,当
Breadcrumb
上BreadcrumbItems
过多时显示。 - 进度条支持。
- 下拉列表支持,
BreadcrumbControl
本身就是一个ComboBox
(版本 2) - 自动完成文本框支持
- 更改目录时记住子项位置,仅在必要时重新排列。
如何使用?
如果您想将该组件仅用作目录 Breadcrumb
,只需将主控件添加到您的窗口中。主控件有一个名为 SelectedFolder
的可绑定属性,它是一个 string
,您可以将其绑定到其他组件,例如
<TextBox x:Name="tb" Text="{Binding ElementName=breadcrumb, Path=RootFolder}" />
<uc:BreadcrumbControl Margin="0,50,0,0" x:Name="breadcrumb" />
如果您想使用该组件来显示自定义数据,您将不得不编写
- 一个视图,即
DataTemplate
,<DataTemplate x:Key="folderDataTemplate"> <DockPanel> <!-- an Icon and a textbox --> <Image Height="16" Width="16" Source="{Binding Icon}" /> <TextBlock Text="{Binding DisplayName}" Margin="2,0" /> </DockPanel> </DataTemplate> <!-- hook it to SubItemTemplate of BreadcrumbControl --> <uc:BreadcrumbControl SubItemTemplate="{StaticResource folderDataTemplate}"/>
- 一个演示者,它派生自
BreadcrumbItemBase
,它实现了以下内容:如果您想附加您的模型,可以在派生的演示者中附加。//Required// //Poll a list of subfolders of current directory. (it's only called when needed) //Threading is already implemented, you dont have to implement your own. public override BreadcrumbItemBase[] PollSubFolders(); //Optionsl// //Convert from DisplayPath to LogicalPath, or vice versa //DisplayPath is based on DisplayName (e.g. Computer\C:\\Program Files\qzLite3) //LogicalPath is based on FolderName (e.g. C:\ProgramFiles\qzLite3) public override string ConvertPath(BreadcrumbItemBase.PathType pt, string path) //Return Icon of current folder public override ImageSource GetIcon()
- 修改
BreadcrumbControl
以支持您的新演示者和视图。CustomPresenter Root = new CustomPresenter(); SwitchPresenter(Root); //Once you run the above code, the BreadcrumbControl will use your presenter.
它是如何工作的?
正如我之前提到的,整个东西都是基于 string
的,ItemsPresenter
返回 string
作为文件夹,文件夹创建基于文件夹名称,这就是为什么您必须确保在将代码传递给 BreadcrumbControl
中的 CurrentFolder
属性之前代码是合法的。(TypedPresenter
确实有一些查找功能,其他实现不检查文件夹是否存在)。
基于 String
使其更容易开发(Breadcrumb
通常用于导航目的,有时您不想为每个导航项创建一个模型),但是,它限制了在视图中显示的信息量,幸运的是,对于 BreadcrumbItems
,它只需要一个图标和一个文本,我可以轻松地使用“Converter
”来完成这项工作。对于文件夹路径,我使用了 PathToDirNameConverter
,对于图标,我使用了 FileToIcon 转换器。
图表如下

程序的一部分(AutoCompleteTextBox
和 BreadcrumbCore
)使用模型-视图-演示者设计模式设计,这区分了 UI 代码和逻辑代码并降低了复杂性。
- 一个
BreadcrumbCore
- 包含一个展开器,- 包含一个或多个
BreadcrumbItems
- 包含一个或多个
- 一个
AutoCompleteTextBox
(AutoCompleteTextBox
) - 一个
ProgressBar
(可以通过BreadcrumbControl
中的Progress
和IsIndeterminate
访问) - 几个
buttons
- 一个切换按钮,用于在
AutoCompleteTextBox
和BreadcrumbCore
之间切换 - 一个用于下拉列表的切换按钮
- 一个刷新按钮(单击时引发
RefreshClicked
事件)
- 一个切换按钮,用于在
AutoCompleteTextBox
“AutoCompleteTextBox
” 根据输入建议项目,它会查找当前文件夹中的所有项目,并在文本匹配时显示。
List<string> retVal = new List<string>();
foreach (BreadcrumbItemBase subFolder in _currentPresenter.ActualSubFolders)
if (subFolder.FolderPath.ToLower().StartsWith(_selectedPath.ToLower()))
retVal.Add(subFolder.FolderPath);
Suggestions = retVal.ToArray(); // output the suggestions
BreadcrumbItem
BreadcrumbItem
是容器内的项目,它由自定义 BreadcrumbItemBase
(Presenter
)和 a ComboBox
(View
)组成
BreadcrumbItemBase
是 BreadcrumbItems
的演示者,演示中定义了几个 ItemsPresenter
BreadcrumbItemBase
- 基类,从中派生以定义自定义BreadcrumbItemBase
FolderPresenter
- 包含当前文件夹的逻辑并轮询子文件夹AnimalPresenter
- 仅用于测试目的,生成猫/狗/老鼠组合作为子文件夹
BreadcrumbItems
的视图部分是样式化的 ComboBox
,其 Items
绑定到 ItemPresenter
的 SubFolders,ComboBox
具有以下项目
- 主按钮(
buttonCurrent
),占据了ComboBox
的大部分空间,当用户单击它时,更改为当前文件夹。(这就是为什么它被称为按钮Current
) - 切换按钮(
buttonExpand
),指定是否显示Popup
(我在这里使用了 nesher 的样式) Popup
(PART_Popup
),弹出部分,WPF 需要它,所以这样命名。ItemsPresenter
(itemList
),位于popup
中,包含所有子文件夹(string
s)。
Nesher 的实现使用上下文菜单而不是 ComboBox
,这可以使用 ComboBox
更容易地实现,但是,ComboBox
中 Popup
的默认位置是靠左对齐的,必须更改 Placement
和 PlacementTarget
属性,如下所示
<Popup ... Placement="Bottom" PlacementTarget="{Binding ElementName=buttonExpand}" />
顺便说一下,TranslateTransform
无法重新定位 Popup
,例如,以下方法无效
<Popup.RenderTransform>
<TranslateTransform X="150" Y="0"/>
</Popup.RenderTransform>
Expander
是一个没有 DisplayText
且图标经过自定义的 ComboBox
。当 Breadcrumb Item
的 IsHitTestVisible
设置为 false
(由 BreadcrumbCorePanel
)时,它们会将自身添加到展开器,并在反向时移除。在版本 2 中,展开器被根组合框替换。

public bool HitTestVisible { get { return true; }
set { changedHitTestVisible(value); } } //Bound to UI
private void changedHitTestVisible(bool value)
{
if (!value) _parentPresenter.Expander.Add(DisplayPath);
else _parentPresenter.Expander.Remove(DisplayPath);
}
如果列表中没有项目,则 ToggleButton
将隐藏。
未完成项目
- 历史
ComboBox
参考
历史
- 02-01-09 初始版本
- 03-01-09 修复:展开器中的幽灵文件夹
- 03-01-09 添加:返回选定的文件夹模型(用于
TypedPresenter
) - 04-01-09 添加:Alt+D 切换
TextBox
/Breadcrumb
- 04-01-09 添加:
Autocomplete textbox
现在支持非磁盘文件夹类型 - 04-01-09 版本 1.2
- 04-01-09 修复:在
textbox
中按回车键,如果文本未更改,则不会切换回breadcrumb
- 05-01-09 更新:代码清理,创建了程序集(QuickZip.UserControls.Breadcrumb.dll)
- 05-01-09 添加:视图部分已移至
BreadcrumbControl.SubItemTemplate
(参见演示,文章需要更新) - 05-01-09 修复:对
TypedPresenter
进行了一些更新 - 05-01-09 版本 1.3
- 05-01-09 修复:Alt+D 切换未正确工作
- 05-01-09 更新:切换到
textbox
时选择最后一个字符 05-01-09 添加:记住子项位置
- 05-01-09 修复:选择文件夹时建议更改导致崩溃
- 05-01-09 版本 1.4
- 06-01-09 修复:又出现幽灵文件夹(上个版本损坏)
- 06-01-09 版本 1.5
- 07-01-09 添加:QuickZip.UserControls.TypedBreadcrumb.dll,专为模型使用设计
- 07-01-09 ----:(展开器未完成,自动完成文本框有时不显示建议,将在下一个版本中添加)
- 07-01-09 更新:演示已更新以反映更改
- 07-01-09 文章更新
- 07-01-09 版本 1.6
- 08-01-09 修复:
TypedBreadcrumb
中的Expander
和AutocompleteTextbox
- 08-01-09 版本 1.7
- 16-01-09 更新:重写,简化代码并添加了一些文档(尚未完成)
- 16-01-09 更新:移除了展开器并将展开器逻辑放在根目录(看起来更像 Vista 的
breadcrumb
)。 - 16-01-09 添加:现在支持带有
null FolderName
的文件夹(例如 Desktop\Computer) - 16-01-09 添加:现在支持将自定义文件夹添加到展开器列表(参见IExpander.cs中的
IRoot
接口,或演示) - 16-01-09 添加:支持将分隔符添加到展开器列表
- 16-01-09 版本 2.1
- 16-01-09 文章已更新
- 16-01-09 添加:刷新按钮
- 16-01-09 添加:历史下拉列表
- 16-01-09 修复:分隔符宽度
- 16-01-09 更新:未选择项目时显示根标题
- 17-01-09 修复:
IsTextBoxEnabled
现在可以工作了 - 17-01-09 版本 2.2
- 17-01-09 修复:打开时
DropDown SelectedIndex
未重置 - 18-01-09 添加:
RefreshCommand
/Parameter
/Target
- 18-01-09 更新:BreadcrumbItemBase.cs 的文档
- 18-01-09 版本 2.3
- 20-01-09 更新:更好的
DataBinding
支持 - 22-01-09 添加:根文件夹调整大小、更改文件夹时出现动画
- 22-01-09 版本 2.4
- 23-01-09 修复:将文件夹添加到展开器(内部)会更改根选择索引,并导致意外的文件夹更改
- 23-01-09 版本 2.5