如何从模型中发送验证消息以在MVVM模式中查看?

Edw*_*uay 4 validation wpf mvvm

我有一个小型测试WPF MVVM应用程序,其中一个视图允许用户更改客户的名字或姓氏,全名自动更改,因此通信从M-to-MV-to-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>
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

Ken*_*art 6

要进行验证,请使用您的视图模型IDataErrorInfo.至于视图之间的通信,不要害怕编写UI服务(例如,允许和查看模型以提供将在UI中某处显示的消息的消息服务).或者,如果视图模型之间存在硬关系(例如,一个视图模型拥有另一个视图模型),则拥有视图模型可以保持对子视图模型的引用.