WPF: автозаполнение TextBox, ... снова - PullRequest
45 голосов
/ 26 февраля 2010

Этот другой вопрос SO спрашивает об автозаполнении текстового поля в WPF. Несколько человек создали их, и один из ответов, приведенных там, предлагает эту статью проекта кода .

Но я не нашел ни одного текстового поля автозаполнения WPF, которое можно сравнить с текстовым полем автозаполнения WinForms. Пример кода проекта работает, вроде, ...

alt text

... но

  • он не структурирован как повторно используемый элемент управления или DLL. Это код, который мне нужно встроить в каждое приложение.
  • Работает только с каталогами. у него нет свойств для установки, является ли источник автозаполнения только каталогами файловой системы, или файлами файловой системы, или .... и т. д. Конечно, я мог бы написать код для этого, но ... я бы предпочел использовать уже написанный чужой код.
  • У него нет свойств для установки размера всплывающего окна и т. Д.
  • есть всплывающее окно со списком возможных завершений. При навигации по этому списку текстовое поле не меняется. Ввод символа, находящегося в фокусе в списке, не приводит к обновлению текстового поля.
  • перемещение фокуса от списка не приводит к исчезновению всплывающего списка. Это смущает.

Итак, мой вопрос:

* У кого-нибудь есть БЕСПЛАТНОЕ текстовое поле автозаполнения WPF , которое работает и обеспечивает качественный пользовательский интерфейс? *


ОТВЕТ

Вот как я это сделал:

0,0. получить WPF Toolkit

0,1. запустить MSI для WPF Toolkit

0,2. В Visual Studio перетаскивайте мышью из панели инструментов, в частности, из группы «Визуализация данных», в конструктор пользовательского интерфейса. На панели инструментов VS это выглядит так:

alt text

Если вы не хотите использовать дизайнер, сделайте вручную 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"

0,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. Вот как это выглядит:

alt text


Спасибо Мэтту за указатель на набор инструментов WPF.

Ответы [ 5 ]

32 голосов
/ 26 февраля 2010

Новейшая капля WPF Toolkit включает AutoCompleteBox. Это бесплатный набор элементов управления от Microsoft, некоторые из которых будут включены в .NET 4.

Джефф Уилкокс - Представляем AutoCompleteBox

17 голосов
/ 26 февраля 2010

Вот как я это сделал:

0,1. запустить MSI для WPF Toolkit

0,2. В Visual Studio перетаскивайте мышью из панели инструментов, в частности, из группы «Визуализация данных», в конструктор пользовательского интерфейса. На панели инструментов VS это выглядит так:

alt text

Или, сделай вручную 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"

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

Спасибо Мэтту за указатель на инструментарий WPF.

2 голосов
/ 29 июля 2014

Вы можете попробовать WPF Auto Complete TextBox в CodePlex здесь: https://wpfautocomplete.codeplex.com/

2 голосов
/ 02 мая 2014

Mindscape также предоставляет 3 бесплатных элемента управления , включая текстовое поле автозаполнения WPF

http://intellibox.codeplex.com/, по-видимому, обновлено только 1 октября 2013 года и содержит единственный элемент управления. Я бы добавил в качестве комментария ответ Троя, но мне не хватает представителя. Я почти проигнорировал это из-за этого комментария.

Пример использования из документации:

    <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>
2 голосов
/ 19 июля 2011

Я использую Intellibox в своем собственном проекте. http://intellibox.codeplex.com/

Я считаю, что использование шаблона провайдера для поиска очень интуитивно понятно.

В ответе Рэйка приведен пример того, как его использовать, и, как он указывает, в конце прошлого года произошли некоторые изменения (хотя это произошло после того, как я в последний раз использовал его).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...