I'm trying to use the MVVM pattern in my Silverlight 3 application and am having problems getting binding to a command property of a view model working. First off, I'm trying to add an attached property called ClickCommand, like this:
public static class Command
{
public static readonly DependencyProperty ClickCommandProperty =
DependencyProperty.RegisterAttached(
"ClickCommand", typeof(Command<RoutedEventHandler>),
typeof(Command), null);
public static Command<RoutedEventHandler> GetClickCommand(
DependencyObject target)
{
return target.GetValue(ClickCommandProperty)
as Command<RoutedEventHandler>;
}
public static void SetClickCommand(
DependencyObject target, Command<RoutedEventHandler> value)
{
// Breakpoints here are never reached
var btn = target as ButtonBase;
if (btn != null)
{
var oldValue = GetClickCommand(target);
btn.Click -= oldValue.Action;
target.SetValue(ClickCommandProperty, value);
btn.Click += value.Action;
}
}
}
The generic Command class is a wrapper around a delegate. I'm only wrapping a delegate because I wondered if having a delegate type for a property was the reason things weren't working for me originally. Here's that class:
public class Command<T> /* I'm not allowed to constrain T to a delegate type */
{
public Command(T action)
{
this.Action = action;
}
public T Action { get; set; }
}
Here's how I am using the attached property:
<Button u:Command.ClickCommand="{Binding DoThatThing}" Content="New"/>
The syntax seems to be accepted, and I think that when I tested all of this with a string property type, that worked fine. Here's the view model class that is being bound to:
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public Command<RoutedEventHandler> DoThatThing
{
get
{
return new Command<RoutedEventHandler>(
(s, e) => Debug.WriteLine("Never output!"));
}
}
}
The delegate contained in the Command property is never invoked. Also, when I place breakpoints in the getter and setter of the attached property, they are never reached.
In trying to isolate the problem, I changing the property type to string; the breakpoint in the getter and setter was also never reached, yet throwing an exception in them did cause the application to terminate, so I am thinking it's a framework eccentricity.
Why is this stuff not working? I also welcome alternate, hopefully simpler ways to bind event handlers to view models.