The title more or less sums it up. If we have a completely clean WPF application, and add the following ViewModel:
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication10
{
public sealed class ViewModel
{
private readonly ObservableCollection<MyObject> _myObjects = new ObservableCollection<MyObject>();
public ViewModel()
{
for (var i = 0; i < 5; i++)
{
_myObjects.Add(new MyObject(i, i));
}
}
public ObservableCollection<MyObject> MyObjects
{
get { return _myObjects; }
}
}
public sealed class MyObject : INotifyPropertyChanged
{
private double _unitStake;
private decimal _unitStakeDecimal;
public decimal UnitStakeDecimal
{
get { return _unitStakeDecimal; }
set
{
if (value == _unitStakeDecimal) return;
_unitStakeDecimal = value;
OnPropertyChanged("UnitStakeDecimal");
}
}
public MyObject(double unitStake, decimal unitStakeDecimal)
{
UnitStake = unitStake;
UnitStakeDecimal = unitStakeDecimal;
}
public double UnitStake
{
get { return _unitStake; }
set
{
if (value.Equals(_unitStake)) return;
_unitStake = value;
OnPropertyChanged("UnitStake");
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And then add the following XAML to MainWindow:
<Window x:Class="WpfApplication10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" DataContext="{StaticResource ViewModel}">
<Grid>
<DataGrid CanUserAddRows="False" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding MyObjects}" RowDetailsVisibilityMode="VisibleWhenSelected" Grid.Row="1">
<DataGrid.Columns>
<DataGridTextColumn Header="Unit Stake"
Binding="{Binding UnitStake,UpdateSourceTrigger=PropertyChanged}"
Width="Auto" />
<DataGridTextColumn Header="Unit Stake Dec"
Binding="{Binding UnitStakeDecimal,UpdateSourceTrigger=PropertyChanged}"
Width="Auto" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
We have a super simple MVVM application, containing a DataGridTextColumn inside a DataGrid. One of the columns in this DataGridTextColumn is bound to a double property, the other is bound to a decimal property.
When we run this, and try to amend a value in the Unit Stake column, lets say we want to change this to .05 and so type exactly this, it changes to 5.
This doesn't happen on the Unit Stake Dec column (which is bound to a decimal). This is causing some major problems, so how do I fix this so that when a user types .05 , the value of the double property is actually .05 as opposed to 5 ?
If I set the UpdateSourceTrigger property of the DataGridTextColumn column bound to the double property to LostFocus, then things work as expected, but there is the potential here for data loss, and also why do I not have to do this on the column bound to the decimal property?
Thanks
Have you given any thoughts to below line of code
if (value.Equals(_unitStake)) return;
See when you creating MyObject instances in ViewModel class
for (var i = 0; i < 5; i++)
{
_myObjects.Add(new MyObject(i, i));
}
So they are basically intialized with integer type and when you do
value.Equals(_unitStake)
It will always return false because both types are not equal. Therefore you are not able to set the property StakeUnit. Where as in case of UnitStakeDecimal you comparing their values
if (value == _unitStakeDecimal) return;
Which works and return exact result so you are able to set the property.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.