在开发用户界面时,经常需要将UI元素绑定到底层数据对象上。本文将介绍如何使用.NET 3.5的IDataErrorInfo接口实现数据绑定和验证,并允许用户选择应用或取消更改。
首先,需要创建一个提供验证功能的数据对象。将使用IDataErrorInfo接口来实现这一点。
以下是C#代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Binding.Explicit
{
class Person : IDataErrorInfo
{
private StringBuilder combinedError = new StringBuilder(2000);
public int Age { get; set; }
public string Error
{
get
{
return combinedError.ToString();
}
}
public string this[string columnName]
{
get
{
string result = null;
switch (columnName)
{
case "Age":
if (Age < 0)
{
result = "Age can't be < 0";
combinedError.Append(result + "\n");
}
if (Age > 20)
{
result = "Age can't be > 20";
combinedError.Append(result + "\n");
}
break;
}
return result;
}
}
}
}
在上述代码中,创建了一个名为Person的类,该类实现了IDataErrorInfo接口。定义了一个Age属性,并在该属性上实现了验证逻辑。
接下来,需要创建一些使用这些绑定的元素。在这个简单的例子中,只绑定了Age属性。
以下是XAML代码示例:
<Window x:Class="Binding.Explicit.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="textStyleTextBox" TargetType="TextBox">
<Setter Property="Foreground" Value="#333333" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Label Content="Age" Width="auto" Height="auto" />
<TextBox x:Name="txtAge" Width="auto" Height="auto" Style="{StaticResource textStyleTextBox}" Text="{Binding Path=Age, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}" />
<StackPanel Orientation="Horizontal">
<Button x:Name="btnUpdate" Content="Update Object" Width="auto" Height="auto" Click="btnUpdate_Click" />
<Button x:Name="btnCancel" Content="Cancel" Width="auto" Height="auto" Click="btnCancel_Click" />
</StackPanel>
</StackPanel>
</Window>
在上述代码中,定义了一个名为Window1的窗口,并在其中创建了一个TextBox控件。使用了一个名为textStyleTextBox的样式来设置TextBox的验证提示。
最后,需要实现代码逻辑,以便在用户选择应用更改时显式地更新绑定源。
以下是C#代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace Binding.Explicit
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
this.DataContext = new Person();
}
private void btnUpdate_Click(object sender, RoutedEventArgs e)
{
BindingExpression expression = txtAge.GetBindingExpression(TextBox.TextProperty);
expression.UpdateSource();
string errorMessage = string.Empty;
if (!IsValid("Age", out errorMessage))
{
ValidationError error = new ValidationError(new ExceptionValidationRule(), expression, errorMessage, null);
Validation.MarkInvalid(expression, error);
}
else
{
MessageBox.Show("Success, we could update DB here", "Success", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
private bool IsValid(string path, out string errorMessage)
{
errorMessage = ((IDataErrorInfo)this.DataContext)[path];
return string.IsNullOrEmpty(errorMessage);
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}