在DataGridTextColumn中,在绑定到双值类型的列上,.05被转换为5

本文关键字:转换 类型 DataGridTextColumn 绑定 | 更新日期: 2023-09-27 18:24:32

标题或多或少地对其进行了总结。如果我们有一个完全干净的WPF应用程序,并添加以下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));
        }
    }
}

然后将以下XAML添加到主窗口:

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

我们有一个超级简单的MVVM应用程序,在DataGrid中包含一个DataGridTextColumn。此DataGridTextColumn中的一列绑定到了double属性,另一列则绑定到了decimal属性。

当我们运行这个程序,并试图修改UnitStake列中的值时,假设我们想将其更改为.05,因此键入确切的值,它将更改为5。

这不会发生在Unit Stake Dec列(绑定到小数)上。这导致了一些主要问题,那么我该如何解决这个问题,以便当用户键入.05时,double属性的值实际上是.05,而不是5

如果我将绑定到double属性的DataGridTextColumn列的UpdateSourceTrigger属性设置为LostFocus,那么一切都如预期的那样进行,但这里存在数据丢失的可能性,以及为什么我不必对绑定到decimal属性的列执行此操作?

感谢

在DataGridTextColumn中,在绑定到双值类型的列上,.05被转换为5

您对以下代码行有什么想法吗

if (value.Equals(_unitStake)) return;

查看在ViewModel类中创建MyObject实例的时间

for (var i = 0; i < 5; i++)
{
    _myObjects.Add(new MyObject(i, i));
}

所以它们基本上是用整数类型初始化的,当你进行时

value.Equals(_unitStake)

它将始终返回false,因为这两种类型不相等。因此,您无法设置属性StakeUnit。在UnitStakeDecimal的情况下,您比较它们的值

if (value == _unitStakeDecimal) return;

它工作并返回确切的结果,以便您能够设置属性。