简体   繁体   中英

In a DataGridTextColumn, on a column bound to a double value type, .05 gets converted to 5

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM