Home > Back-end >  Checkbox as part of dataGrid - how to call event on bound data in the right order
Checkbox as part of dataGrid - how to call event on bound data in the right order

Time:09-16

I am trying to perform a calculation based on checkbox value in a datagrid as soon as a checkbox value changes, but am struggling. I thing part of the problem is timing of events.

The datagrid is bound to an observable collection. I had throught the values would update instantly, but seems not.

Below is the xaml:

<Window x:Class="GridViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GridViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
   <DockPanel>
      <GroupBox Header="Data"  Grid.Row ="1" Margin="0,0,0,0" DockPanel.Dock="Top" Height="100">
         <DataGrid x:Name="dataGrid" Margin="0,0,0,0"  AutoGenerateColumns="False" 
                         CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False" 
                         CanUserResizeColumns="False" CanUserReorderColumns="False" VerticalAlignment="Stretch" >
            <DataGrid.Columns>
               <DataGridCheckBoxColumn Header="Flag" Binding="{Binding Path=flag}" Width="35" IsReadOnly="false">
                  <DataGridCheckBoxColumn.CellStyle>
                     <Style>
                        <EventSetter Event="CheckBox.Checked" Handler="UseCheckboxChanged"/>
                        <EventSetter Event="CheckBox.Unchecked" Handler="UseCheckboxChanged"/>
                     </Style>
                  </DataGridCheckBoxColumn.CellStyle>
               </DataGridCheckBoxColumn>
               <DataGridTextColumn Header="Value" Binding="{Binding Path=dataValue, StringFormat=N3}" Width="50" IsReadOnly="True"/>
            </DataGrid.Columns>
         </DataGrid>
      </GroupBox>
      <Button x:Name="myButton" Content="Count" DockPanel.Dock="Top" Height="100" Click="myButton_Click"/>
      <TextBox x:Name="myTextBox" DockPanel.Dock="Top" Height="25"/>
   </DockPanel>
</Window>

And the code:

namespace GridViewTest
{
  public class Data
  {
    private bool _flag;
    public bool flag { get; set; }
    public double dataValue { get; set; }
    public Data()
    {
      flag = false;
      dataValue = 0;
    }
  }

  public partial class MainWindow : Window
  {
    ObservableCollection<Data> dataCol = new ObservableCollection<Data>();
    public MainWindow()
    {
      InitializeComponent();
      dataCol = new ObservableCollection<Data>();
      Data dataPt1 = new Data();
      dataPt1.flag = false;
      dataPt1.dataValue = 1.23;
      Data dataPt2 = new Data();
      dataPt2.flag = true;
      dataPt2.dataValue = 2.34;
      dataCol.Add(dataPt1);
      dataCol.Add(dataPt2);
      dataGrid.ItemsSource = dataCol;
    }
    private void UseCheckboxChanged(object sender, RoutedEventArgs e)
    {
      performCount();
    }
    public void performCount()
    {
      int count = 0;
      double sum = 0;
      foreach (Data dataPt in dataCol)
      {
        if (dataPt.flag)
        {
          count  ;
          sum  = dataPt.dataValue;
        }
      }
      this.myTextBox.Text = count.ToString()   "|"   sum.ToString();
    }
    private void myButton_Click(object sender, RoutedEventArgs e)
    {
      performCount();
    }
  }
}

My function "performCount" is called on the "CheckBox.Checked" and "CheckBox.UnChecked" but it uses the old value, so when I run the code for the first time, and check/uncheck a box, the value in the textbox does not change. Then if I click on checkbox again the value displayed is what it previously should have been. So the event seems to happen before the ObservableCollection is updated. If I click the button it displays the right value.

What is the correct way to ahve the observable collection update before running the calculation?

CodePudding user response:

add UpdateSourceTrigger=PropertyChanged to DataGridCheckBoxColumn binding:

<DataGridCheckBoxColumn 
    Header="Flag" 
    Binding="{Binding Path=flag, UpdateSourceTrigger=PropertyChanged}" 
    Width="35" 
    IsReadOnly="false">
  • Related