WPF/C#:BusinessLayerValidation

wpf,businesslayervalidation · 浏览次数 : 0

小编点评

本文介绍了BusinessLayerValidation(业务层验证)的概念,它是软件应用程序中业务逻辑层的一部分,主要负责确保数据在业务规则和逻辑上的有效性。业务层验证的目的是维护数据的完整性和一致性,确保数据在整个应用程序中的正确性和一致性。 业务层验证的主要内容包括检查数据是否符合特定的业务规则、数据完整性检查和数据一致性检查等。通过在业务层进行验证,可以避免在用户界面层出现不必要的错误提示,使用户能够更快地理解并纠正输入错误。 在WPF中,可以通过实现IDataErrorInfo接口来为数据对象提供详细的验证错误信息。这个接口包含两个成员:一个是Error属性,用于返回整个对象的错误信息;另一个是this[string columnName]索引器,用于返回指定属性的错误信息。 此外,WPF还提供了触发器(Trigger)机制,可以根据不同的条件自动调整控件的外观和行为。例如,当文本框获得焦点且文本为空时,文本框的边框颜色会变为红色。 最后,本文提供了一个WPF样品,其中使用了IDataErrorInfo接口和触发器来实现业务层验证。通过这个样品,读者可以更好地理解业务层验证的概念和实现方法。

正文

BusinessLayerValidation介绍

BusinessLayerValidation,即业务层验证,是指在软件应用程序的业务逻辑层(Business Layer)中执行的验证过程。业务逻辑层是应用程序架构中的一个关键部分,负责处理与业务规则和逻辑相关的操作。业务层验证的主要目的是确保数据在业务规则和逻辑上的有效性,从而维护数据的完整性和一致性。

  • 业务层验证的主要目的是确保数据在业务规则和逻辑上的有效性。这包括检查数据是否符合特定的业务规则、数据完整性检查、数据一致性检查等。
  • 通过在业务层进行验证,可以确保数据在整个应用程序中的正确性和一致性,而不仅仅是在用户界面层。

在WPF中如何实现BusinessLayerValidation

在WPF Samples中有一个Demo提到了BusinessLayerValidation。

该Demo结构如下所示:

image-20240625143242336

实现的效果如下所示:

当输入值是字符时会提示不是正确的形式,当输入小于0或大于150的数时会有一个自定义的提示。

IDataErrorInfo接口

在WPF中实现业务逻辑层的验证可以使用IDataErrorInfo接口与INotifyDataErrorInfo 接口。这个Demo使用的是IDataErrorInfo接口。IDataErrorInfo接口主要用于在数据绑定场景中提供自定义的验证错误信息。IDataErrorInfo接口包含两个成员:

string IDataErrorInfo.Error { get; }

这个属性返回一个字符串,表示整个对象的错误信息。如果对象没有错误,应该返回一个空字符串或null。

string IDataErrorInfo.this[string columnName] { get; }

这个索引器用于返回指定属性的错误信息。columnName参数表示属性的名称,索引器应该返回该属性的错误信息。如果属性没有错误,应该返回一个空字符串或null。

通过实现IDataErrorInfo接口,可以为数据对象提供详细的验证错误信息,这些信息可以在用户界面中显示,帮助用户理解和纠正输入错误。

定义一个实现该接口的Person类:

 public class Person : IDataErrorInfo
 {
     public int Age { get; set; }
     public string Error => null;

     public string this[string name]
     {
         get
         {
             string result = null;

             if (name == "Age")
             {
                 if (Age < 0 || Age > 150)
                 {
                     result = "Age must not be less than 0 or greater than 150.";
                 }
             }
             return result;
         }
     }
 }

定义资源

  <local:Person x:Key="Data"/>

现在xaml中定义了一个Person对象为资源,键名为Data。

<!--The tool tip for the TextBox to display the validation error message.-->
<Style x:Key="TextBoxInError" TargetType="TextBox">
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip"
                    Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                                    Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

为TextBox控件定义了一个键名为TextBoxInError的样式(Style)。

触发器(Trigger)

在WPF中,触发器(Trigger)是一种用于在特定条件满足时改变控件外观或行为的机制。Trigger通常用于Style

或ControlTemplate中,以便在属性值变化或事件发生时自动应用视觉效果或行为。

WPF 中的Trigger可以分为以下几类:

  • Property Trigger
  • Data Trigger
  • Event Trigger
  • MultiTrigger
  • MultiDataTrigger

Property Trigger是最常用的触发器类型。它根据依赖属性的值来应用视觉效果或行为。

示例:

<Style TargetType="Button">
  <Style.Triggers>
    <Trigger Property="IsMouseOver" Value="True">
      <Setter Property="Background" Value="Yellow"/>
    </Trigger>
  </Style.Triggers>
</Style>

在这个例子中,当鼠标悬停在按钮上时,按钮的背景色会变为黄色。

Data Trigger类似于Property Trigger,但它用于绑定数据上下文中的属性,而不是控件本身的依赖属性。

示例:

<Style TargetType="TextBlock">
  <Style.Triggers>
    <DataTrigger Binding="{Binding Path=IsEnabled}" Value="False">
      <Setter Property="Foreground" Value="Gray"/>
    </DataTrigger>
  </Style.Triggers>
</Style>

在这个例子中,当数据上下文中的IsEnabled属性为False时,文本块的前景色会变为灰色。

Event Trigger用于在特定事件发生时执行动画或命令。

示例:

<Button Content="Click Me">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:1"/>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

在这个例子中,当按钮被点击时,按钮的透明度会从 1 变为 0,持续 1 秒钟。

MultiTriggerMultiDataTrigger允许你指定多个条件,只有当所有条件都满足时,才会应用视觉效果或行为。

示例:

<Style TargetType="TextBox">
  <Style.Triggers>
    <MultiTrigger>
      <MultiTrigger.Conditions>
        <Condition Property="IsFocused" Value="True"/>
        <Condition Property="Text" Value=""/>
      </MultiTrigger.Conditions>
      <Setter Property="BorderBrush" Value="Red"/>
    </MultiTrigger>
  </Style.Triggers>
</Style>

在这个例子中,当文本框获得焦点且文本为空时,文本框的边框颜色会变为红色。

通过使用这些触发器,可以创建动态和响应式的用户界面,根据不同的条件自动调整控件的外观和行为。

通过回顾WPF中的这些触发器,再来看看现在遇到的触发器:

 <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip"
                    Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                                    Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>

这是属性触发器,当Validation.HasError属性的值为true时,会将ToolTip的值设置为(Validation.Errors)[0].ErrorContent的值。

之前我们已经接触过StaticSource这表示是静态资源,现在这里是RelativeSource,让我们来了解一下它吧。

RelativeSource是WPF中的一个绑定标记扩展,用于指定数据绑定的源相对于绑定目标的位置。它允许你在绑定表达式中引用相对于当前控件或数据上下文的另一个对象,而不是直接指定一个固定的源对象。

RelativeSource可以用于以下几种模式:

  • Self:绑定到控件自身的一个属性。
  • TemplatedParent:绑定到应用控件模板的控件。
  • PreviousData:在数据模板中绑定到前一个数据项。
  • FindAncestor:绑定到可视树中的祖先控件。

可以创建更灵活和动态的数据绑定,特别是在处理复杂的用户界面和控件模板时。

再来看文本框部分:

 <StackPanel Margin="20">
     <TextBlock>Enter your age:</TextBlock>
     <TextBox Style="{StaticResource TextBoxInError}">
         <TextBox.Text>
             <!--By setting ValidatesOnExceptions to True, it checks for exceptions
             that are thrown during the update of the source property.
             An alternative syntax is to add <ExceptionValidationRule/> within
             the <Binding.ValidationRules> section.-->
             <Binding Path="Age" Source="{StaticResource Data}"
                      ValidatesOnExceptions="True"
                      UpdateSourceTrigger="PropertyChanged">
                 <Binding.ValidationRules>
                     <!--DataErrorValidationRule checks for validation 
                         errors raised by the IDataErrorInfo object.-->
                     <!--Alternatively, you can set ValidationOnDataErrors="True" on the Binding.-->
                     <DataErrorValidationRule/>
                 </Binding.ValidationRules>
             </Binding>
         </TextBox.Text>
     </TextBox>
     <TextBlock>Mouse-over to see the validation error message.</TextBlock>
 </StackPanel>

首先为文本框设置了键名为TextBoxInError的样式。

 <TextBox.Text>   
 <Binding Path="Age" Source="{StaticResource Data}"
          ValidatesOnExceptions="True"
          UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
                 <DataErrorValidationRule/>
      </Binding.ValidationRules>
             </Binding>
  </TextBox.Text>

ValidatesOnExceptions属性指定了是否在数据绑定过程中捕获并处理异常。ValidatesOnExceptions="True"

表示如果在数据绑定过程中发生了异常(例如,数据源的Age属性在设置值时抛出了异常),这个异常将会被捕获并用于验证目的,通常用于显示错误信息或阻止无效数据的输入。

  <Binding.ValidationRules>
        <DataErrorValidationRule/>
  </Binding.ValidationRules>

Binding.ValidationRules是一个集合属性,用于存储数据绑定的验证规则。这些验证规则用于在数据绑定过程中检查数据的合法性。DataErrorValidationRule是WPF中预定义的一种验证规则。它用于检查数据对象是否实现了

IDataErrorInfo接口,并根据该接口提供的信息进行验证。当数据对象实现了IDataErrorInfo接口时,DataErrorValidationRule会调用接口中的方法来获取错误信息,并在数据绑定过程中应用这些错误信息。

验证类型

默认验证:当你输入 "a" 时,WPF尝试将 "a" 转换为整数,但由于 "a" 不是有效的整数,默认验证机制会生成一个错误,提示 "不是正确的格式"。

自定义验证:在你输入一个有效的整数后,WPF会继续检查这个值是否符合你的自定义验证规则(例如,年龄必须在0到150之间)。如果值不符合规则,你会看到 "Age must not be less than 0 or greater than 150" 的提示。

在WPF中,数据绑定的验证过程通常遵循以下顺序:

数据转换(Data Conversion)

如果绑定的数据需要从一种类型转换为另一种类型(例如,从字符串转换为整数),WPF会首先尝试进行类型转换。如果转换失败,会抛出一个异常,这个异常可以被捕获并用于验证目的。

验证规则(Validation Rules)

如果绑定的ValidationRules集合中定义了任何自定义的验证规则,WPF会按照这些规则的顺序依次执行它们。每个验证规则可以返回一个ValidationResult对象,指示数据是否有效以及相关的错误信息。

异常验证(Exception Validation)

如果绑定的ValidatesOnExceptions属性设置为True,WPF会在数据绑定的过程中捕获任何抛出的异常,并将这些异常转换为验证错误。这通常用于捕获数据转换或数据设置过程中的异常。

IDataErrorInfo 验证

如果数据对象实现了IDataErrorInfo接口,WPF会调用该接口的方法来获取错误信息。DataErrorValidationRule

可以用于在数据绑定过程中应用这些错误信息。

INotifyDataErrorInfo 验证

如果数据对象实现了INotifyDataErrorInfo接口,WPF会监听该接口的事件,并在数据发生错误时获取错误信息。这种验证方式提供了更灵活和异步的验证机制。

这些验证步骤并不是严格按顺序执行的,而是根据绑定的配置和数据对象的实现情况来决定。例如,如果绑定的

ValidationRules集合中包含了DataErrorValidationRule,那么IDataErrorInfo验证会在验证规则执行的过程中被触发。

WPF中的验证顺序是灵活的,并且可以根据具体的绑定配置和数据对象的实现情况来调整。通常情况下,数据转换和自定义验证规则会在异常验证和IDataErrorInfo验证之前执行。

代码来源

[WPF-Samples/Data Binding/BusinessLayerValidation at main · microsoft/WPF-Samples (github.com)](https://github.com/microsoft/WPF-Samples/tree/main/Data Binding/BusinessLayerValidation)

与WPF/C#:BusinessLayerValidation相似的内容:

WPF/C#:BusinessLayerValidation

BusinessLayerValidation介绍 BusinessLayerValidation,即业务层验证,是指在软件应用程序的业务逻辑层(Business Layer)中执行的验证过程。业务逻辑层是应用程序架构中的一个关键部分,负责处理与业务规则和逻辑相关的操作。业务层验证的主要目的是确保数

WPF/C#:如何实现拖拉元素

前言 在Canvas中放置了一些元素,需要能够拖拉这些元素,在WPF Samples中的DragDropObjects项目中告诉了我们如何实现这种效果。 效果如下所示: 拖拉过程中的效果如下所示: 具体实现 xaml页面 我们先来看看xaml:

WPF/C#:数据绑定到方法

在WPF Samples中有一个关于数据绑定到方法的Demo,该Demo结构如下: 运行效果如下所示: 来看看是如何实现的。 先来看下MainWindow.xaml中的内容:

WPF/C#:在DataGrid中显示选择框

前言 在使用WPF的过程中可能会经常遇到在DataGrid的最前或者最后添加一列选择框的需求,今天跟大家分享一下,在自己的项目中是如何实现的。 整体实现效果如下: 如果对此感兴趣,可以接下来看具体实现部分。 实践 假设数据库中的模型如下: public class Person { public i

WPF/C#:显示分组数据的两种方式

前言 本文介绍自己在遇到WPF对数据进行分组显示的需求时,可以选择的两种方案。一种方案基于ICollectionView,另一种方案基于IGrouping。 基于ICollectionView实现 相关cs代码: [ObservableProperty] private ObservableColl

WPF/C#:如何将数据分组显示

WPF Samples中的示例 在WPF Samples中有一个关于Grouping的Demo。 该Demo结构如下: MainWindow.xaml如下:

WPF/C#:程序关闭的三种模式

ShutdownMode枚举类型介绍 ShutdownMode是一个枚举类型,它定义了WPF应用程序的关闭方式。这个枚举类型有三个成员: OnLastWindowClose:当最后一个窗口关闭或者调用System.Windows.Application.Shutdown方法时,应用程序会关闭。 On

C# WPF 将第三方DLL嵌入 exe

没成功,只是做个记录,后面再研究 希望将第三方的 HandyControl.dll 嵌入到 exe 中,这样不用发多个文件给别人 ![image](https://img2023.cnblogs.com/blog/80824/202308/80824-20230804153348542-538869

你们眼睛干涩,胀痛吗?C# WPF 久坐提醒桌面小程序 - 内附 眼肌运动、远视力表高清图

目录说明设置提醒时间,及休息时间久坐提醒倒计时休息提醒倒计时休息到计时代码说明主窗体设置工作到计时休息倒计时源码高清图 久坐提醒桌面小程序: 干这行职业病比较多,之前用爱丽(即:玻璃酸钠滴眼液),用的时候挺舒服,缓解吧,不过治标不治本。 注意休息,加强锻炼非常有必要,每工作1小时,休息10分钟(程序

在WPF中使用着色器

概念类比 范畴 CPU GPU 二进制文件 .exe .cso / .ps 二进制指令 机器码 CSO(shader指令) 助记符 汇编 SL 高级语言 C# HLSL 高级语言文件 .cs .hlsl / .fx 高级语言编译器 csc.exe fxc.exe API .NET API Direc