例如:我们把一个 Slider 的Value 属性和 TextBox 的 Text 属性双向绑定在一起, Slider 的Value 的有效值是 0~100。当我们使用 Binding 绑定数值时,需要对该 Binding 的 ValidationRules 添加校验规则。具体实现如下所示:
第一步:我们声明一个 RangeValidationRule 类编写校验规则,该类需要继承 ValidationRule 类(该类为抽象类),ValidationRule类的作用是提供创建自定义规则的一个方式,旨在检查用户输入的有效性。具体代码如下:
public class RangeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (double.TryParse(value.ToString(), out var d))
{
if (d >= 0 && d <= 100)
{
return new ValidationResult(true, null);
}
}
return new ValidationResult(false, "Validation value");
}
}
第二步:对 TextBox 的 Text 属性进行 Binding 绑定,并对该 Binding 的 ValidationRules 添加一个校验规则 RangeValidationRule 类,具体实现如下:
然后,我们在文本框中,输入200,发现 TextBox 会显示红色边框,这表示数值是错误的,具体显示如下图:
image-20210205151612353
三、Binding 的数据转换#
例如:我们实现如下一个程序,程序的用途是在列表里向玩家显示一些军用飞机的状态。数据类型如下:
public enum Category
{
Bomber,
Fighter,
}
public enum State
{
Available,
Locked,
Unknown,
}
public class Plane
{
public Category Category { get; set; }
public string Name { get; set; }
public State State { get; set; }
}
在UI中,Plane 的 Category 属性被映射为图片,State 被映射为 CheckBox 的 IsChecked 属性。具体转换规则如下:
public class CategoryToSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var c = (Category)value;
switch (c)
{
case Category.Bomber:
return "image/bomber.png";
case Category.Fighter:
return "image/fighter.png";
}
return new ValidationResult(false, "Validation Value");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class StateToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var s = (State) value;
switch (s)
{
case State.Available:
return true;
case State.Locked:
return false;
default:
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var b = (bool?) value;
switch (b)
{
case true:
return State.Available;
case false:
return State.Locked;
default:
return State.Unknown;
}
}
}
我们添加一个 ViewModel 绑定到 UI 上,ViewModel 代码如下(属性变更可以阅读 WPF 之 INotifyPropertyChanged 接口的使用 (一)):
public class Window3VM : NotifyProperty
{
private ObservableCollection
private string _output;
public ObservableCollection
{
get => _planes;
set => SetProperty(ref _planes, value);
}
public string Output
{
get => _output;
set => SetProperty(ref _output, value);
}
}
我们把 ViewModel 绑定到 UI 界面上,并把转换规则添加到对应的 Binding 上,具体实现如下:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:UI" mc:Ignorable="d" d:DataContext="{d:DesignInstance local:Window3VM}" Title="Window3" Height="500" Width="600">
如下所示,当我们点击Load 按钮后,加载出来列表,点击 Save 按钮后,把整个列表输出到右边的文本框:
///
/// Window3.xaml 的交互逻辑
///
public partial class Window3 : Window
{
private readonly Window3VM vm;
public Window3()
{
InitializeComponent();
this.DataContext= vm =new Window3VM();
}
private void ButtonLoad_OnClick(object sender, RoutedEventArgs e)
{
vm.Planes=new ObservableCollection
{
new Plane(){Name = "B-1", Category = Category.Bomber, State = State.Unknown,},
new Plane(){Name = "F-35",Category = Category.Fighter,State = State.Unknown,},
new Plane(){Name = "B-6", Category = Category.Bomber, State = State.Unknown,},
new Plane(){Name = "F-22",Category = Category.Fighter,State = State.Unknown,},
new Plane(){Name = "J-20",Category = Category.Fighter,State = State.Unknown,},
};
}
private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (var plane in vm.Planes)
{
sb.Append($"{plane.Category},{plane.Name},{plane.State}\r\n");
}
vm.Output = sb.ToString();
}
}
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com