2011-03-16 3 views
1

Ci-dessous un exemple d'application simple. La case à cocher dans le ItemTemplate a une commande de liaison qui semble être à l'origine du problème. Lorsque j'essaie de l'exécuter, j'obtiens une exception NullReferenceException (à Microsoft.Practices.Composite.Presentation.Commands.DelegateCommand`1.System.Windows.Input.ICommand.CanExecute ...). Pourquoi cela arrive-t-il?CheckBox dans ItemTemplate provoque NullReferenceException pour la liaison de commande

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; } 
} 

Répondre

2

Cela se passe très probablement parce que vous utilisez une valeur Lorsque le modèle est chargé pour la première fois, les liaisons n'ont pas encore été évaluées, de sorte que la propriété CommandParameter (de type object) est initialement (et seulement temporairement) affectée d'une valeur null. il est lié (dans ce cas juste b avant le CommandParameter), le DelegateCommand essaie ensuite d'utiliser le paramètre null comme int, ce qui est normalement correct lorsque le paramètre est un type de référence mais manifestement invalide pour les types de valeur tels que int.

Vous pouvez corriger l'erreur en modifiant simplement le type de paramètre à int? et en cochant HasValue dans vos gestionnaires de commandes.

+0

Ça l'a fait! Merci! –

0

Quand je l'ai fait, je toujours utiliser une méthode de CanExecute pour déterminer si la commande est autorisée à s'exécuter, peut-être son requis, ne pourrait pas dire si sans regarder plus mais essayez un dd quelque chose comme:

privé bool CanExecuteOnCheckBoxChecked (int notsed) { return true; }

Modifier votre délégué:

CheckBoxCommand = new DelegateCommand (OnCheckBoxChecked, CanExecuteOnCheckBoxChecked);

private void dans OnCheckBoxChecked put:

si (CanExecuteOnCheckBoxChecked (i) { // Faites ce que vous voulez faire }

+0

Merci, mais non, ce n'est pas que CanExecute est requis. Ça échoue quand même. –

Questions connexes