EventSetter in DataGridComboBoxColumn throws NullReferenceException

佐手、 提交于 2021-02-16 23:35:11

问题


I'm trying to bind the SelectionChanged to a command in the code below.

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

But unfortunately I'm gettin an NullReferenceException at InitializeComponent();

What can be the problem? The program works if I remove the above single line.

<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:


EventSetter expects from you to indicate existing event from codebehind file (xaml.cs). It doesn't work with bindings. So create corresponding event handler inside MainWindow.xaml.cs and indicate it in EventSetter or use Interaction.Triggers from Blend, 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>


来源:https://stackoverflow.com/questions/42023994/eventsetter-in-datagridcomboboxcolumn-throws-nullreferenceexception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!