2008-11-02 47 views
5

我在理解命令參數綁定的工作原理時遇到了一些麻煩。WPF CommandParameter綁定問題

當我在調用InitializeComponent之前創建一個widget類的實例時,它似乎工作正常。對ExecuteCommand函數中參數(Widget)的修改將被「應用」到_widget。這是我期望的行爲。

如果_widget的實例是在InitializeComponent之後創建的,那麼我會在ExecuteCommand函數中獲得e.Parameter的空引用異常。

這是爲什麼?如何使用MVP模式進行這項工作,在創建視圖之後綁定對象可能會創建?

public partial class WidgetView : Window 
{ 
    RoutedCommand _doSomethingCommand = new RoutedCommand(); 

    Widget _widget; 

    public WidgetView() 
    { 
     _widget = new Widget(); 
     InitializeComponent(); 
     this.CommandBindings.Add(new CommandBinding(DoSomethingCommand, ExecuteCommand, CanExecuteCommand)); 
    } 

    public Widget TestWidget 
    { 
     get { return _widget; } 
     set { _widget = value; } 
    } 

    public RoutedCommand DoSomethingCommand 
    { 
     get { return _doSomethingCommand; } 
    } 

    private static void CanExecuteCommand(object sender, CanExecuteRoutedEventArgs e) 
    { 
     if (e.Parameter == null) 
      e.CanExecute = true; 
     else 
     { 
      e.CanExecute = ((Widget)e.Parameter).Count < 2; 
     } 
    } 

    private static void ExecuteCommand(object sender, ExecutedRoutedEventArgs e) 
    { 
     ((Widget)e.Parameter).DoSomething(); 
    } 
} 



<Window x:Class="CommandParameterTest.WidgetView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="WidgetView" Height="300" Width="300" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <StackPanel> 
     <Button Name="_Button" Command="{Binding DoSomethingCommand}" 
      CommandParameter="{Binding TestWidget}">Do Something</Button> 
    </StackPanel> 
</Window> 


public class Widget 
{ 
    public int Count = 0; 
    public void DoSomething() 
    { 
     Count++; 
    } 
} 

回答

4

InitializeCompenent處理與該文件關聯的xaml。正是在這個時候,CommandParameter綁定首先被處理。如果您在InitializeCompenent之前初始化您的字段,那麼您的屬性不會爲空。如果你在創建它之後它是空的。

如果你想在InitializeCompenent之後創建widget,那麼你將需要使用一個依賴屬性。依賴項proeprty會引發一個通知,導致CommandParameter被更新,因此它不會爲空。

以下是如何使TestWidget成爲依賴項屬性的示例。

public static readonly DependencyProperty TestWidgetProperty = 
    DependencyProperty.Register("TestWidget", typeof(Widget), typeof(Window1), new UIPropertyMetadata(null)); 
public Widget TestWidget 
{ 
    get { return (Widget) GetValue(TestWidgetProperty); } 
    set { SetValue(TestWidgetProperty, value); } 
} 
0

即使依賴屬性,你仍然需要調用CommandManager.InvalidateRequerySuggested強制命令的CanExecute被評估。