DataGridComboBoxColumn中的EventSetter抛出NullReferenceException

时间:2017-02-03 12:10:05

标签: wpf mvvm datagrid

我正在尝试将SelectionChanged绑定到下面代码中的命令。

<EventSetter Event="SelectionChanged" Handler="{Binding MyCommand}" />

但不幸的是,我在InitializeComponent();

获得了NullReferenceException

可能是什么问题?如果我删除上面的单行,该程序将起作用。

<StackPanel>

    <DataGrid ItemsSource="{Binding Items}" 
              AutoGenerateColumns="False">
        <DataGrid.Columns>

            <DataGridTextColumn Header="Name" 
                                Binding="{Binding Name}"/>

            <DataGridComboBoxColumn Header="Color" 
                                    SelectedItemBinding="{Binding Color}">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Colors}"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Colors}"/>

                        <EventSetter Event="SelectionChanged" Handler="{Binding MyCommand}" />


                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>

    <Button Command="{Binding MyCommand}" Width="100" Height="100" Content="Change"/>
</StackPanel>


   public partial class MainWindow : Window
   {
      public MainWindow()
      {
         InitializeComponent();

         this.DataContext = new Data();
      }
   }


   public class Data
   {
      /// <summary>
      /// A collection that stores the data required 
      /// to populate the <seealso cref="DataGrid"/> for sheets in paste window.
      /// </summary>
      private ObservableCollection<Item> _items;
      public ObservableCollection<Item> Items
      {
         get { return _items; }

      }

      private ICommand _myCommand;
      public ICommand MyCommand
      {
         get
         {
            return _myCommand ?? (_myCommand = new CommandHandler(() => Change(), _canExecute));
         }
      }
      private bool _canExecute;

      public Data()
      {
         _canExecute = true;
         _items = new ObservableCollection<Item>();
         _items.Add(new Item("A"));
         _items.Add(new Item("B"));
      }

      public void Change()
      {
         _items[0].Name = "D";
      }
   }

   public class CommandHandler : ICommand
   {
      private Action _action;
      private bool _canExecute;
      public CommandHandler(Action action, bool canExecute)
      {
         _action = action;
         _canExecute = canExecute;
      }

      public bool CanExecute(object parameter)
      {
         return _canExecute;
      }

      public event EventHandler CanExecuteChanged;

      public void Execute(object parameter)
      {
         _action();
      }
   }

   public class Item : INotifyPropertyChanged
   {
      private string _name;
      public string Name
      {
         get { return _name; }
         set
         {
            _name = value;
            RaisePropertyChanged("Name");
         }
      }
      public string Color { get; set; }


      private IList<string> _colors;

      public event PropertyChangedEventHandler PropertyChanged;

      public IList<string> Colors
      {
         get { return _colors; }
      }


      public Item(string name)
      {
         _name = name;
         _colors = new List<string> { "Green", "Blue" };
         Color = _colors[0];
      }

      private void RaisePropertyChanged(string propertyName)
      {
         var handler = PropertyChanged;
         if (handler == null) return;

         handler(this, new PropertyChangedEventArgs(propertyName));
      }
   }

1 个答案:

答案 0 :(得分:1)

EventSetter希望您从代码隐藏文件(xaml.cs)中指示现有事件。它不适用于绑定。因此,在MainWindow.xaml.cs中创建相应的事件处理程序并在EventSetter中指示它或使用Blend中的Interaction.Triggers,MvvmLight

<Window
 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
 xmlns:command="http://www.galasoft.ch/mvvmlight" >
 <i:Interaction.Triggers>
          <i:EventTrigger EventName="Loaded">
            <command:EventToCommand
              Command="{Binding MyCommand}"
              PassEventArgsToCommand="False" />
          </i:EventTrigger>
 </i:Interaction.Triggers>
</Window>