我有自定义用户控件:
<UserControl Name="ddTextBox" x:Class="UserControlsLibrary.DDTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignWidth="250" FontFamily="Tahoma" FontSize="14" MinHeight="25" Height="275">
<StackPanel>
<TextBox Name="ControlText" Height="25" HorizontalAlignment="Stretch" VerticalAlignment="Top" Text="{Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<ListBox Name="ControlList" VerticalAlignment="Top" MaxHeight="250" HorizontalAlignment="Stretch" Visibility="Collapsed" ItemsSource="{Binding Path=DList, UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</UserControl>
后面的代码:
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace UserControlsLibrary
{
public partial class DDTextBox : UserControl, INotifyPropertyChanged
{
private string _text;
public string Text { get => _text ?? string.Empty; set { _text = value; OnPropertyChanged(); } }
public DDTextBox()
{
InitializeComponent();
ControlText.DataContext = this;
ControlList.DataContext = this;
ControlText.TextChanged += TextChanged;
ControlText.GotKeyboardFocus += KeyboardFocusChanged;
ControlText.LostKeyboardFocus += KeyboardFocusChanged;
ControlList.SelectionChanged += SelectionChanged;
ControlList.GotKeyboardFocus += KeyboardFocusChanged;
ControlList.LostKeyboardFocus += KeyboardFocusChanged;
IsKeyboardFocusWithinChanged += DDTextBox_IsKeyboardFocusWithinChanged;
}
private void TextChanged(object sender, TextChangedEventArgs e)
{ DItemsSource = ItemsSource.Cast<string>().ToList().FindAll(r => r.IndexOf(( (TextBox)sender ).Text, StringComparison.OrdinalIgnoreCase) >= 0); }
private void SelectionChanged(object sender, SelectionChangedEventArgs e)
{ Text = ( e.AddedItems.Count > 0 ) ? e.AddedItems[0].ToString() : string.Empty; ( (ListBox)sender ).Visibility = Visibility.Collapsed; }
private void KeyboardFocusChanged(object sender, KeyboardFocusChangedEventArgs e)
{
ControlList.Visibility = ( e.NewFocus == ControlList || e.NewFocus == ControlText ) ? Visibility.Visible : Visibility.Collapsed;
if ( e.OldFocus?.GetType() == typeof(ListBox) ) ( (ListBox)e.OldFocus ).SelectedIndex = -1;
}
private void DDTextBox_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ( (bool)e.OldValue == true && (bool)e.NewValue == false )
{ RaiseEvent(new RoutedEventArgs(UserControlLostFocusEvent, this)); }
}
private void ControlLostFocus(object sender, RoutedEventArgs e)
{ if ( !ControlList.IsFocused && !ControlText.IsFocused ) { ControlList.Visibility = Visibility.Collapsed; ControlList.SelectedIndex = -1; } }
public event RoutedEventHandler UserControlLostFocus
{
add { AddHandler(UserControlLostFocusEvent, value); }
remove { RemoveHandler(UserControlLostFocusEvent, value); }
}
public IEnumerable ItemsSource
{
private get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); SetValue(DItemsSourceProperty, value); }
}
/// <summary>
/// Dynamically generated ItemsSource based on Text property. Changes made to this may be lost. List changes should be made to the ItemsSource.
/// </summary>
public IEnumerable DItemsSource
{
private get { return (IEnumerable)GetValue(DItemsSourceProperty); }
set { SetValue(DItemsSourceProperty, value); }
}
public static DependencyProperty DItemsSourceProperty => dItemsSourceProperty;
public static DependencyProperty ItemsSourceProperty => itemsSourceProperty;
public static RoutedEvent UserControlLostFocusEvent => userControlLostFocusEvent;
private static readonly DependencyProperty itemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(DDTextBox), new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));
private static readonly DependencyProperty dItemsSourceProperty = DependencyProperty.Register("DItemsSource", typeof(IEnumerable), typeof(DDTextBox), new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));
private static readonly RoutedEvent userControlLostFocusEvent = EventManager.RegisterRoutedEvent("UserControlLostFocus", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DDTextBox));
private static void OnItemsSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{ if ( sender is DDTextBox control ) control.OnItemsSourceChanged((IEnumerable)e.NewValue, (IEnumerable)e.OldValue); }
private void OnItemsSourceChanged(IEnumerable newValue, IEnumerable oldValue)
{
if ( oldValue is INotifyCollectionChanged oldValueINotifyCollectionChanged )
{ oldValueINotifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(NewValueINotifyCollectionChanged_CollectionChanged); }
if ( newValue is INotifyCollectionChanged newValueINotifyCollectionChanged )
{ newValueINotifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(NewValueINotifyCollectionChanged_CollectionChanged); }
}
void NewValueINotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string Name = "")
{ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(Name)); }
}
}
在我的主项目中引用并添加到主窗口:
<Window Name="Main" x:Class="POSystem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myCtrls="clr-namespace:UserControlsLibrary;assembly=UserControlsLibrary"
Title="Purchase Order" Height="850" Width="1100" Background="#FFD8D0A9">
<Grid Name="TheGrid" Focusable="True" MouseDown="ClearFocus_OnClick" Background="Transparent">
<myCtrls:DDTextBox x:Name="ItemsBox" Width="300" VerticalAlignment="Top" HorizontalAlignment="Left" Panel.ZIndex="1"/>
</Grid>
</Window>
在运行时,所有内容都会显示并按原样运行,但是,在主页面的窗口设计器中,除了指示控件在那里的轮廓之外,它不会显示任何内容。此轮廓可以从该位置的单个行(仅所有功能正常工作)或如果我添加最小或仅直线高度,它显示控件的空轮廓。如何在主窗口设计器的用户控件中显示(应该是)可见的文本框?