CheckBox in ItemTemplate causes NullReferenceException for Command binding
Belo开发者_如何学运维w is a simple sample app. The checkbox in the ItemTemplate has a command binding which seems to be what is causing the problem. When I try to run it I get a NullReferenceException ( at Microsoft.Practices.Composite.Presentation.Commands.DelegateCommand`1.System.Windows.Input.ICommand.CanExecute ...). Why does this happen?
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; }
}
This is most likely happening because you're using a value type for your command parameter, along with a Binding for the Parameter. When the template is first loaded, the Bindings haven't evaluated yet so the CommandParameter property (of type object
) is initially (and only temporarily) assigned a null
value. When it is bound (in this case just before the CommandParameter), the DelegateCommand then tries to use the null parameter as an int
, which is normally fine when the parameter is a reference type but obviously invalid for value types like int
.
You may be able to fix the error by just changing the parameter type to int?
and checking HasValue in your command handlers.
When I have done this I always use a CanExecute method to determine if the command is allowed to execute, maybe its required, couldnt say though without looking into it more but try add something like:
private bool CanExecuteOnCheckBoxChecked(int notUsed) { return true; }
Change your delegate to :
CheckBoxCommand = new DelegateCommand(OnCheckBoxChecked,CanExecuteOnCheckBoxChecked);
in private void OnCheckBoxChecked put:
if(CanExecuteOnCheckBoxChecked(i) { // Do whatever you want to do }
精彩评论