2010-03-02 91 views
2

我有具有以下依赖属性WPF反向绑定OneWayToSource

public static readonly DependencyProperty PrintCommandProperty = DependencyProperty.Register(
     "PrintCommand", 
     typeof(ICommand), 
     typeof(ExportPrintGridControl), 
     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits)); 

public ICommand PrintCommand 
{ 
    get { return (ICommand)GetValue(PrintCommandProperty); } 
    set { throw new Exception("ReadOnly Dependency Property. Use Mode=OneWayToSource"); } 
} 

在我控制的构造,我设置我的属性的默认值的自定义控制:

public MyControl() 
{ 
    this.SetValue(PrintCommandProperty, new DelegateCommand<object>(this.Print)); 
} 

我然后试图将该属性绑定到我的ViewModel,以便我可以访问该属性并调用打印命令。

<controls:MyControl PrintCommand="{Binding PrintCommand, Mode=OneWayToSource}"/> 

但是,在XAML中的绑定会导致属性值设置为null。如果我删除XAML中的绑定,则默认属性值在我的控件的构造函数中正确设置。

让我的ViewModel调用我的控件的Print方法的正确方法是什么?

回答

0

我刚刚重读你的问题,它听起来像你试图从你的视图模型调用视图中的方法。这不是视图模型的用途。

如果这真的是你想要的东西,就没有必要使用命令:你所有的观点需要做的就是调用:

view.Print() 

如果你想改变打印命令,那么你就需要一个属性如图所示。在这种情况下,您的视图模型将调用

view.PrintCommand.Execute() 

在这两种情况下都不需要数据绑定。

更多的WPF-ish方法是为您的控件的CommandBindings集合添加绑定以处理内置的Application.Print命令。然后视图模型可以在需要打印时使用RaiseEvent发送此命令。

请注意,CommandBinding与Binding完全不同。不要混淆两者。 CommandBinding用于处理路由命令。绑定用于更新属性值。

0

你使用命令绑定的方式是从它们在MVVM中使用的正常方式开始的。通常情况下,你会在虚拟机中声明一个DelegateCommand,这将根据UI操作(如点击按钮)在VM中执行一些操作。由于您正在寻找相反的路径,因此使用源自虚拟机的事件可能会更好,然后由ExportPrintGridControl来处理。根据设置关系的方式,您可以在VM实例声明中的XAML中声明事件处理程序(看起来不像您的情况)或在您的控制代码中,只需抓住DataContext并将其转换为虚拟机或(更好)包含要订阅的事件的界面。

p.s.您的DependencyProperty目前已设置好,以便您班级的任何内容都可以通过拨打SetValue(如所有XAML)进行设置。我明白了为什么你设置了这种方式来尝试将它用作只能绑定的绑定,但是当你真的需要时,这种方式可以更好地实现只读:

private static readonly DependencyPropertyKey PrintCommandPropertyKey = DependencyProperty.RegisterReadOnly(
    "PrintCommand", 
    typeof(ICommand), 
    typeof(ExportPrintGridControl), 
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits)); 

public static readonly DependencyProperty PrintCommandProperty = PrintCommandPropertyKey.DependencyProperty; 

public ICommand PrintCommand 
{ 
    get { return (ICommand)GetValue(PrintCommandProperty); } 
    private set { SetValue(PrintCommandPropertyKey, value); } 
}