【发布时间】:2010-02-20 19:09:38
【问题描述】:
我正在尝试在我的 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 中放置断点时,它们永远不会到达。
在尝试隔离问题时,我将属性类型更改为字符串; getter 和 setter 中的断点也从未到达,但在其中抛出异常确实会导致应用程序终止,所以我认为这是框架的怪癖。
为什么这些东西不起作用?我也欢迎将事件处理程序绑定到视图模型的替代方法,希望是更简单的方法。
【问题讨论】:
-
有趣。您是否尝试过使用非通用版本?
-
好主意。但是,我刚刚尝试创建一个
RoutedEventCommand类并用它替换Command<RoutedEventHandler>的实例,并且行为是相同的。
标签: c# data-binding silverlight-3.0 mvvm delegates