我认为这可能可以通过附加属性(行为)来完成,但是简单地继承TextBox
并覆盖OnTextChanged
、OnKeyDown
和OnKeyUp
类似方法来添加自定义功能会更简单、更直接。
您为什么不想以这种方式创建自己的控件?
更新:附加行为
如果您真的不想要派生控件,请使用以下附加行为来完成此操作(以下说明):
public class ScanReading
{
private static readonly IDictionary<TextBox, ScanInfo> TrackedTextBoxes = new Dictionary<TextBox, ScanInfo>();
public static readonly DependencyProperty ScanCompletedCommandProperty =
DependencyProperty.RegisterAttached("ScanCompletedCommand", typeof (ICommand), typeof (ScanReading),
new PropertyMetadata(default(ICommand), OnScanCompletedCommandChanged));
public static void SetScanCompletedCommand(TextBox textBox, ICommand value)
{
textBox.SetValue(ScanCompletedCommandProperty, value);
}
public static ICommand GetScanCompletedCommand(TextBox textBox)
{
return (ICommand) textBox.GetValue(ScanCompletedCommandProperty);
}
private static void OnScanCompletedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBox = d as TextBox;
if (textBox == null)
return;
var command = (ICommand) e.NewValue;
if (command == null)
{
textBox.Unloaded -= OnTextBoxUnloaded;
textBox.KeyUp -= OnTextBoxKeyUp;
TrackedTextBoxes.Remove(textBox);
}
else
{
textBox.Unloaded += OnTextBoxUnloaded;
TrackedTextBoxes.Add(textBox, new ScanInfo(command));
textBox.KeyUp += OnTextBoxKeyUp;
}
}
static void OnTextBoxKeyUp(object sender, KeyEventArgs e)
{
var textBox = (TextBox) sender;
var scanInfo = TrackedTextBoxes[textBox];
if (scanInfo.IsTracking)
{
if (e.Key == Key.Return)
{
scanInfo.ScanCompletedCommand.Execute(textBox.Text);
scanInfo.IsTracking = false;
}
}
else if (string.IsNullOrEmpty(textBox.Text) && e.Key == Key.Pause)
{
TrackedTextBoxes[textBox].IsTracking = true;
}
}
static void OnTextBoxUnloaded(object sender, RoutedEventArgs e)
{
var textBox = (TextBox) sender;
textBox.KeyUp -= OnTextBoxKeyUp;
textBox.Unloaded -= OnTextBoxUnloaded;
TrackedTextBoxes.Remove(textBox);
}
}
public class ScanInfo
{
public ScanInfo(ICommand scanCompletedCommand)
{
ScanCompletedCommand = scanCompletedCommand;
}
public bool IsTracking { get; set; }
public ICommand ScanCompletedCommand { get; private set; }
}
通过声明TextBox
这样的方式来使用它(local
您的附加属性的命名空间在哪里,并且ScanCompleted
在ICommand
您的视图模型上):
<TextBox local:ScanReading.ScanCompletedCommand="{Binding ScanCompleted}" />
现在,当设置此属性时,我们将TextBox
与关联的 一起添加到静态集合中ICommand
。
每次按下一个键,我们检查它是否是Pause键。如果是,并且如果TextBox
是空的,我们设置一个标志true
来开始寻找Enter密钥。
现在每次按下一个键,我们检查它是否是Enter键。如果是,我们执行命令,传入TextBox.Text
值,并将标志重置false
为TextBox
.
我们还为事件添加了一个处理程序TextBox.Unloaded
来清理我们的事件订阅并TextBox
从静态列表中删除。