65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 面包屑文件夹文本框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (9投票s)

2009年1月2日

LGPL3

6分钟阅读

viewsIcon

104808

downloadIcon

1725

本文提供了一个 WPF 面包屑控件的实现,并说明了如何开发一个。

demo.jpg

引言

本文提供了一个 WPF Breadcrumb 控件的实现,并说明了如何开发一个。

背景

Vista 发布时,它的一个主要功能是 Breadcrumb 资源管理器栏,我一直想做一个,但一直缺乏自行开发的知识。

Nesher 在几个月前创建了一个 breadcrumb 组件,它是一个功能齐全的组件,但它是一个 XAML 密集型解决方案,代码对我来说太复杂,无法理解,更不用说我想要修改它并添加功能了,所以我使用 MVP 模式(模型是 string)编写了自己的。

他的实现给了我开发面包屑的想法,并且我从他的实现中借鉴了一些样式。除此之外,我的实现是完全重写的,它们之间有几个不同之处

  • 它是完全基于 string 的,这意味着
    • 子文件夹轮询是手动完成的。您不能绑定 HierarchicalDataModel 并期望它自动工作。
  • 您可以使用两个或多个不同的“Root”,例如演示中的 Folder Animal ,这可以在运行时更改。
  • 展开器支持,当 Breadcrumb BreadcrumbItems 过多时显示。

    expander1.jpg

  • 进度条支持。
  • 下拉列表支持,BreadcrumbControl 本身就是一个 ComboBox(版本 2)
  • 自动完成文本框支持

    acTextBox.jpg

  • 更改目录时记住子项位置,仅在必要时重新排列。

    rememberPosition.jpg

如何使用?

如果您想将该组件仅用作目录 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 转换器。

图表如下

BreadcrumbControl.png

程序的一部分(AutoCompleteTextBox BreadcrumbCore)使用模型-视图-演示者设计模式设计,这区分了 UI 代码和逻辑代码并降低了复杂性。

BreadcrubCore 包含几个组件:breadcrumbIndex.jpg

  • 一个 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 是容器内的项目,它由自定义 BreadcrumbItemBasePresenter)和 a ComboBoxView)组成

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 中,包含所有子文件夹(strings)。

Nesher 的实现使用上下文菜单而不是 ComboBox,这可以使用 ComboBox 更容易地实现,但是,ComboBox Popup 的默认位置是靠左对齐的,必须更改 Placement PlacementTarget 属性,如下所示

<Popup ... Placement="Bottom" PlacementTarget="{Binding ElementName=buttonExpand}" />

CustomCombobox.jpg

顺便说一下,TranslateTransform 无法重新定位 Popup,例如,以下方法无效

<Popup.RenderTransform>
  <TranslateTransform X="150" Y="0"/>
</Popup.RenderTransform>

Expander 是一个没有 DisplayText 且图标经过自定义的 ComboBox。当 Breadcrumb ItemIsHitTestVisible 设置为 false (由 BreadcrumbCorePanel)时,它们会将自身添加到展开器,并在反向时移除。在版本 2 中,展开器被根组合框替换。

expander.jpg
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
© . All rights reserved.