Si vous ne voulez pas ajouter de code dans le fichier de code de votre XAML et garder votre conception propre du point de vue de l'architecture MVVM, vous pouvez utiliser l'approche suivante. Dans votre XAML, définissez votre commande en binding comme ceci :
<TextBox
Text="{Binding Text}"
custom:KeyUp.Command="{Binding Path=DataContext.DoCommand, ElementName=root}" />
où KeyUp classe :
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;
}
}
}
La classe en utilise d'autres, alors je les fournis aussi. TextBoxCommandBehavior classe :
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 classe :
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);
}
}
}
}
Vous pouvez trouver l'exemple fonctionnel sur mon projet open source ( PhoneGuitarTab.Controls projet en solution) : http://phoneguitartab.codeplex.com