IValueConverter 和 Metric/Imperial 单位
IValueConverter and Metric/Imperial units
我计划实施代码,使用 IValueConverter 根据用户设置的布尔值以公制或英制显示测量单位。我面临的问题是存储在我的数据库中的数据必须始终采用公制。如果有区别的话,我首先使用 Entity Framework 数据库。
所以我想知道的情况是:如果用户选择以英制单位显示数据,然后更改其中一个字段并保存它 - 我如何确保它以公制正确保存?从我通过在线研究收集到的信息来看,这似乎是转换器的 ConvertBack 方法的一部分?现在我打电话给 Textbox.GetBindingExpression(TextBox.TextProperty).UpdateSource();保存数据,我不明白如何让它工作,因为据我所知,它只是获取 TextBox 中的值并保存它。我说得对吗,或者如果有 ConvertBack 方法,是否会调用该方法以获取 TextProperty?
此外,一般来说,我的处理方式是否正确(即使用 IValueConverter 来更改显示)?老实说,我在这个项目上不知所措,但我的最后期限很快就要到了,并且迫切需要正确地完成这项工作。任何帮助将不胜感激。
谢谢。
你有一些模型,你想使用 TextBox
和 ValueConverter
编辑该模型的一些属性。让我们采用一些虚拟值转换器,它将值乘以 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 方法,结果将分配给您模型的 SomeValue。
当用户按下保存按钮时,您只需使用您拥有的任何方法将模型保存到数据库中。您不需要显式更新模型的属性,因为它们已经是最新的。您也可以使用 UpdateSourceTrigger=LostFocus
(默认一个)。然后,每当字段失去焦点时 - 您模型中的 属性 将与其同步(同样,通过 ConvertBack
)
我计划实施代码,使用 IValueConverter 根据用户设置的布尔值以公制或英制显示测量单位。我面临的问题是存储在我的数据库中的数据必须始终采用公制。如果有区别的话,我首先使用 Entity Framework 数据库。
所以我想知道的情况是:如果用户选择以英制单位显示数据,然后更改其中一个字段并保存它 - 我如何确保它以公制正确保存?从我通过在线研究收集到的信息来看,这似乎是转换器的 ConvertBack 方法的一部分?现在我打电话给 Textbox.GetBindingExpression(TextBox.TextProperty).UpdateSource();保存数据,我不明白如何让它工作,因为据我所知,它只是获取 TextBox 中的值并保存它。我说得对吗,或者如果有 ConvertBack 方法,是否会调用该方法以获取 TextProperty?
此外,一般来说,我的处理方式是否正确(即使用 IValueConverter 来更改显示)?老实说,我在这个项目上不知所措,但我的最后期限很快就要到了,并且迫切需要正确地完成这项工作。任何帮助将不胜感激。
谢谢。
你有一些模型,你想使用 TextBox
和 ValueConverter
编辑该模型的一些属性。让我们采用一些虚拟值转换器,它将值乘以 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 方法,结果将分配给您模型的 SomeValue。
当用户按下保存按钮时,您只需使用您拥有的任何方法将模型保存到数据库中。您不需要显式更新模型的属性,因为它们已经是最新的。您也可以使用 UpdateSourceTrigger=LostFocus
(默认一个)。然后,每当字段失去焦点时 - 您模型中的 属性 将与其同步(同样,通过 ConvertBack
)