我想创建一个收集设备测量值的C#
WPF表单,但有些用户会尝试使用英尺和英寸进行测量,而其他(较年轻)用户则使用公制进行测量.数据库以米为单位存储所有内容,我认为这是使用IMultiValueConverter的理想场所.
每个表单都有一个名为UseImperialMeasurements的DependencyProperty,用于存储用户首选项,并将此值与实际测量值(以米为单位)一起传递给Convert函数.到目前为止,代码如下所示:
<Label>Length:</Label> <TextBox> <TextBox.Text> <MultiBinding Converter="{StaticResource distanceStringConverter}" Mode="TwoWay"> <Binding Path="Length" /> <Binding ElementName="ThisControl" Path="UseImperialMeasurements" /> </MultiBinding> </TextBox.Text> </TextBox> public class distanceStringConverter : IMultiValueConverter { public object Convert(object[] values,Type targettype,object parameter,System.Globalization.CultureInfo culture) { if (values.Length != 2 || !(values[0] is Double) || !(values[1] is Boolean)) return "ERROR"; Double measurement = (Double)values[0]; // Always in meters Boolean useImperial = (Boolean)values[1]; string unit; if (useImperial == true) { double feet,inches; inches = (measurement * 100) / 2.54; feet = Math.Floor(inches / 12); inches = inches % 12; var replacements = new object[4]; replacements[0] = feet.ToString("#,0"); replacements[1] = "'"; replacements[2] = inches.ToString("0"); replacements[3] = "\""; // display like 12'4" return string.Format("{0}{1}{2}{3}",replacements); } else { // display like 5,987.97m return string.Format("{0}{1}",measurement.ToString("#,0.##"),m); } } public object[] ConvertBack(object value,Type[] targettypes,System.Globalization.CultureInfo culture) { // Todo: figure out if imperial or metric measurements are prefered... } }
这适用于显示测量,但将它们作为公制或英制的输入是有问题的,因为我无法在ConvertBack方法中看到UseImperialMeasurements属性的绑定值.因此,我不仅无法猜测用户是否在未指定单位时输入英尺或米,但我无法知道要返回的布尔值,以便用户设置首选项不会更改.
是否可以将UseImperialMeasurements的值传递给ConvertBack函数?
解决方法
将UseImperialMeasurements值存储为应用程序设置(或任何您想要的地方,实际上,但用例有利于应用程序范围的用户设置).双击Visual Studio中项目树中的“属性”项,即可实现此目的.在那里,只需单击“设置”选项卡并将“UseImperialMeasurements”添加为bool,作用域用户,并设置默认值.
然后,在代码中的任何位置,使用Properties.Settings.Default.UseImperialMeasurements属性访问和更改值.
如果您记得在关闭表单或应用程序之前调用Properties.Settings.Default.Save(),则设置将为“Stick”.
然后,在XAML中,您将使用此绑定访问该设置:
{Binding Source={x:Static my:Settings.Default},Path=UseImperialMeasurements}
或者,忘记转换器.将此功能烘焙到viewmodel中,并将UseImperialMeasurements值存储为应用程序设置(或任何您想要的地方,但用例有利于用户设置)
public class backingDataClass { public double LengthAlwaysMetric { get; set; } } public class backingDataClassviewmodel : INotifyPropertyChanged { public backingDataClass Data { get; set; } public double Length { get { if (Properties.Settings.Default.UseImperialMeasurements == true) { return ConvertToImperial(Data.LengthAlwaysMetric); } else { return _lengthAlwaysMetric; } } set { if (Properties.Settings.Default.UseImperialMeasurements == true) { Data.LengthAlwaysMetric = ConvertToMetric(value); } else { Data.LengthAlwaysMetric = value; } PropertyChanged(this,new PropertyChangedEventArgs("Length")); } } public event PropertyChangedEventHandler PropertyChanged; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。