I have a GridViewModel with a DataGrid which is bound to a BindableCollection of CalibrationPoints. The grid contains 4 columns: No, Start, Stop and EstimatedCalibrationTime. The user is able to edit the values directly in the DataGrid. When value in column Start is edited, the value in column EstimatedCalibrationTime needs to be recalculated. When value in column Stop is edited, the value in column Start needs to be recalculated. I am facing 2 problems that i really do not know how to solve:
public class CalibrationPoint
{
public int No { get; set; }
public int Start { get; set; }
public int Stop { get; set; }
public double EstimatedCalibrationTime { get; set; }
}
public class GridViewModel : Screen
{
public BindableCollection<CalibrationPoint> CalibrationPoints { get; }
private CalibrationPoint selectedCalibrationPoint;
public CalibrationPoint SelectedCalibrationPoint
{
get => selectedCalibrationPoint;
set
{
selectedCalibrationPoint = value;
NotifyOfPropertyChange(() => SelectedCalibrationPoint);
}
}
public GridViewModel()
{
CalibrationPoints = new BindableCollection<CalibrationPoint>();
CalibrationPoints.Add(new CalibrationPoint() { No = 1, Start = 1, Stop = 2, EstimatedCalibrationTime = CalculateCalibrationTime(1, 2) });
CalibrationPoints.Add(new CalibrationPoint() { No = 2, Start = 3, Stop = 5, EstimatedCalibrationTime = CalculateCalibrationTime(3, 5) });
CalibrationPoints.Add(new CalibrationPoint() { No = 3, Start = 6, Stop = 8, EstimatedCalibrationTime = CalculateCalibrationTime(6, 8) });
}
private double CalculateCalibrationTime(int start, int stop)
{
var time = (start * 0.7) + (stop * 1.2);
return time;
}
}
Window x:Class="Wpf_DataGridTest.Views.GridView"
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:Wpf_DataGridTest.Views"
mc:Ignorable="d"
Title="GridView" Height="300" Width="400">
<Grid>
<DataGrid Grid.Column="1"
ItemsSource="{Binding CalibrationPoints, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
SelectedItem="{Binding Path=SelectedCalibrationPoint, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserSortColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="no" Width="*" Binding="{Binding No}" IsReadOnly="True"/>
<DataGridTextColumn Header="start"
Width="2*"
Binding="{Binding Start}">
</DataGridTextColumn>
<DataGridTextColumn Header="stop"
Width="2*"
Binding="{Binding Stop}"/>
<DataGridTextColumn Header="estimated
calibration
time(s)"
Width="3*"
Binding="{Binding EstimatedCalibrationTime}"
IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
When you tab out a field you edited in the datagrid, that value will transfer via the magic of binding to your viewmodel property. You have a CalibrationPoint viewmodel per row.
Therefore an edited value will transfer to the matching CalibrationPoint instance.
That value will be set on your property. You have default empty setters there but you're not forced to work that way.
One option would be to call logic in your setter(s). Write a method does your calculation. Call it from the setter.
Like is described here:
That covers 1)
Moving on from there to 2) you need to implement inotifypropertychanged on your viewmodel and raise property changed with the name of any field which is changing as a parameter. The view then re gets the value from the viewmodel for that property.
That seems to be covered here:
https://doc.postsharp.net/inotifypropertychanged-caliburnmicro