WPF:自动完成文本框,...再次

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2338690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:31:57  来源:igfitidea点击:

WPF: AutoComplete TextBox, ...again

wpftextboxautocomplete

提问by Cheeso

This other SO questionasks about an autocomplete textbox in WPF. Several people have built these, and one of the answers given there suggests this codeproject article.

另一个 SO 问题询问了 WPF 中的自动完成文本框。有几个人已经构建了这些,并且那里给出的答案之一建议这篇 codeproject article

But I've not found any WPF Autocomplete Textbox that compares with the WinForms autocomplete textbox. The codeproject sample works, sort of, ...

但我没有找到任何与 WinForms 自动完成文本框相比的 WPF 自动完成文本框。codeproject 示例工作,有点,......

alt text

替代文字

...but

...但

  • it isn't structured as a re-usable control or DLL. It's code I need to embed in every app.
  • It works only with directories. it doesn't have properties for setting whether the autocomplete source is filesystem directories only, or filesystem files, or ....etc. I could write code to do this, of course, but...I'd rather use someone else's code already written.
  • it doesn't have properties to set the popup size, etc.
  • there's a popup listbox that presents the posible completions. When navigating through that list, the textbox doesn't change. Typing a character while focused in the listbox doesn't cause the textbox to get updated.
  • navigating focus away from the listbox doesn't make the popup listbox disappear. This is confusing.
  • 它不是作为可重复使用的控件或 DLL 构建的。这是我需要嵌入到每个应用程序中的代码。
  • 它仅适用于目录。它没有用于设置自动完成源是仅文件系统目录还是文件系统文件或...等的属性。当然,我可以编写代码来执行此操作,但是……我宁愿使用其他人已经编写的代码。
  • 它没有设置弹出窗口大小等的属性。
  • 有一个弹出列表框显示可能的完成。浏览该列表时,文本框不会改变。在列表框中输入一个字符不会导致文本框更新。
  • 将焦点从列表框移开不会使弹出列表框消失。这令人困惑。

So, my question:

所以,我的问题:

*Does anyone have a FREE WPF AutoComplete textbox that works, and provides a quality UI experience?*

*有没有人有一个免费的 WPF 自动完成文本框,它可以工作并提供高质量的 UI 体验?*



ANSWER

回答

Here's how I did it:

这是我如何做到的:

.0. get the WPF Toolkit

.0。获取WPF 工具包

.1. run the MSI for the WPF Toolkit

.1. 为 WPF Toolkit 运行 MSI

.2. Within Visual Studio, Drag/drop from the toolbox - specifically the Data Visualization group - into the UI Designer. It looks like this in the VS toolbox:

.2. 在 Visual Studio 中,从工具箱(特别是数据可视化组)拖/放到 UI 设计器中。在 VS 工具箱中看起来是这样的:

alt text

替代文字

If you don't want to use the designer, hand-craft the xaml. It looks like this:

如果您不想使用设计器,请手工制作 xaml。它看起来像这样:



<toolkit:AutoCompleteBox
   ToolTip="Enter the path of an assembly."
   x:Name="tbAssembly" Height="27" Width="102"
   Populating="tbAssembly_Populating" />

...where the toolkit namespace is mapped this way:

...以这种方式映射工具包命名空间的地方:

xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"


.3. Provide the code for the Populatingevent. Here's what I used:

.3. 提供Populating事件的代码。这是我使用的:



private void tbAssembly_Populating(object sender, System.Windows.Controls.PopulatingEventArgs e)
{
    string text = tbAssembly.Text;
    string dirname = Path.GetDirectoryName(text);

    if (Directory.Exists(Path.GetDirectoryName(dirname)))
    {
        string[] files = Directory.GetFiles(dirname, "*.*", SearchOption.TopDirectoryOnly);
        string[] dirs = Directory.GetDirectories(dirname, "*.*", SearchOption.TopDirectoryOnly);
        var candidates = new List<string>();

        Array.ForEach(new String[][] { files, dirs }, (x) =>
            Array.ForEach(x, (y) =>
                      {
                          if (y.StartsWith(dirname, StringComparison.CurrentCultureIgnoreCase))
                              candidates.Add(y);
                      }));

        tbAssembly.ItemsSource = candidates;
        tbAssembly.PopulateComplete();
    }
}


It works, just the way you'd expect. It feels professional. There are none of the anomalies that the codeproject control exhibits. This is what it looks like:

它有效,正如您所期望的那样。感觉很专业。codeproject 控件没有任何异常。这是它的样子:

alt text

替代文字



Thanks to Matt for the pointerto the WPF toolkit.

感谢 Matt 提供指向WPF 工具包的指针

采纳答案by Matt Hamilton

The newest drop of the WPF Toolkitincludes an AutoCompleteBox. It's a free set of controls from Microsoft, some of which will be included in .NET 4.

WPF 工具包的最新版本包括一个 AutoCompleteBox。这是 Microsoft 提供的一组免费控件,其中一些将包含在 .NET 4 中。

Jeff Wilcox - Introducing the AutoCompleteBox

Jeff Wilcox - 介绍 AutoCompleteBox

回答by Cheeso

Here's how I did it:

这是我如何做到的:

.1. run the MSI for the WPF Toolkit

.1. 为 WPF Toolkit 运行 MSI

.2. Within Visual Studio, Drag/drop from the toolbox - specifically the Data Visualization group - into the UI Designer. It looks like this in the VS toolbox:

.2. 在 Visual Studio 中,从工具箱(特别是数据可视化组)拖/放到 UI 设计器中。在 VS 工具箱中看起来是这样的:

alt text

替代文字

Or, hand-craft the xaml. It looks like this:

或者,手工制作 xaml。它看起来像这样:



<toolkit:AutoCompleteBox
   ToolTip="Enter the path of an assembly."
   x:Name="tbAssembly" Height="27" Width="102"
   Populating="tbAssembly_Populating" />

...where the toolkit namespace is mapped this way:

...以这种方式映射工具包命名空间的地方:

xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"


.3. Provide the code for the Populatingevent. Here's what I used:

.3. 提供Populating事件的代码。这是我使用的:



private void tbAssembly_Populating(object sender, System.Windows.Controls.PopulatingEventArgs e)
{
    string text = tbAssembly.Text;
    string dirname = Path.GetDirectoryName(text);

    if (Directory.Exists(Path.GetDirectoryName(dirname)))
    {
        string[] files = Directory.GetFiles(dirname, "*.*", SearchOption.TopDirectoryOnly);
        string[] dirs = Directory.GetDirectories(dirname, "*.*", SearchOption.TopDirectoryOnly);
        var candidates = new List<string>();

        Array.ForEach(new String[][] { files, dirs }, (x) =>
            Array.ForEach(x, (y) =>
                      {
                          if (y.StartsWith(dirname, StringComparison.CurrentCultureIgnoreCase))
                              candidates.Add(y);
                      }));

        tbAssembly.ItemsSource = candidates;
        tbAssembly.PopulateComplete();
    }
}


Thanks to Matt for the pointer to the WPF toolkit.

感谢 Matt 提供指向 WPF 工具包的指针。

回答by Troy

I use the Intellibox in my in-house project. http://intellibox.codeplex.com/

我在我的内部项目中使用 Intellibox。http://intellibox.codeplex.com/

I find it's use of the Provider pattern for searching very intuitive.

我发现它使用 Provider 模式进行搜索非常直观。

Rake's answer provides an example of how to use it, and as he points out, it has seen some development late last year (although this is well after I last used it).

Rake 的回答提供了一个如何使用它的例子,正如他所指出的,它在去年年底得到了一些发展(尽管这在我上次使用它之后已经很久了)。

回答by RationalDev likes GoFundMonica

Mindscape also provides a 3 free controlsincluding a WPF Autocomplete Textbox

Mindscape 还提供了3 个免费控件,包括一个 WPF 自动完成文本框

http://intellibox.codeplex.com/does seem to updated as recently as Oct 1, 2013 and contains the single control. I would have added as comment on Troy's answer, but don't have enough rep. I nearly ignored it because of that comment.

http://intellibox.codeplex.com/似乎在 2013 年 10 月 1 日更新,并且包含单个控件。我会添加作为对特洛伊答案的评论,但没有足够的代表。因为那条评论,我几乎忽略了它。

Example usage from documentation:

文档中的示例用法:

    <auto:Intellibox ResultsHeight="80"
                     ExplicitlyIncludeColumns="True"
                     Name="lightspeedBox"
                     DisplayedValueBinding="{Binding Product_Name}"
                     SelectedValueBinding="{Binding Product_Id}"
                     DataProvider="{Binding RelativeSource={RelativeSource FindAncestor, 
                     AncestorType={x:Type Window}}, Path=LinqToEntitiesProvider}"
                     Height="26"
                     Margin="12,26,12,0"
                     VerticalAlignment="Top">
        <auto:Intellibox.Columns>
            <auto:IntelliboxColumn DisplayMemberBinding="{Binding Product_Name}"
                                   Width="150"
                                   Header="Product Name" />
            <auto:IntelliboxColumn DisplayMemberBinding="{Binding Unit_Price}"
                                   Width="75"
                                   Header="Unit Price" />
            <auto:IntelliboxColumn DisplayMemberBinding="{Binding Suppliers.Company_Name}"
                                   Width="125"
                                   Header="Supplier" />
        </auto:Intellibox.Columns>
    </auto:Intellibox>

回答by Deepak Bhardwaj

You can try WPF Auto Complete TextBox at CodePlex here: https://wpfautocomplete.codeplex.com/

您可以在 CodePlex 上尝试 WPF 自动完成文本框:https: //wpfautocomplete.codeplex.com/