C# IValueConverter和公制/英制单位

C# IValueConverter和公制/英制单位,c#,wpf,entity-framework,units-of-measurement,C#,Wpf,Entity Framework,Units Of Measurement,我计划实现一个代码,该代码将使用IValueConverter根据用户设置的布尔值以公制或英制显示度量单位。我面临的问题是,存储在数据库中的数据必须始终使用公制。如果有区别的话,我会先使用实体框架数据库 因此,我想知道的情况是:如果用户选择以英制单位显示数据,但随后更改了其中一个字段并将其保存—我如何确保它以公制单位正确保存?从我通过在线研究收集的信息来看,这似乎是转换器ConvertBack方法的一部分?现在我调用Textbox.GetBindingExpression(Textbox.Tex

我计划实现一个代码,该代码将使用IValueConverter根据用户设置的布尔值以公制或英制显示度量单位。我面临的问题是,存储在数据库中的数据必须始终使用公制。如果有区别的话,我会先使用实体框架数据库

因此,我想知道的情况是:如果用户选择以英制单位显示数据,但随后更改了其中一个字段并将其保存—我如何确保它以公制单位正确保存?从我通过在线研究收集的信息来看,这似乎是转换器ConvertBack方法的一部分?现在我调用Textbox.GetBindingExpression(Textbox.TextProperty).UpdateSource();为了保存数据,我不知道该怎么做,因为据我所知,它只会抓取文本框中的值并保存它。我说的对吗,或者如果有一个ConvertBack方法,为了获取TextProperty会调用它吗

此外,一般来说,我是否以正确的方式(即使用IValueConverter更改显示)?老实说,我在这个项目上有点不知所措,但我的最后期限很快就要到了,我迫切需要把这件事做好。任何帮助都将不胜感激


谢谢。

所以您有一些模型,您想使用
文本框
值转换器
编辑该模型的一些属性。让我们使用一些虚拟值转换器,它将值乘以10,在
ConvertBack
中,将值除以10

public class MyConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if (value == null || value == DependencyProperty.UnsetValue)
            return null;
        return (decimal) value*10;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        if (value == null || value == DependencyProperty.UnsetValue)
            return 0;
        decimal d;
        if (decimal.TryParse((string) value, out d))
            return d/10;
        return 0;
    }
}
现在是一些测试模型

public class MyModel : INotifyPropertyChanged {
    private decimal _someValue;

    public decimal SomeValue
    {
        get { return _someValue; }
        set
        {
            if (value == _someValue) return;
            _someValue = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
然后你就有了你的文本框

<TextBox Width="150" Height="20" Text="{Binding SomeValue, Mode=TwoWay, Converter={StaticResource myConverter}, UpdateSourceTrigger=PropertyChanged}" />

如果使用
UpdateSourceTrigger=PropertyChanged
,则在每次用户编辑时,该值将传递给ConvertBack方法,并将结果分配给模型的某个值


当用户按下“保存”按钮时,您只需使用任何一种方法将模型保存到数据库中。您不需要显式更新模型的属性,因为它们已经是最新的。您还可以使用
UpdateSourceTrigger=LostFocus
(默认值)。然后,每当字段失去焦点时,模型中的属性将与其同步(同样,通过
ConvertBack

您需要使用Mode=TwoWay绑定文本框。然后,当在您的模型上设置textbox的值时,将调用转换器ConvertBack。()Ok@Evk。我确信我明白了:如果我设置Mode=TwoWay,那么当我调用Textbox.GetBindingExpression(Textbox.TextProperty.UpdateSource();那么它应该保存ConvertBack()转换器的结果吗?对不起,如果我的声音很模糊,我只是想确定一下。谢谢你的帮助。谢谢@Rom链接。你根本不需要致电UpdateSource。使用双向绑定,当您更改文本框中的文本时(在失去焦点时,或立即,请参阅链接问题),它将更新模型中的值(如果有转换器,则通过转换器的ConvertBack方法)。确定。我想我现在明白了。出于某种原因,我认为调用UpdateSource()实际上是在保存数据库。我更仔细地观察了一下,当我调用DTE.ChangeTracker.DetectChanges()时,这种情况实际上发生了;SaveChanges();其中DTE是我的数据库上下文。我现在明白了。酷。唯一阻止我实现您所说的内容的是我的模型没有实现INotifyPropertyChanged,因为我首先使用了数据库。可能需要咬紧牙关,先用代码。不管怎样,你已经给了我足够多的时间来指引我正确的方向。非常感谢你,@Evk。我真的很感谢你抽出时间和我详细讨论这件事。你太棒了。我把你的回答标为已被接受。我希望你有一个美好的一天。