如何发送验证消息表单模型以在 MVVM 模式中查看?
Posted
技术标签:
【中文标题】如何发送验证消息表单模型以在 MVVM 模式中查看?【英文标题】:How to do I send validation messages form model to view in the MVVM pattern? 【发布时间】:2009-04-03 08:48:59 【问题描述】:我有一个小型测试 WPF MVVM 应用程序在其中工作,其中一个视图允许用户更改客户的名字或姓氏,并且全名会自动更改,因此通信是从 M 到 MV 到 - V 和回来,一切都完全解耦,到目前为止一切顺利。
但是现在当我考虑如何开始扩展它以使用 MVVM 模式构建大型应用程序时,我发现解耦是一个障碍,即:
我将如何处理验证消息,例如如果回到 LastName 设置器中的模型中,我添加了阻止设置超过 50 个字符的名称的代码,如何向视图发送消息,告诉它显示名称太长的消息?
在复杂的应用程序中我可能在一个屏幕上同时有几十个视图,但我知道在 MVVM 中每个视图都有一个且只有一个 ViewModel 分配给它以提供它数据和行为,因此视图如何相互交互,例如在上面的验证示例中,如果回到客户模型中,我们想要通知特定的“MessageAreaView”以显示消息“姓氏可能只包含 50 个字符。”,我们如何将堆栈向上传达给该特定视图?
CustomerHeaderView.xaml(视图):
<UserControl x:Class="TestMvvm444.Views.CustomerHeaderView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<StackPanel HorizontalAlignment="Left">
<ItemsControl ItemsSource="Binding Path=Customers">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBox
Text="Binding Path=FirstName, Mode=TwoWay"
Width="100"
Margin="3 5 3 5"/>
<TextBox
Text="Binding Path=LastName, Mode=TwoWay"
Width="100"
Margin="0 5 3 5"/>
<TextBlock
Text="Binding Path=FullName, Mode=OneWay"
Margin="0 5 3 5"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
Customer.cs(模型):
using System.ComponentModel;
namespace TestMvvm444.Model
class Customer : INotifyPropertyChanged
public int ID get; set;
public int NumberOfContracts get; set;
private string firstName;
private string lastName;
public string FirstName
get return firstName;
set
if (firstName != value)
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
public string LastName
get return lastName;
set
if (lastName != value)
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
public string FullName
get return firstName + " " + lastName;
#region PropertChanged Block
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
#endregion
【问题讨论】:
【参考方案1】:为了验证,让您的视图模型实现IDataErrorInfo
。至于视图之间的通信,不要害怕编写 UI 服务(例如,允许视图模型提供将在 UI 中某处显示的消息的消息服务)。或者,如果视图模型之间存在硬关系(例如,一个视图模型拥有另一个视图模型),那么拥有的视图模型可以持有对子视图模型的引用。
【讨论】:
【参考方案2】:添加验证消息的一个非常简单的方法是使用绑定。
向您的视图模型添加一个可通知的属性,用于定义是否应显示验证消息:
private Boolean _itemValidatorDisplayed;
public Boolean ItemValidatorDisplayed
get return _itemValidatorDisplayed;
set
_itemValidatorDisplayed= value;
_OnPropertyChanged("ItemValidatorDisplayed");
添加一个将 bool 转换为可见性的转换器类:
using System;
using System.Windows;
namespace xxx
public class BoolToVisibilityConverter : IValueConverter
public bool Negate get; set;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
bool val = System.Convert.ToBoolean(value);
if (!Negate)
return val ? Visibility.Visible : Visibility.Collapsed;
else
return val ? Visibility.Collapsed : Visibility.Visible;
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
throw new NotImplementedException();
从视图绑定到属性并应用转换器:
<UserControl x:Class="ViewClass"
...
>
<UserControl.Resources>
<contract:BoolToVisibilityConverter Negate="False"
x:Key="BoolToVisibilityConverter" />
</UserControl.Resources>
...
<TextBlock Visibility="Binding Converter=StaticResource BoolToVisibilityConverter, Path=ItemValidatorDisplayed" />
...
</UserControl>
您需要将 ViewModel 设置为视图的数据上下文:
namespace xxx
public partial class ViewClass: UserControl
public ViewClass()
InitializeComponent();
this.DataContext = new ViewClass_ViewModel();
Bingo - 完美工作的验证被推送到任何愿意订阅此 ViewModel/Property 的视图。
【讨论】:
【参考方案3】:您还可以将验证绑定到 SL3 中的源对象集合:-)
【讨论】:
以上是关于如何发送验证消息表单模型以在 MVVM 模式中查看?的主要内容,如果未能解决你的问题,请参考以下文章
如何发送纯 JSON 对象(位于模型对象内)以在 Spring Boot 中查看?
Django使用不完整的模型创建一个有效的ModelForm,以在表单验证后手动添加字段