Если вы не хотите добавлять какой-либо код в файл кода XAML и сохраняете свой дизайн чистым с точки зрения архитектуры MVVM, вы можете использовать следующий подход.В вашем XAML определите свою команду в связывании следующим образом:
<TextBox
Text="{Binding Text}"
custom:KeyUp.Command="{Binding Path=DataContext.DoCommand, ElementName=root}" />
, где KeyUp class:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace PhoneGuitarTab.Controls
{
public static class KeyUp
{
private static readonly DependencyProperty KeyUpCommandBehaviorProperty = DependencyProperty.RegisterAttached(
"KeyUpCommandBehavior",
typeof(TextBoxCommandBehavior),
typeof(KeyUp),
null);
///
/// Command to execute on KeyUp event.
///
public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(KeyUp),
new PropertyMetadata(OnSetCommandCallback));
///
/// Command parameter to supply on command execution.
///
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(KeyUp),
new PropertyMetadata(OnSetCommandParameterCallback));
///
/// Sets the to execute on the KeyUp event.
///
/// TextBox dependency object to attach command
/// Command to attach
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for buttonbase")]
public static void SetCommand(TextBox textBox, ICommand command)
{
textBox.SetValue(CommandProperty, command);
}
///
/// Retrieves the attached to the .
///
/// TextBox containing the Command dependency property
/// The value of the command attached
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for buttonbase")]
public static ICommand GetCommand(TextBox textBox)
{
return textBox.GetValue(CommandProperty) as ICommand;
}
///
/// Sets the value for the CommandParameter attached property on the provided .
///
/// TextBox to attach CommandParameter
/// Parameter value to attach
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for buttonbase")]
public static void SetCommandParameter(TextBox textBox, object parameter)
{
textBox.SetValue(CommandParameterProperty, parameter);
}
///
/// Gets the value in CommandParameter attached property on the provided
///
/// TextBox that has the CommandParameter
/// The value of the property
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Only works for buttonbase")]
public static object GetCommandParameter(TextBox textBox)
{
return textBox.GetValue(CommandParameterProperty);
}
private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = dependencyObject as TextBox;
if (textBox != null)
{
TextBoxCommandBehavior behavior = GetOrCreateBehavior(textBox);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = dependencyObject as TextBox;
if (textBox != null)
{
TextBoxCommandBehavior behavior = GetOrCreateBehavior(textBox);
behavior.CommandParameter = e.NewValue;
}
}
private static TextBoxCommandBehavior GetOrCreateBehavior(TextBox textBox)
{
TextBoxCommandBehavior behavior = textBox.GetValue(KeyUpCommandBehaviorProperty) as TextBoxCommandBehavior;
if (behavior == null)
{
behavior = new TextBoxCommandBehavior(textBox);
textBox.SetValue(KeyUpCommandBehaviorProperty, behavior);
}
return behavior;
}
}
}
В классе используются дополнительные команды, поэтому я также предоставляю их, TextBoxCommandBehavior класс:
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace PhoneGuitarTab.Controls
{
public class TextBoxCommandBehavior : CommandBehaviorBase
{
public TextBoxCommandBehavior(TextBox textBoxObject)
: base(textBoxObject)
{
textBoxObject.KeyUp += (s, e) =>
{
string input = (s as TextBox).Text;
//TODO validate user input here
**//ENTER IS PRESSED!**
if ((e.Key == Key.Enter)
&& (!String.IsNullOrEmpty(input)))
{
this.CommandParameter = input;
ExecuteCommand();
}
};
}
}
}
CommandBehaviorBase класс:
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace PhoneGuitarTab.Controls
{
///
/// Base behavior to handle connecting a to a Command.
///
/// The target object must derive from Control
///
/// CommandBehaviorBase can be used to provide new behaviors similar to .
///
public class CommandBehaviorBase
where T : Control
{
private ICommand command;
private object commandParameter;
private readonly WeakReference targetObject;
private readonly EventHandler commandCanExecuteChangedHandler;
///
/// Constructor specifying the target object.
///
/// The target object the behavior is attached to.
public CommandBehaviorBase(T targetObject)
{
this.targetObject = new WeakReference(targetObject);
this.commandCanExecuteChangedHandler = new EventHandler(this.CommandCanExecuteChanged);
}
///
/// Corresponding command to be execute and monitored for
///
public ICommand Command
{
get { return command; }
set
{
if (this.command != null)
{
this.command.CanExecuteChanged -= this.commandCanExecuteChangedHandler;
}
this.command = value;
if (this.command != null)
{
this.command.CanExecuteChanged += this.commandCanExecuteChangedHandler;
UpdateEnabledState();
}
}
}
///
/// The parameter to supply the command during execution
///
public object CommandParameter
{
get { return this.commandParameter; }
set
{
if (this.commandParameter != value)
{
this.commandParameter = value;
this.UpdateEnabledState();
}
}
}
///
/// Object to which this behavior is attached.
///
protected T TargetObject
{
get
{
return targetObject.Target as T;
}
}
///
/// Updates the target object's IsEnabled property based on the commands ability to execute.
///
protected virtual void UpdateEnabledState()
{
if (TargetObject == null)
{
this.Command = null;
this.CommandParameter = null;
}
else if (this.Command != null)
{
TargetObject.IsEnabled = this.Command.CanExecute(this.CommandParameter);
}
}
private void CommandCanExecuteChanged(object sender, EventArgs e)
{
this.UpdateEnabledState();
}
///
/// Executes the command, if it's set, providing the
///
protected virtual void ExecuteCommand()
{
if (this.Command != null)
{
this.Command.Execute(this.CommandParameter);
}
}
}
}
Рабочий пример вы можете найти в моем проекте с открытым исходным кодом ( PhoneGuitarTab.Controls проект в решении): http://phoneguitartab.codeplex.com