这个 Stack Overflow 的问题 询问了 WPF 中的自动完成文本框。已经有几个人建立了这些,其中一个给出的答案建议使用 这篇 CodeProject 文章。
但是我还没有找到任何与 WinForms 自动完成文本框相比较的 WPF 自动完成文本框。CodeProject 的示例可以运行,但是有点问题...
但是:
- 它不像可重复使用控件或DLL那样结构化。 它是我需要嵌入每个应用程序的代码。
- 它仅适用于目录。 它没有设置自动完成源是否仅限于文件系统目录、文件系统文件等属性。 当然,我可以编写代码来实现这一点,但......我宁愿使用别人已经编写好的代码。
- 它没有设置弹出窗口大小等属性。
- 有一个弹出列表框显示可能的自动完成。 在浏览该列表时,文本框不会改变。 在列表框中聚焦时键入字符不会导致文本框更新。
- 将焦点从列表框导航到其他地方不会使弹出列表框消失。 这很令人困惑。
所以,我的问题是:
* 有人有免费的WPF AutoComplete文本框(有效),并提供优质的UI体验吗? *
回答
这是我实现的方法:
.0. 获取WPF Toolkit。
.1. 运行 WPF Toolkit 的 MSI 安装程序。
.2. 在 Visual Studio 中,从工具箱中拖放 - 特别是数据可视化组 - 到 UI Designer。在 VS 工具箱中它看起来像这样:
如果您不想使用设计师工具,可以手动编写XAML。它看起来像这样:<toolkit:AutoCompleteBox
ToolTip="Enter the path of an assembly."
x:Name="tbAssembly" Height="27" Width="102"
Populating="tbAssembly_Populating" />
...其中工具包命名空间是这样映射的:
xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
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();
}
}
它运作正常,就像你预期的那样。感觉很专业。没有codeproject控件表现出的任何异常情况。它看起来是这样的:
感谢Matt提供的指引,介绍了WPF工具包。