代码之家  ›  专栏  ›  技术社区  ›  Cheeso

wpf:自动完成文本框,…再次

  •  45
  • Cheeso  · 技术社区  · 15 年前

    This other SO question 询问有关WPF中自动完成文本框的信息。有几个人建造了这些,其中一个答案表明 this codeproject article .

    但我没有找到任何与WinForms自动完成文本框相比较的WPF自动完成文本框。代码项目示例工作,有点……

    alt text http://i50.tinypic.com/sx2ej5.jpg

    但…

    • 它的结构不是一个可重用的控件或DLL。这是我需要嵌入到每个应用程序中的代码。
    • 它只适用于目录。它没有用于设置自动完成源是否仅是文件系统目录、文件系统文件或….等的属性。当然,我可以编写代码来完成此操作,但…我宁愿使用其他人已经编写的代码。
    • 它没有设置弹出窗口大小等的属性。
    • 有一个弹出列表框显示可设置位置的完成。浏览该列表时,文本框不会更改。在列表框中集中输入字符不会导致文本框得到更新。
    • 将焦点远离列表框不会使弹出列表框消失。这让人困惑。

    *有人有免费的WPF自动完成文本框吗 那作品 并提供高质量的用户界面体验?*


    回答

    我是这样做的:

    0。得到 WPF Toolkit

    1。运行wpf工具包的msi

    2。在Visual Studio中,从工具箱(特别是数据可视化组)拖放到UI设计器中。在vs工具箱中如下所示:

    alt text http://i49.tinypic.com/s12q6x.jpg

    如果你不想使用设计师,手工制作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();
        }
    }
    

    它可以工作,就像你所期望的那样。感觉很专业。代码项目控制没有显示出任何异常。这就是它的样子:

    alt text http://i50.tinypic.com/24qsopy.jpg


    Thanks to Matt for the pointer 到WPF工具包。

    5 回复  |  直到 10 年前
        1
  •  32
  •   Matt Hamilton    15 年前

    最新的一滴 WPF Toolkit 包括自动完成框。这是微软提供的一套免费控件,其中一些将包含在.NET 4中。

    Jeff Wilcox - Introducing the AutoCompleteBox

        2
  •  17
  •   Cheeso    15 年前

    我是这样做的:

    1。运行wpf工具包的msi

    2。在Visual Studio中,从工具箱(特别是数据可视化组)拖放到UI设计器中。在vs工具箱中如下所示:

    alt text http://i49.tinypic.com/s12q6x.jpg


    <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();
        }
    }
    

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

        3
  •  2
  •   Athari    11 年前

    Mindscape还提供了 3 free controls 包括WPF自动完成文本框

    http://intellibox.codeplex.com/ 似乎最新于2013年10月1日更新,包含单一控制。我本可以对特洛伊的回答加上评论,但没有足够的代表。因为这个评论,我几乎忽略了它。

    文档中的示例用法:

        <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>
    
        4
  •  2
  •   Troy    11 年前

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

    我发现它使用提供者模式来搜索非常直观。

    Rake的答案提供了一个如何使用它的例子,正如他指出的那样,它在去年晚些时候看到了一些发展(尽管这在我上次使用它之后已经很好了)。

        5
  •  2
  •   Deepak Bhardwaj    10 年前

    您可以在codeplex这里尝试wpf auto-complete文本框: https://wpfautocomplete.codeplex.com/