# feishu-doc-export 一個支持Windows、Mac、Linux系統的飛書文檔一鍵導出服務,僅需一行命令即可將飛書知識庫的全部文檔同步到本地電腦。導出速度嘎嘎快,實測**700**多個文檔導出只需**25**分鐘,且程式是後臺掛機運行,不影響正常工作。 ## 動機 最近也是公司辦公 ...
WPF入門教程系列目錄 WPF入門教程系列二——Application介紹 WPF入門教程系列三——Application介紹(續) WPF入門教程系列四——Dispatcher介紹 WPF入門教程系列十一——依賴屬性(一) WPF入門教程系列十五——WPF中的數據綁定(一)
DataGrid 控制項可以在單元格級別和行級別執行驗證。 通過單元格級別驗證,可以在用戶修改單元的數據時驗證綁定數據對象的單個屬性。 通過行級別驗證,可以在用戶提交對行的更改時驗證整行對象的數據。 還可以提供針對驗證錯誤的自定義可視化反饋,或使用 DataGrid 控制項提供的預設可視化反饋。
今天通過下麵的示例學習如何將驗證規則應用於 DataGrid 綁定並自定義可視化錯誤信息提示。
1. 在Visual Studio 2022的“解決方案資源管理器”中,使用滑鼠右鍵單擊“WpfGridDemo.NET7”項目,在彈出菜單中選擇“添加-->新建文件夾”。 並將“新文件夾”改名為 “Vali”。
2. 在Visual Studio 2022的解決方案資源管理器中,使用滑鼠右鍵單擊“Vali”文件夾,在彈出菜單中選擇“添加--> 類”,在彈出的“添加新項”對話框中,選擇添加 “AreaValidationRule”類,這是一個我們要實現的驗證類,然後選擇“添加”。
3.要實現在自定交驗證規則,則必須繼承ValidationRule類,並重寫Validate方法,下麵就是具體實現代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using WpfGridDemo.NET7.Entitys; namespace WpfGridDemo.NET7.Vali { public class AreaValidationRule: ValidationRule { public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { Area course = (value as BindingGroup).Items[0] as Area; if (course.Created > course.Updated) { return new ValidationResult(false, "創建日期必須小於等於更新日期。"); } else { return ValidationResult.ValidResult; } } } }
4. 創建提示信息的錯誤樣式,當用戶輸入無效值時,提示信息樣式將更改單元格背景色並添加工具提示。 請註意,使用觸發器來確定是否存在驗證錯誤。 此步驟是必需的,因為當前沒有針對單元格的專用錯誤模板。錯誤樣式代碼:
<DataGrid.Resources> <Style x:Key="errorStyle" TargetType="{x:Type TextBox}"> <Setter Property="Padding" Value="-2"/> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="Background" Value="Red"/> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources>
5. 對DataGrid的DataGridTextColumn 綁定錯誤提示信息樣式,設置ValidatesOnExceptions屬性為true,此屬性提供了顯式使用元素的 ExceptionValidationRule替代方法。 ExceptionValidationRule是一個內置驗證規則,用於檢查在更新源屬性期間引發的異常。
<DataGridTextColumn Header="ID" Width="100" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id ,ValidatesOnExceptions=True}" ClipboardContentBinding="{x:Null}"/>
6.在Visual Studio 2022中按F5鍵,啟動WPF應用程式。然後使用滑鼠點擊省份下拉框,界面中DataGrid中的呈現了城市與縣區鎮數據。
請嘗試以下操作:
- 在“ID”列中輸入一個非整數值。
- 刪除“ID”的值。
你會發現,刪除或是填了非整數值的那個單元格變成了紅色,滑鼠移到到其他單元格,也無法進入編輯模式。如下圖。
7. 移動滑鼠,將游標置入到紅色的單元格中,然後按 ESC 鍵,應用程式自動撤消了無效的單元格值。如下圖。
8.在Visual Studio 2022中打開MainWindows.xmal文件,併在文件的開頭添加如下命名空間。
xmlns:vl="clr-namespace:WpfGridDemo.NET7.Vali"
9. 將之前創建的驗證規則AreaValidationRule添加到 DataGrid.RowValidationRules 集合中。 以便通過 RowValidationRules 屬性直接訪問 BindingGroup 實例的 ValidationRules 屬性,該實例對控制項使用的所有綁定進行分組。
<DataGrid.RowValidationRules> <vl:AreaValidationRule ValidationStep="UpdatedValue"/> </DataGrid.RowValidationRules>
10. 通過設置 DataGrid.RowValidationErrorTemplate 屬性,自定義各個 DataGrid 控制項的行驗證時的錯誤提示。 還可以使用隱式行樣式設置 DataGridRow.ValidationErrorTemplate 屬性來影響多個控制項。
當用戶輸入無效值,行標題中將顯示帶有白色感嘆號的紅色圓圈。 行和單元格驗證錯誤時都將發生這種情況。 關聯的錯誤消息將顯示在工具提示中。
<DataGrid.RowValidationErrorTemplate> <ControlTemplate> <Grid Margin="0,-2,0,-2" ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent}"> <Ellipse StrokeThickness="0" Fill="Red" Width="{TemplateBinding FontSize}" Height="{TemplateBinding FontSize}" /> <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" /> </Grid> </ControlTemplate> </DataGrid.RowValidationErrorTemplate>
11. 對DataGrid的DataGridTextColumn 綁定錯誤提示信息樣式,設置ValidatesOnExceptions屬性為true,此屬性提供了顯式使用元素的 ExceptionValidationRule替代方法。 ExceptionValidationRule是一個內置驗證規則,用於檢查在更新源屬性期間引發的異常。
<DataGridTextColumn Header="創建時間" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Created ,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="更新時間" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Updated,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/>
12. 在Visual Studio 2022中按F5鍵,啟動WPF應用程式。然後使用滑鼠點擊省份下拉框,界面中DataGrid中的呈現了城市與縣區鎮數據。
請嘗試以下操作:
- 在“創建時間”列中輸入一個早於更新時間的日期。
- 刪除“創建時間”或是“更新時間”單元格中的值
你會發現,刪除了日期的那個單元格變成了紅色,滑鼠移到到其他單元格,也無法進入編輯模式。
你會發現,在行的行頭中將顯示一個紅色感嘆號 (!),將滑鼠指針移到行標題中的標記上,以查看關聯的錯誤消息。
如下圖。
13.MainWindow.xmal的全部代碼如下:
<Window x:Class="WpfGridDemo.NET7.MainWindow" 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:be="http://schemas.microsoft.com/xaml/behaviors" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfGridDemo.NET7" xmlns:v="clr-namespace:WpfGridDemo.NET7.ViewModel" xmlns:vl="clr-namespace:WpfGridDemo.NET7.Vali" mc:Ignorable="d" Title="MainWindow" Height="600" Width="960" Loaded="Window_Loaded" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="100"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="25"></RowDefinition> </Grid.RowDefinitions> <WrapPanel Grid.Row="0" HorizontalAlignment="Left"> <ComboBox x:Name="cboProvince" DisplayMemberPath="Name" SelectedValuePath="Code" > <be:Interaction.Triggers> <be:EventTrigger EventName="SelectionChanged"> <be:InvokeCommandAction Command="{Binding ProviceChangedAction}"
CommandParameter="{Binding ElementName=cboProvince}"/> </be:EventTrigger> </be:Interaction.Triggers> </ComboBox> </WrapPanel> <DataGrid x:Name="gridArea" Grid.Row="1" ItemsSource="{Binding GridAreaList}"
AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{Binding Path=AreaVM, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <DataGrid.Resources> <Style x:Key="errorStyle" TargetType="{x:Type TextBox}"> <Setter Property="Padding" Value="-2"/> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="Background" Value="Red"/> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> <DataGrid.Columns> <DataGridComboBoxColumn Header="城市" Width="120" x:Name="cboCity"
ItemsSource="{x:Static v:MainWindowVM.GridCityList}" ClipboardContentBinding="{x:Null}" SelectedValuePath="Code" SelectedValueBinding="{Binding Path=CityCode,
UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" /> <DataGridComboBoxColumn Header="城市(Style)" SelectedValuePath="Code"
SelectedValueBinding="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" Width="1*"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource" Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> </Style> </DataGridComboBoxColumn.EditingElementStyle> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource" Value="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> </Style> </DataGridComboBoxColumn.ElementStyle> </DataGridComboBoxColumn> <DataGridTextColumn Header="縣區鎮" Width="*" Binding="{Binding Name}" ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="郵編" Width="100" Binding="{Binding Code}" ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="ID" Width="100" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Id ,ValidatesOnExceptions=True}" ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="創建時間" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Created ,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="更新時間" Width="160" EditingElementStyle="{StaticResource errorStyle}"
Binding="{Binding Updated,ValidatesOnExceptions=True,StringFormat=s}" ClipboardContentBinding="{x:Null}"/> </DataGrid.Columns> <DataGrid.RowValidationRules> <vl:AreaValidationRule ValidationStep="UpdatedValue"/> </DataGrid.RowValidationRules> <DataGrid.RowValidationErrorTemplate> <ControlTemplate> <Grid Margin="0,-2,0,-2" ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent}"> <Ellipse StrokeThickness="0" Fill="Red" Width="{TemplateBinding FontSize}" Height="{TemplateBinding FontSize}" /> <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" /> </Grid> </ControlTemplate> </DataGrid.RowValidationErrorTemplate> </DataGrid> <WrapPanel Grid.Row="2"> <Button x:Name="btnRefresh" Height="22" Width="120" Click="btnRefresh_Click">刷新</Button> <Button x:Name="btnSave" Height="22" Width="120" Command="{Binding ClickSaveAction}" >保存</Button> </WrapPanel> </Grid> </Window>