WPF 中的自动完成文本框

56

在WPF中,是否可以使文本框自动完成?

我找到了一个示例,其中使用组合框,并通过编辑样式模板删除了三角形。

有更好的解决方案吗?


2
这是一个好的开端 http://joshsmithonwpf.wordpress.com/2007/06/12/searching-for-items-in-a-listbox/ - Daniil Harik
7个回答

40

4
WPF Toolkit现在可在GitHub上找到:https://github.com/xceedsoftware/wpftoolkit。 - user
WPF Toolkit不可用于商业用途 :( - Clonkex

13

Nimgoble's是我在2015年使用的版本。 我想把它放在这里,因为谷歌对“wpf自动完成文本框”的搜索结果中,这个问题排名第一。

  1. 在Visual Studio项目中安装nuget包

  2. 在xaml中添加对该库的引用:
    xmlns:behaviors="clr-namespace:WPFTextBoxAutoComplete;assembly=WPFTextBoxAutoComplete"

  3. 创建一个文本框,并将AutoCompleteBehaviour绑定到List<String>(TestItems):
    <TextBox Text="{Binding TestText, UpdateSourceTrigger=PropertyChanged}" behaviors:AutoCompleteBehavior.AutoCompleteItemsSource="{Binding TestItems}" />

在我看来,与上面列出的其他选项相比,这要容易得多,也更容易管理。


6
在内联自动完成方面表现良好,但不提供包含选项的下拉列表。 - lambinator
1
@lambinator - 是的,没有下拉菜单。从设计的角度来看,如果我只有几个项目(比如<20-50?),那么我会使用普通的组合框,因为你可以在里面输入:https://dev59.com/lXRB5IYBdhLWcg3wxZxK#8333801。如果我有太多的项目要显示(谁想要滚动很长时间?),那么我会使用这个自动完成文本框。 - JumpingJezza

4
或者您可以通过单击它并选择项目,将AutoCompleteBox添加到工具箱中,转到WPF组件,输入过滤器AutoCompleteBox(位于System.Windows.Controls命名空间中),然后将其拖入xaml文件中。这比做其他事情要容易得多,因为AutoCompleteBox是本地控件。

16
System.Windows.Controls.AutoCompleteBox 不是 WPF 的一部分。您需要添加对 WPF Toolkit 的引用才能使用该控件。 - Martin Liversage
1
@MartinLiversage 我已经为Visual Studio 2013添加了WPF工具包,但工具箱中仍然看不到自动完成框。为什么会这样呢? - vigamage

4
我知道这是一个非常老的问题,但我想添加一个答案。

首先,你需要为你的普通TextChanged事件处理程序创建一个处理程序,用于TextBox:

private bool InProg;
internal void TBTextChanged(object sender, TextChangedEventArgs e)
            {
            var change = e.Changes.FirstOrDefault();
            if ( !InProg )
                {
                InProg = true;
                var culture = new CultureInfo(CultureInfo.CurrentCulture.Name);
                var source = ( (TextBox)sender );
                    if ( ( ( change.AddedLength - change.RemovedLength ) > 0 || source.Text.Length > 0 ) && !DelKeyPressed )
                        {
                         if ( Files.Where(x => x.IndexOf(source.Text, StringComparison.CurrentCultureIgnoreCase) == 0 ).Count() > 0 )
                            {
                            var _appendtxt = Files.FirstOrDefault(ap => ( culture.CompareInfo.IndexOf(ap, source.Text, CompareOptions.IgnoreCase) == 0 ));
                            _appendtxt = _appendtxt.Remove(0, change.Offset + 1);
                            source.Text += _appendtxt;
                            source.SelectionStart = change.Offset + 1;
                            source.SelectionLength = source.Text.Length;
                            }
                        }
                InProg = false;
                }
            }

然后创建一个简单的PreviewKeyDown处理程序:
    private static bool DelKeyPressed;
    internal static void DelPressed(object sender, KeyEventArgs e)
    { if ( e.Key == Key.Back ) { DelKeyPressed = true; } else { DelKeyPressed = false; } }

在这个例子中,“Files”是在应用程序启动时创建的目录名称列表。
然后只需附加处理程序:
public class YourClass
  {
  public YourClass()
    {
    YourTextbox.PreviewKeyDown += DelPressed;
    YourTextbox.TextChanged += TBTextChanged;
    }
  }

使用这个方法,无论你选择将什么放入List中,都将用于自动完成框。如果你期望在自动完成中有一个巨大的列表,那可能不是一个很好的选择,但在我的应用程序中,它只会看到20-50个项目,所以它非常快速循环。

3

如果您只有少量需要自动完成的值,您可以在xaml中简单地添加它们。键入时将调用自动完成功能,并且您还可以使用下拉菜单。

<ComboBox Text="{Binding CheckSeconds, UpdateSourceTrigger=PropertyChanged}"
          IsEditable="True">
    <ComboBoxItem Content="60"/>
    <ComboBoxItem Content="120"/>
    <ComboBoxItem Content="180"/>
    <ComboBoxItem Content="300"/>
    <ComboBoxItem Content="900"/>
</ComboBox>

1
我很惊讶为什么没有人建议使用WinForms文本框。
XAML:
     <WindowsFormsHost  Margin="10" Width="70">
        <wf:TextBox x:Name="textbox1"/>
     </WindowsFormsHost>

同时不要忘记Winforms命名空间:

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

C#:

     AutoCompleteStringCollection stringCollection = new AutoCompleteStringCollection(){"String 1", "String 2", "etc..."};
   
     textbox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
     textbox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
     textbox1.AutoCompleteCustomSource = stringCollection;

使用自动完成功能,您需要在代码后台进行操作,因为由于某些原因(其他人可能可以解释),它会抛出异常。

1

使用 WPF PopUp 元素和一个文本框的方法如下:

XAML 文件

<TextBox x:Name="DocumentType"
    Margin="20"
    KeyUp="DocumentType_KeyUp"
    LostFocus="DocumentType_LostFocus"/>

<Popup x:Name="autoCompletorListPopup"
        Visibility="Collapsed"
        StaysOpen="False"
        AllowsTransparency="True"
        PlacementTarget="{Binding ElementName=DocumentType}"
        Width="150"
        Placement="Bottom">
    <ListBox x:Name="autoCompletorList"
                Background="WhiteSmoke"
                MaxHeight="200"
                Margin="20 0"
                SelectionChanged="autoCompletorList_SelectionChanged"/>
</Popup>

CS file

List<string> listDocumentType = new List<string>() {"Pdf File","AVI File","JPEG file","MP3 sound","MP4 Video"} //...

private void autoCompletorList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    try
    {
        if (autoCompletorList.SelectedItem != null)
        {
            DocumentType.Text = autoCompletorList.SelectedValue.ToString();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

private void DocumentType_KeyUp(object sender, KeyEventArgs e)
{
    try
    {
        if(e.Key == Key.Enter)
        {
            // change focus or remove focus on this element
            NextElementBox.Focus();
        }
        else
        {
            if (DocumentType.Text.Trim() != "")
            {
                autoCompletorListPopup.IsOpen = true;
                autoCompletorListPopup.Visibility = Visibility.Visible;
                autoCompletorList.ItemsSource = listDocumentType.Where(td => td.Trim().ToLower().Contains(DocumentType.Text.Trim().ToLower()));
            }
            else
            {
                autoCompletorListPopup.IsOpen = false;
                autoCompletorListPopup.Visibility = Visibility.Collapsed;
                autoCompletorList.ItemsSource = null;
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

private void DocumentType_LostFocus(object sender, RoutedEventArgs e)
{
    try
    {
        if (autoCompletorList.SelectedItem != null)
        {
            DocumentType.Text = autoCompletorList.SelectedValue.ToString();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

从这篇文章中:https://www.c-sharpcorner.com/article/wpf-auto-completesuggestion-text-box-control2/ - Romylussone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接