【问题标题】:Data Entry for Two-Way Binding of Small Double小双的双向绑定数据录入
【发布时间】:2014-08-20 18:58:09
【问题描述】:

我正在开发一个执行一些自定义财务数据导入的应用程序,并且用户需要能够对数字进行小的更改以使交易平衡。 (有时一个系统或另一个系统中的舍入错误会导致不平衡,需要手动调整)。错误发生在我无法控制的两个系统之间,而更改的性质需要人来决定要进行哪些更改。

我已经让数据绑定工作了,只是在输入数据时很烦人。如果用户想要输入一个非常小的负数,输入会不断覆盖他们的输入以删除负号和小数位。

例如:如果我尝试不停地输入“-0.06”,我最终只会得到“6”。如果我在到达 6 之前停下来。如果我输入了“-0.0”并意识到有些事情搞砸了,那么只有一个“0”。可以输入所需的值,但我需要进行一系列编辑,例如“1006”、“10.06”、“0.06”、“-0.06”。这不是很有成效,而且很难教别人去做。

我的模板列的 XAML 如下:

<DataGridTemplateColumn Header="Amount">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=LineAmount, Mode=OneWay, StringFormat=C2}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=LineAmount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

有什么建议吗?我尝试过自定义 IValueConverter 实现,但仍然遇到同样的问题。

【问题讨论】:

  • 数据绑定或类型没有问题。转换行为正常工作,我的程序做了它应该做的事情,问题似乎出在输入行为上。
  • 您在处理财务数据时使用decimal
  • 这个数字以十进制开头,但最终是双倍的,因为它随后被传递给允许我在不使用 QuickBooks SDK(文档很少)的情况下与 QuickBooks 交互的 odata 服务。 wcf 服务引用生成的类需要双精度值。
  • 如果将 updatesourcetrigger 更改为 lostfocus 会发生什么?

标签: wpf xaml wpfdatagrid


【解决方案1】:

我认为直接绑定到双精度是给您带来问题的原因。想一想,当你第一次输入“-”时,不能转换为双精度,所以不能应用字符串格式,打破它。您可能会在运行时在 Visual Studio 的 Output 窗口中看到这一点。相反,创建一个从字符串转换为双精度的支持属性,然后更新双精度值。

<DataGridTemplateColumn Header="Amount">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=LineAmount, Mode=OneWay, StringFormat=C2}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=LineAmountStr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

您的视图模型类:

public class TheViewModel
{
    private string _lineAmountStr;
    public string LineAmountStr
    {
        get { return _lineAmountStr; }
        set
        {
            double amt;
            if(double.TryParse(value, out amt))
            {
                LineAmount = amt;
            }
            _lineAmountStr = value;
            NotifyPropertyChanged("LineAmountStr");
        }

    private double _lineAmount;
    public double LineAmount
    {
        get { return _lineAmount; }
        set
        {
            _lineAmount = value;
            NotifyPropertyChanged("LineAmount");
        }
    }
}

【讨论】:

  • 我很快就会试试这个。我偷工减料,因为从概念到生产的最后期限是两周,所以我目前直接绑定到模型。我将设置一个 ViewModel,看看这是否能解决问题(看起来会)。
  • @Balrog30 虽然它可能不是纯 MVVM,但您可以在模型内部实现它并进行测试。
  • 这会很困难,因为模型是生成的数据服务。我可能可以继承它,但我最好只构建视图模型,无论如何这是更好的做法。我写了很多代码,只是为了让事情正常工作,是时候做一些重构了。现在我通过将UpdateSourceTrigger 更改为LostFocus 来使该功能正常工作。
  • 所以我确实让它工作了。我遇到的一个问题是我试图让LineAmount setter 更新LineAmountStr,这导致StackOverflowException(顺便说一下,试着在谷歌上搜索...... StackOverflow 有点杀了那个) )。不过,现在一切都很好。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-02-24
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2014-01-30
相关资源
最近更新 更多