Since you want to display a calculated Weight
value based on other properties, you should change the following parts of your code:
Make the binding one-way, since the value will always be re-computed in source.
<DataGridTextColumn Binding="{Binding Weight, Mode=OneWay}"
Header="???"
Width="100"
IsReadOnly="True"/>
Write the property as get-only calculation.
public int Weight
{
get { return Item.Weight * Count; } // TODO: adjust if Item can be null
}
Notify for dependent changes in the source properties of your calculation. If Item.Weight
could change within an item instance, you need additional handling.
private Item _Item;
public Item Item
{
get { return _Item; }
set
{
_Item = value;
RaiseProperChanged();
RaiseProperChanged(nameof(Weight));
}
}
private int _Count;
public int Count
{
get { return _Count; }
set
{
_Count = value;
RaiseProperChanged();
RaiseProperChanged(nameof(Weight));
}
}
Remove everything that accesses the Weight
setter (for example in constructor).
See the following minimal working example for a calculated property. I rely on auto-generated columns in this case, but the same should be possible with hand written columns.
<Window
... your default generated window class, nothing special ... >
<Grid x:Name="grid1">
<DataGrid ItemsSource="{Binding}"/>
</Grid>
</Window>
Viewmodel itemtype definition with dependent property Calculated
:
public class ExampleItemViewModel : INotifyPropertyChanged
{
private int _Number;
public int Number
{
get { return _Number; }
set
{
_Number = value;
NotifyPropertyChanged();
NotifyPropertyChanged("Calculated");
}
}
public int Calculated { get { return 2 * Number; } }
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string prop = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(prop));
}
}
MainWindow constructor:
public MainWindow()
{
InitializeComponent();
var data = new List<ExampleItemViewModel>();
data.Add(new ExampleItemViewModel { Number = 1 });
data.Add(new ExampleItemViewModel { Number = 2 });
grid1.DataContext = data;
}
What should happen: the DataGrid autogenerates an editable column for Number
and a read-only column for Calculated
. Since the columns are autogenerated, the default behavior applies: when you change a number, the source will not be updated immediately, because the row is in edit mode. It will be updated after the edit completes (eg. you press enter or the row loses focus). As soon as the source is updated, the dependent Calculated
column value changes to 2 times the Number
value.