WPF CommandParameter绑定问题

时间:2008-11-02 21:21:20

标签: wpf commandbinding

我在理解命令参数绑定的工作原理时遇到了一些麻烦。

当我在调用InitializeComponent之前创建widget类的实例时,它似乎工作正常。对ExecuteCommand函数中的参数(Widget)的修改将“应用”到_widget。这是我预期的行为。

如果在InitializeComponent之后创建_widget实例,我会在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++;
    }
}

2 个答案:

答案 0 :(得分:4)

InitializeCompenent处理与文件关联的xaml。此时,首先处理CommandParameter绑定。如果在InitializeCompenent之前初始化字段,那么您的属性将不为null。如果在之后创建它,则为null。

如果要在InitializeCompenent之后创建窗口小部件,则需要使用依赖项属性。依赖项proeprty将引发一个通知,该通知将导致CommandParameter被更新,因此它不会为null。

以下是如何使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); }
}

答案 1 :(得分:0)

即使使用依赖项属性,仍然需要调用CommandManager.InvalidateRequerySuggested来强制执行正在评估的Command的CanExecute。