Out of the box the Patterns and Practices PRISM code only supports the click event handler. Writing additional handlers really is very easy. Firstly there are two great starter blogs which I’m not going to recreate:
How Commanding Works in Prism and MVVM by Erik Mork and A code snippet to quickly write Prism commands by Andrea Boschin
Following these patterns it was a sinch to create the code that can be used as a TextChanged command handler:
1: public class TextChangedCommandBehavior : CommandBehaviorBase2: {3: public TextChangedCommandBehavior(TextBox targetObject)4: : base(targetObject)5: {6: targetObject.TextChanged += (s, e) => base.ExecuteCommand();7: }8: }9:10: public static class TextChanged11: {12: public static readonly DependencyProperty TextChangedBehaviorProperty =13: DependencyProperty.RegisterAttached(14: "TextChangedBehavior", typeof(TextChangedCommandBehavior),15: typeof(TextChangedCommandBehavior), null);16:17: #region CommandProperty18:19: public static readonly DependencyProperty CommandProperty =20: DependencyProperty.RegisterAttached(21: "Command", typeof(ICommand), typeof(TextChanged),22: new PropertyMetadata(CommandProperty_Changed));23:24: public static ICommand GetCommand(DependencyObject obj)25: {26: return (ICommand)obj.GetValue(CommandProperty);27: }28:29: public static void SetCommand(DependencyObject obj, ICommand value)30: {31: obj.SetValue(CommandProperty, value);32: }33:34: private static void CommandProperty_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)35: {36: TextBox targetObject = dependencyObject as TextBox;37:38: if (targetObject != null)39: GetOrCreateBehavior(targetObject).Command = e.NewValue as ICommand;40: }41:42: #endregion43:44: #region CommandParameterProperty45:46: public static readonly DependencyProperty CommandParameterProperty =47: DependencyProperty.RegisterAttached(48: "CommandParameter", typeof(object),49: typeof(TextChanged), new PropertyMetadata(CommandParameterProperty_Changed));50:51: public static ICommand GetCommandParameter(DependencyObject obj)52: {53: return (ICommand)obj.GetValue(CommandParameterProperty);54: }55:56: public static void SetCommandParameter(DependencyObject obj, ICommand value)57: {58: obj.SetValue(CommandParameterProperty, value);59: }60:61: private static void CommandParameterProperty_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)62: {63: TextBox targetObject = dependencyObject as TextBox;64:65: if (targetObject != null)66: GetOrCreateBehavior(targetObject).CommandParameter = e.NewValue;67: }68:69: #endregion70:71: private static TextChangedCommandBehavior GetOrCreateBehavior(TextBox targetObject)72: {73: TextChangedCommandBehavior behavior = targetObject.GetValue(TextChangedBehaviorProperty) as TextChangedCommandBehavior;74:75: if (behavior == null)76: {77: behavior = new TextChangedCommandBehavior(targetObject);78: targetObject.SetValue(TextChangedBehaviorProperty, behavior);79: }80:81: return behavior;82: }83: }
Sorry, code doesn't work!
The error message is:
A 'Binding' cannot be set on the 'SetCommand' property of type 'TextBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Hi Manullino,
Sorry, I think I posted the wrong name on the dependency property:
public static readonly DependencyProperty TextChangedBehaviorProperty = DependencyProperty.RegisterAttached(“TextChangedBehaviorProperty”, typeof(TextChangedCommandBehavior), typeof(TextChangedCommandBehavior), null);
This should be:
public static readonly DependencyProperty TextChangedBehaviorProperty = DependencyProperty.RegisterAttached(“TextChangedBehavior“, typeof(TextChangedCommandBehavior), typeof(TextChangedCommandBehavior), null);
I have fixed this above too. Thanks for the note, hope this helps further,
Mark
Hi
The event seems to be firing before the binding to text path for the same control can be passed as the parameter. here is the xaml I am using:
When I break on the TextBoxTextChanged event, the parameter passed is a string prior to the text entered, ie if I type in “Wor” then add a “d” to make “Word” the string parameter is string only “Wor” instead of “Word”.
Is there anything that I am missing?
Sorry, the above code did not post for some reason
Commands:TextBoxTextChanged.CommandParameter=”{Binding ElementName=txtUserName, Path=Text}”
Commands:TextBoxTextChanged.Command=”{Binding TextBoxTextChanged}”>
I got the same problem as Nick.
============================
When I break on the TextBoxTextChanged event, the parameter passed is a string prior to the text entered, ie if I type in “Wor” then add a “d” to make “Word” the string parameter is string only “Wor” instead of “Word”.
============================
I found that the behavior is invoke the Command before getting the CommandParameter and this is a reason of the above problem.
I'm finding why it occurred this way….