2010-03-02 37 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); } 
}