WPF反向绑定OneWayToSource

时间:2010-03-02 17:23:14

标签: c# wpf xaml data-binding mvvm

我有一个自定义控件,它具有以下依赖属性

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,以便我可以访问该属性并调用Print Command。

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

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

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

2 个答案:

答案 0 :(得分:0)

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

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

view.Print()

如果要更改打印命令,则需要显示如下所示的属性。在这种情况下,您的视图模型将调用

view.PrintCommand.Execute()

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

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

请注意,CommandBinding是一个与Binding完全不同的对象。不要混淆两者。 CommandBinding用于处理路由命令。 Binding用于更新属性值。

答案 1 :(得分:0)

您使用命令绑定的方式与它们在MVVM中使用的正常方式相反。通常,您会在VM中声明DelegateCommand,这会根据UI操作(如按钮单击)在VM中执行某些操作。由于您正在寻找相反的路径,因此您可能最好使用源自VM的事件,然后由ExportPrintGridControl处理。根据关系的设置方式,您可以在VM实例声明中声明XAML中的事件处理程序(在您的情况下看起来不像它),或者在您的控制代码中只需抓取DataContext并进行转换它是您的VM或(更好)包含要订阅的事件的接口。

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); }
}
相关问题