ItemTemplate中的CheckBox导致命令绑定的NullReferenceException

时间:2011-03-16 17:13:45

标签: c# .net wpf

以下是一个简单的示例应用。 ItemTemplate中的复选框具有命令绑定,这似乎是导致问题的原因。当我尝试运行它时,我得到一个NullReferenceException(在Microsoft.Practices.Composite.Presentation.Commands.DelegateCommand`1.System.Windows.Input.ICommand.CanExecute ...)。为什么会这样?

MainWindow.xaml:

<Window x:Class="CheckBoxCommandTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <StackPanel x:Name="stackPanel">
      <ItemsControl ItemsSource="{Binding CheckBoxes}">
          <ItemsControl.ItemTemplate>
              <DataTemplate>
                  <CheckBox Content="{Binding Name}" 
                            IsChecked="{Binding IsSelected}"
                            Command="{Binding DataContext.CheckBoxCommand, ElementName=stackPanel}"
                            CommandParameter="{Binding Parameter}" />
              </DataTemplate>
          </ItemsControl.ItemTemplate>
      </ItemsControl>
  </StackPanel>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        CheckBoxCommand = new DelegateCommand<int>(OnCheckBoxChecked);

        CheckBoxes = new List<CheckBoxModel>()
                         {
                             new CheckBoxModel { Name = "Checkbox #1", Parameter = 1 },
                             new CheckBoxModel { Name = "Checkbox #2", Parameter = 2 },
                         };
        TriggerPropertyChanged("CheckBoxes");
    }

    public List<CheckBoxModel> CheckBoxes { get; set; }

    public ICommand CheckBoxCommand { get; set; }

    private void OnCheckBoxChecked(int i) { /* Do nothing */ }
}

CheckBoxModel.cs

public class CheckBoxModel
{
    public string Name { get; set; }
    public bool IsSelected { get; set; }
    public int Parameter { get; set; }
}

2 个答案:

答案 0 :(得分:2)

这很有可能发生,因为您正在为命令参数使用值类型,以及参数的绑定。首次加载模板时,Bindings尚未进行评估,因此CommandParameter属性(类型object)最初(并且仅暂时)分配了null值。当它被绑定时(在这种情况下恰好在CommandParameter之前),DelegateCommand然后尝试将null参数用作int,这在参数是引用类型时通常很好,但对于像{这样的值类型显然是无效的{1}}。

您可以通过将参数类型更改为int并在命令处理程序中检查HasValue来修复错误。

答案 1 :(得分:0)

当我这样做时,我总是使用CanExecute方法来确定命令是否被允许执行,也许是必需的,但不能说但是没有进一步研究,但尝试添加类似的东西:

private bool CanExecuteOnCheckBoxChecked(int notUsed) { 返回true; }

将您的代表更改为:

CheckBoxCommand = new DelegateCommand(OnCheckBoxChecked,CanExecuteOnCheckBoxChecked);

in private void OnCheckBoxChecked 放:

如果

(CanExecuteOnCheckBoxChecked(I) { // 做任何你想做的事 }