我之前使用 WPF Popup 控件结合文本框编写了“自动完成”样式控件。如果您使用 Popup,它应该像您所说的那样出现在其他所有内容之上的图层中。只需使用 Placement of Bottom 将其与文本框的底部对齐。
这是我不久前写的一个例子。基本上它是一个文本框,当您键入时会弹出一个建议弹出窗口,并且当您键入更多时,它会细化选项。如果您愿意,您可以很容易地更改它以支持多字自动完成样式代码编辑情况:
XAML:
<Grid>
<TextBox x:Name="textBox"
Text="{Binding Text, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IntelliSenseUserControl}}}"
KeyUp="textBox_KeyUp"/>
<Popup x:Name="popup"
Placement="Bottom"
PlacementTarget="{Binding ElementName=textBox}"
IsOpen="False"
Width="200"
Height="300">
<ListView x:Name="listView"
ItemsSource="{Binding FilteredItemsSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:IntelliSenseUserControl}}}"
SelectionChanged="ListView_Selected"/>
</Popup>
</Grid>
代码隐藏:
public partial class IntelliSenseUserControl : UserControl, INotifyPropertyChanged
{
public IntelliSenseUserControl()
{
InitializeComponent();
DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(ItemsSourceProperty, typeof(IntelliSenseUserControl));
prop.AddValueChanged(this, ItemsSourceChanged);
}
private void ItemsSourceChanged(object sender, EventArgs e)
{
FilteredItemsSource = new ListCollectionView((IList)ItemsSource);
FilteredItemsSource.Filter = (arg) => { return arg == null || string.IsNullOrEmpty(textBox.Text) || arg.ToString().Contains(textBox.Text.Trim()); };
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(IntelliSenseUserControl), new FrameworkPropertyMetadata(null) { BindsTwoWayByDefault = true });
public object ItemsSource
{
get { return (object)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(object), typeof(IntelliSenseUserControl), new PropertyMetadata(null));
#region Notified Property - FilteredItemsSource (ListCollectionView)
public ListCollectionView FilteredItemsSource
{
get { return filteredItemsSource; }
set { filteredItemsSource = value; RaisePropertyChanged("FilteredItemsSource"); }
}
private ListCollectionView filteredItemsSource;
#endregion
private void textBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return || e.Key == Key.Enter)
{
popup.IsOpen = false;
}
else
{
popup.IsOpen = true;
FilteredItemsSource.Refresh();
}
}
private void UserControl_LostFocus(object sender, RoutedEventArgs e)
{
popup.IsOpen = false;
}
private void ListView_Selected(object sender, RoutedEventArgs e)
{
if (listView.SelectedItem != null)
{
Text = listView.SelectedItem.ToString().Trim();
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}