WPF使用MVVM时,表单验证
来源:互联网 发布:南京浦口行知基地图片 编辑:程序博客网 时间:2024/06/07 03:48
<StackPanel Orientation="Horizontal" Height="30"> <TextBlock TextWrapping="Wrap" Text="底板" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVT}" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding H_H, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="60" VerticalAlignment="Center"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVW}" VerticalAlignment="Center" Margin="30,0,3,0" /> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, Path=H_B}" Width="60" VerticalAlignment="Center"/></StackPanel><StackPanel Orientation="Horizontal" Height="30"> <TextBlock TextWrapping="Wrap" Text="腹板" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVT}" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding H_T2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="60" VerticalAlignment="Center"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVW}" VerticalAlignment="Center" Margin="30,0,3,0" /> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding H_D, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="60" VerticalAlignment="Center"/></StackPanel> <StackPanel Orientation="Horizontal" Height="30"> <TextBlock TextWrapping="Wrap" Text="面板" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVT}" VerticalAlignment="Center" Margin="20,0,3,0"/> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding B_H1, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="60" VerticalAlignment="Center"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVW}" VerticalAlignment="Center" Margin="30,0,3,0" Visibility="{Binding Visib}" /> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding B_H2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="60" Visibility="{Binding Visib}" VerticalAlignment="Center"/> <TextBlock TextWrapping="Wrap" Text="{StaticResource X_TbVL}" VerticalAlignment="Center" Margin="30,0,3,0" /> <TextBox TextAlignment="Right" Margin="5,0,3,0" TextWrapping="Wrap" Text="{Binding H_T1, UpdateSourceTrigger=LostFocus, ValidatesOnDataErrors=True}" Width="60" VerticalAlignment="Center"/> <TextBlock TextWrapping="Wrap" Text="TYPE" VerticalAlignment="Center" Margin="30,0,3,0"/> <ComboBox Height="25" Margin="5,0,3,0" SelectedIndex="{Binding CoverPlateType}"> <ComboBoxItem Content="覆盖"/> <ComboBoxItem Content="嵌入"/> </ComboBox></StackPanel><Button Content="保存" HorizontalAlignment="Left" VerticalAlignment="Center" Width="80" Margin="120,0,0,0" Command="{Binding WorksSaveManage}" Click="saveButton_Click" /><Button Content="删除" HorizontalAlignment="Right" VerticalAlignment="Center" Width="75" Margin="60,0,0,0" Command="{Binding WorksDeleteManage}" Click="Button2_Click"/><Button Content="关闭" HorizontalAlignment="Left" VerticalAlignment="Center" Width="80" Margin="60,0,0,0" Click="Button_Click" />
错误提示模板:
<Window.Resources><ControlTemplate x:Key="ErrorTemplate"> <DockPanel LastChildFill="true"> <Border Background="Red" DockPanel.Dock="right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10" ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"> <TextBlock Text="!" VerticalAlignment="center" HorizontalAlignment="center" FontWeight="Bold" Foreground="white"> </TextBlock> </Border> <AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center" > <Border BorderBrush="red" BorderThickness="1" /> </AdornedElementPlaceholder> </DockPanel> </ControlTemplate> <Style TargetType="TextBox"> <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ErrorTemplate}"> </Setter> <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>
应用场景描述:表单中TextBox数据验证条件依赖其他TextBox数据(例:腹板T<0.5*底板W)。
问题1:先录入腹板T数据,后录入底板W数据,不能触发腹板T 数据验证。
解决方法1:底板W加入和腹板T相关的验证,实现双向关联验证。优点,解决方式简单;缺点,用户体验差,增加表验证逻辑复杂性(整个表单校验时,校验失败,2选1提示数据内容)。
方法2:终端校验,保存按钮触发整个表单校验。优点:减少表单验证条件。缺点:验证条件依赖其他TextBox数据的校验,需要保存按钮触发校验提示。
问题2:表单验证失败,保存按钮不提交数据。(能力原因,没有找到ViewModel中校验整个表单的方式(╯︵╰),有大神请赐教。)
方法1:cs代码中添加保存按钮Click事件,返回整个表单验证结果给ViewModel。(关键内容校验控件的 ((TextBox)controlName).GetBindingExpression(TextBox.TextProperty).UpdateTarget())
ViewModel代码:
public class WorksManageViewModel : NotificationObject, IDataErrorInfo{ /// <summary> /// 底板厚 /// </summary> public decimal H_H { get { return MainSelect.H_H; } set { MainSelect.H_H = value; this.RaisePropertyChanged("H_H"); } } /// <summary> /// 底板宽 /// </summary> public decimal H_B { get { return MainSelect.H_B; } set { MainSelect.H_B = value; this.RaisePropertyChanged("H_B");} } /// <summary> /// 腹板厚 /// </summary> public decimal H_T2 { get { return MainSelect.H_T2; } set { MainSelect.H_T2 = value; this.RaisePropertyChanged("H_T2"); } } /// <summary> /// 腹板宽 /// </summary> public decimal H_D { get { return MainSelect.H_D; } set { MainSelect.H_D = value; this.RaisePropertyChanged("H_D"); } } /// <summary> /// 面板厚 /// </summary> public decimal B_H1 { get { return MainSelect.B_H1; } set { MainSelect.B_H1 = value; this.RaisePropertyChanged("B_H1");} } /// <summary> /// 面板宽 /// </summary> public decimal B_H2 { get { return MainSelect.B_H2; } set { MainSelect.B_H2 = value; this.RaisePropertyChanged("B_H2"); } } /// <summary> /// 箱体长度 /// </summary> public decimal H_T1 { get { return MainSelect.H_T1; } set { MainSelect.H_T1 = value; this.RaisePropertyChanged("H_T1"); } } public string this[string columnName] { get { return GetErrorFor(columnName); } } private string _error; public string Error { get { return _error; } set { _error = value; } } /// <summary> /// 校验方式 /// </summary> /// <param name="columnName"></param> /// <returns></returns> public string GetErrorFor(string columnName) { switch (columnName) { case "H_H": if (0 >= H_H) return columnName + " 必须大于0"; break; case "H_B": if (0 >= H_B) return columnName + " 必须大于0"; break; case "H_T2": if (0 >= H_T2) return columnName + " 必须大于0"; if (2 * H_T2 >= H_B) return columnName + string.Format(" 必须小于(0.5*底板W){0}", (H_B / 2).ToString()); break; case "H_D": if (0 >= H_D) return columnName + " 必须大于0"; break; case "B_H1": if (0 >= B_H1) return columnName + " 必须大于0"; else { switch (CoverPlateType) { case 1: if (B_H1 >= H_D) { return columnName + string.Format(" 必须小于(腹板W){0}", H_D.ToString()); } break; } } break; case "B_H2": switch (CoverPlateType) { case 0: if (2 * H_T2 >= B_H2) return columnName + string.Format(" 必须大于(2*腹板T){0}", (2 * H_T2).ToString()); break; case 1: if (B_H2 >= H_B - 2 * H_T2) { return columnName + string.Format(" 必须大于(底板W-2*腹板T){0}", (H_B - 2 * H_T2).ToString()); } break; } break; case "H_T1": if (0 >= H_T1) return columnName + " 必须大于0"; break; } return ""; }}
cs文件代码:
private void saveButton_Click(object sender, RoutedEventArgs e) { ((WorksManageViewModel)this.DataContext).IsValid = IsValid(this); } // Validate all dependency objects in a window bool IsValid(DependencyObject node) { // Check if dependency object was passed if (node != null) { //Check DependencyObject is TextBox //NOTE:Update DataSource Binding if (node is TextBox) { BindingExpression binding = ((TextBox)node).GetBindingExpression(TextBox.TextProperty); binding.UpdateTarget(); } // Check if dependency object is valid. // NOTE: Validation.GetHasError works for controls that have validation rules attached bool isValid = !Validation.GetHasError(node); if (!isValid) { // If the dependency object is invalid, and it can receive the focus, // set the focus if (node is IInputElement) Keyboard.Focus((IInputElement)node); return false; } } // If this dependency object is valid, check all child dependency objects foreach (object subnode in LogicalTreeHelper.GetChildren(node)) { if (subnode is DependencyObject) { // If a child dependency object is invalid, return false immediately, // otherwise keep checking if (IsValid((DependencyObject)subnode) == false) return false; } } // All dependency objects are valid return true; }
阅读全文
0 0
- WPF使用MVVM时,表单验证
- WPF 使用ValidationRule进行表单数据验证
- wpf mvvm使用问题集锦
- WPF-MVVM
- wpf-mvvm
- wpf mvvm
- WPF MvvM
- 使用MVVM设计模式构建WPF应用程序
- 使用MVVM设计模式构建WPF应用程序
- WPF程序中使用MVVM模式
- 使用WPF+MVVM模式的小案例
- MVVM WPF 使用 datagrid 绑定 comboBox
- spry 表单验证使用
- 使用JavaScript验证表单
- 使用 Ajax 验证表单
- 表单验证使用HTML5
- 使用javascript验证表单
- 使用validate验证表单
- 趣谈设计模式
- OpenGL 可编程管线学习
- IntelliJ Idea 集成svn 和使用
- 关于oracle rowid 自动排序的理解
- idea git 小技巧
- WPF使用MVVM时,表单验证
- matlab画图的一些问题
- 【数论-莫比乌斯入门】hdu 1695 GCD
- java 发带有附件的邮件
- 一个分布式服务器集群架构方案
- wordperss安装(17年8月3日)
- 学习mysql的索引设计原则以及常见索引区别
- Zabbix配置mysql监控
- 并查集-区间问题