Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF命令参数绑定问题_Wpf_Commandbinding - Fatal编程技术网

WPF命令参数绑定问题

WPF命令参数绑定问题,wpf,commandbinding,Wpf,Commandbinding,我在理解命令参数绑定如何工作时遇到了一些问题 在调用InitializeComponent之前创建widget类的实例时,它似乎工作正常。ExecuteCommand函数中对参数(小部件)的修改将“应用”到_小部件。这是我所期望的行为 如果_小部件的实例是在InitializeComponent之后创建的,那么在ExecuteCommand函数中,e.参数会出现空引用异常 为什么会这样?如何使用MVP模式实现这一点,在MVP模式中,绑定对象可能在创建视图后创建 public partial cl

我在理解命令参数绑定如何工作时遇到了一些问题

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

如果_小部件的实例是在InitializeComponent之后创建的,那么在ExecuteCommand函数中,e.参数会出现空引用异常

为什么会这样?如何使用MVP模式实现这一点,在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++;
    }
}
公共部分类WidgetView:窗口
{
RoutedCommand_doSomethingCommand=新RoutedCommand();
widgetu Widget;
公共WidgetView()
{
_widget=newwidget();
初始化组件();
添加(新的CommandBinding(DoSomethingCommand、ExecuteCommand、CanExecuteCommand));
}
公共小部件TestWidget
{
获取{return\u widget;}
设置{u widget=value;}
}
公共路由命令DoSomethingCommand
{
获取{return\u doSomethingCommand;}
}
私有静态void CanExecuteCommand(对象发送方,CanExecuteRoutedEventArgs e)
{
如果(e.Parameter==null)
e、 CanExecute=true;
其他的
{
e、 CanExecute=((小部件)e.Parameter).Count<2;
}
}
私有静态void ExecuteCommand(对象发送方,ExecutedRoutedEventArgs e)
{
((Widget)e.Parameter).DoSomething();
}
}
做点什么
公共类小部件
{
公共整数计数=0;
公共无效剂量测定法()
{
计数++;
}
}

InitializeCompent处理与文件关联的xaml。正是在这个时间点上,CommandParameter绑定第一次被处理。如果在InitializeComponent之前初始化字段,则属性将不为null。如果在之后创建它,则它为空

如果要在InitializeComponent之后创建小部件,则需要使用依赖项属性。dependency项目将引发一个通知,该通知将导致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); }
}

即使使用dependency属性,您仍然需要调用CommandManager.InvalidateRequestSuggested以强制执行正在计算的命令