在WPF中,是否可以使文本框自动完成?
我找到了一个示例,其中使用组合框,并通过编辑样式模板删除了三角形。
有更好的解决方案吗?
在WPF中,是否可以使文本框自动完成?
我找到了一个示例,其中使用组合框,并通过编辑样式模板删除了三角形。
有更好的解决方案吗?
你可以在 WPF Toolkit 中找到一个,也可以通过 NuGet 获取。
本文演示如何创建一个文本框,它可以根据输入自动建议项目,例如磁盘驱动器文件夹。 WPF 自动完成文件夹文本框
还可以看看这个不错的 可重用的 WPF 自动完成文本框,对我很有用。
Nimgoble's是我在2015年使用的版本。 我想把它放在这里,因为谷歌对“wpf自动完成文本框”的搜索结果中,这个问题排名第一。
在Visual Studio项目中安装nuget包
在xaml中添加对该库的引用:
xmlns:behaviors="clr-namespace:WPFTextBoxAutoComplete;assembly=WPFTextBoxAutoComplete"
创建一个文本框,并将AutoCompleteBehaviour绑定到List<String>
(TestItems):
<TextBox Text="{Binding TestText, UpdateSourceTrigger=PropertyChanged}"
behaviors:AutoCompleteBehavior.AutoCompleteItemsSource="{Binding TestItems}" />
在我看来,与上面列出的其他选项相比,这要容易得多,也更容易管理。
System.Windows.Controls.AutoCompleteBox
不是 WPF 的一部分。您需要添加对 WPF Toolkit 的引用才能使用该控件。 - Martin Liversage首先,你需要为你的普通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; } }
public class YourClass
{
public YourClass()
{
YourTextbox.PreviewKeyDown += DelPressed;
YourTextbox.TextChanged += TBTextChanged;
}
}
List
中,都将用于自动完成框。如果你期望在自动完成中有一个巨大的列表,那可能不是一个很好的选择,但在我的应用程序中,它只会看到20-50个项目,所以它非常快速循环。如果您只有少量需要自动完成的值,您可以在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>
<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;
使用 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);
}
}