If you want to bind Silverlight controls which does not implement the ICommand interface to an ICommand method of your viewmodel, you can use System.Windows.Interactivity with the following pattern. In this sample I have implemented a SaveCommand at the LostFocus-Event of a TextBox.
XAML
1: <TextBox
2: Text="{Binding Name, Converter={StaticResource UpperCaseConverter}, Mode=TwoWay}"
3: Grid.Column="0"
4: HorizontalAlignment="Stretch"
5: VerticalAlignment="Center"
6: Width="Auto"
7: FontSize="18"
8: Template="{StaticResource TextBoxFadeOut}">
9: <Interactivity:Interaction.Triggers>
10: <Interactivity:EventTrigger EventName="LostFocus" >
11: <Helpers:InvokeDelegateCommandAction
12: Command="{Binding DataContext.SaveKategorieCommand, ElementName=LayoutRoot}" CommandParameter="{Binding}"/>
13: </Interactivity:EventTrigger>
14: </Interactivity:Interaction.Triggers>
15: </TextBox>
Viewmodel-Command Definition
1: public ICommand SaveKategorieCommand { get; set; }
2:
3: SaveKategorieCommand = new DelegateCommand(SaveKategorie);
Viewmodel-Command Implementation
1: private void SaveKategorie(object param)
2: {
3: if (param != null && param is AnzeigeKategorie)
4: {
5: var anz = param as AnzeigeKategorie;
6: if (anz.HasChanges)
7: {
8: _domainContextSynchronizer.AddSubmitChangesToQueue();
9: }
10: }
11: }
Helper-Method InvokeDelegateCommandAction
1: public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject>
2: {
3: /// <summary>
4: ///
5: /// </summary>
6: public static readonly DependencyProperty CommandParameterProperty =
7: DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);
8:
9: /// <summary>
10: ///
11: /// </summary>
12: public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
13: "Command", typeof(ICommand), typeof(InvokeDelegateCommandAction), null);
14:
15: /// <summary>
16: ///
17: /// </summary>
18: public static readonly DependencyProperty InvokeParameterProperty = DependencyProperty.Register(
19: "InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);
20:
21: private string commandName;
22:
23: /// <summary>
24: ///
25: /// </summary>
26: public object InvokeParameter
27: {
28: get
29: {
30: return this.GetValue(InvokeParameterProperty);
31: }
32: set
33: {
34: this.SetValue(InvokeParameterProperty, value);
35: }
36: }
37:
38: /// <summary>
39: ///
40: /// </summary>
41: public ICommand Command
42: {
43: get
44: {
45: return (ICommand)this.GetValue(CommandProperty);
46: }
47: set
48: {
49: this.SetValue(CommandProperty, value);
50: }
51: }
52:
53: /// <summary>
54: ///
55: /// </summary>
56: public string CommandName
57: {
58: get
59: {
60: return this.commandName;
61: }
62: set
63: {
64: if (this.CommandName != value)
65: {
66: this.commandName = value;
67: }
68: }
69: }
70:
71: /// <summary>
72: ///
73: /// </summary>
74: public object CommandParameter
75: {
76: get
77: {
78: return this.GetValue(CommandParameterProperty);
79: }
80: set
81: {
82: this.SetValue(CommandParameterProperty, value);
83: }
84: }
85:
86: /// <summary>
87: ///
88: /// </summary>
89: /// <param name="parameter"></param>
90: protected override void Invoke(object parameter)
91: {
92: this.InvokeParameter = parameter;
93:
94: if (this.AssociatedObject != null)
95: {
96: ICommand command = this.ResolveCommand();
97: if ((command != null) && command.CanExecute(this.CommandParameter))
98: {
99: command.Execute(this.CommandParameter);
100: }
101: }
102: }
103:
104: private ICommand ResolveCommand()
105: {
106: ICommand command = null;
107: if (this.Command != null)
108: {
109: return this.Command;
110: }
111: var frameworkElement = this.AssociatedObject as FrameworkElement;
112: if (frameworkElement != null)
113: {
114: object dataContext = frameworkElement.DataContext;
115: if (dataContext != null)
116: {
117: PropertyInfo commandPropertyInfo = dataContext
118: .GetType()
119: .GetProperties(BindingFlags.Public | BindingFlags.Instance)
120: .FirstOrDefault(
121: p =>
122: typeof(ICommand).IsAssignableFrom(p.PropertyType) &&
123: string.Equals(p.Name, this.CommandName, StringComparison.Ordinal)
124: );
125:
126: if (commandPropertyInfo != null)
127: {
128: command = (ICommand)commandPropertyInfo.GetValue(dataContext, null);
129: }
130: }
131: }
132: return command;
133: }
134: }
At this way you can bind each event of any Silverlight control to a ICommand.