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