我正在尝试在我的Silverlight 3应用程序中使用MVVM模式,并且在让视图模型的绑定到命令属性时遇到了问题。首先,我尝试添加一个名为ClickCommand的附加属性,如下所示:
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;
}
}
}
通用的Command类是一个代理的包装器。我只是包装了一个代理,因为我想知道一个属性是否有代理类型,这可能是最初导致事情不起作用的原因。以下是该类:
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; }
}
以下是我如何使用附加属性的方法:
这里是我使用附加属性的方式:
<Button u:Command.ClickCommand="{Binding DoThatThing}" Content="New"/>
这个语法似乎被接受了,我认为当我用字符串属性类型测试所有内容时,一切都很好。这是要绑定的视图模型类:
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public Command<RoutedEventHandler> DoThatThing
{
get
{
return new Command<RoutedEventHandler>(
(s, e) => Debug.WriteLine("Never output!"));
}
}
}
Command属性中包含的委托从未被调用。此外,当我在附加属性的Getter和Setter中放置断点时,它们从未到达。
为了分离问题,我将属性类型更改为字符串;获取器和设置器中的断点也从未到达,但在其中抛出异常确实导致应用程序终止,因此我认为这是框架的特异性。
为什么这些东西不起作用?我也欢迎替代方法,希望能更简单地将事件处理程序绑定到视图模型。
RoutedEventCommand
类,并将Command<RoutedEventHandler>
的实例替换为它,但行为是相同的。 - Jacob