nan
nan

Reputation: 585

CellValueChanged event for a DataGrid in WPF?

I have a DataGrid bound to an ObservableCollection of DataRowView. DataGrid.BeginningEdit is called before I start typing. CellEditEnding is called after the focus is lost. I need an event that fires whenever I type on a cell. What should I do?

private static ObservableCollection<DataRowView> _dataGridSrcCollection = new ObservableCollection<DataRowView>();
public static ObservableCollection<DataRowView> DataGridSrcCollection
{
  get
  {
    return _dataGridSrcCollection;
  }
  set
  {
    if (value != _dataGridSrcCollection)
    {
      _dataGridSrcCollection = value;        
    }  
  }
}

I am Binding each column programmatically.

Upvotes: 2

Views: 5772

Answers (2)

Bahman_Aries
Bahman_Aries

Reputation: 4808

I doubt there is any CellValueChanged event for DataGrid however assuming all your data-grid columns are text columns then you can use TextChanged event as follow:

Xaml:

    <DataGrid Grid.Row="0" 
              ItemsSource="{Binding DataGridSrcCollection}" 
              SelectionUnit="Cell"
              SelectionMode="Single" >
        <DataGrid.Columns>
            <DataGridTextColumn  Header="your header" Binding="{Binding Path=YourProperty}" >
                <DataGridTextColumn.EditingElementStyle>
                    <Style TargetType="{x:Type TextBox}">
                        <EventSetter Event="TextChanged" Handler="CellValueChanged" />
                    </Style>
                </DataGridTextColumn.EditingElementStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

Code behind:

    private void CellValueChanged(object sender, TextChangedEventArgs e)
    {
        // your code
    }

Upvotes: 1

almulo
almulo

Reputation: 4978

First of all, since you say you're binding the columns programmatically, you need to add Binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged to those Bindings.

Then, you need to subscribe to the PropertyChanged event of each of the DataRowView objects in your collection. The best way to do this, to avoid loose event handlers, would be in the CollectionChanged event of your ObservableCollection, like this:

private static ObservableCollection<DataRowView> _dataGridSrcCollection = new ObservableCollection<DataRowView>();
public static ObservableCollection<DataRowView> DataGridSrcCollection
{
    get
    {
        return _dataGridSrcCollection;
    }
    set
    {
        if (value != _dataGridSrcCollection)
        {
            if (_dataGridScrCollection != null)
            {
                _dataGridScrCollection.CollectionChanged -= DataGridScrCollection_CollectionChanged;

                foreach (var row in _dataGridScrCollection)
                    row.PropertyChanged -= DataRowView_PropertyChanged;
            }

            if (value != null)
            {
                value.CollectionChanged += DataGridScrCollection_CollectionChanged;

                foreach (var row in value)
                    row.PropertyChanged += DataRowView_PropertyChanged;
            }

            _dataGridSrcCollection = value;        
        }  
    }
}

private void DataGridScrCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.OldItems != null)
        foreach (var item in e.OldItems)
            ((DataRowView)item).PropertyChanged -= DataRowView_PropertyChanged;

    if (e.NewItems != null)
        foreach (var item in e.NewItems)
            ((DataRowView)item).PropertyChanged += DataRowView_PropertyChanged;
}

private void DataRowView_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // This will be called every time a change is made to any cell
}

Upvotes: 0

Related Questions