Подтвердить что ты не робот

WPF: автозаполнение TextBox,... снова

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

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

alt text

...но

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

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

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


ОТВЕТ

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

+0,0. получить инструментарий WPF

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.

4b9b3361

Ответ 2

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

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.

Ответ 3

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

Я нахожу его использование шаблона Provider для поиска очень интуитивно понятным.

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

Ответ 4

Mindscape также предоставляет 3 бесплатных элемента управления, включая текстовое поле Autocomplete 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>