MVVMLight - ModernWindow - 验证

时间:2017-09-14 09:56:08

标签: wpf validation mvvm-light idataerrorinfo

我的模型对象中使用IDataErrorInfo进行视图验证时出现问题。 我有一个使用ModernWindow控件的多个页面的应用程序。

启动时,验证工作正常。但是一旦我在视图上导航一次,当我回到已经访问过的视图之一时,验证不再工作,但是调用了IDataErrorInfo valiation方法,在框架的运行知识方面让我想念

如果有人已经遇到这个问题,欢迎他

ViewModel的示例代码:

public class MyViewModel : ViewModelBase 
{
     public readonly IDataAccessService ServiceProxy;
     private User _myUser
     public User MyUser
     {
         get { return _myUser; }
         set
      {
          _myUser= value;
           RaisePropertyChanged("MyUser");
      }
  }

   public MyViewModel(IDataAccessService serviceProxy)
{
    ServiceProxy = serviceProxy;
    MyUser = new User();

    ReadAllCommand = new RelayCommand(GetUsers);
    SaveCommand = new RelayCommand<User>(SaveUser);
    SearchCommand = new RelayCommand(SearchUser);
    SendProctorCommand = new RelayCommand<User>(SendUser);
    DeleteProctorCommand = new RelayCommand<User>(DeleteUser);
    ReceiveUser();

}
private void ReceiveUser()
{
    if (Proctor != null)
    {
        Messenger.Default.Register<MessageCommunicator>(this, (user) => {
            this.MyUser= user.User;
        });
    }
}

private  void SendUser(User user)
{
    if (user!= null)
    {

        Messenger.Default.Send<MessageCommunicator>(new MessageCommunicator()
        {
            User = user
        });                             
    }
}

实体代码(仅涉及问题的部分):

public partial class User : ObservableObject, IDataErrorInfo
{


[NotMapped]
public string Error
{
    get
    {
        return this[null];
    }
}

public string this[string columnName]
{
    get
    {
        string result = null;
        if (columnName == "Lastname")
        {
            if (string.IsNullOrEmpty(Lastname))
                result = "Please enter a lastname";
            else
            if (Lastname.Length < 5)
                result = "The lastname must have 5 characters at least";
        }

        ...
        return result;
    }
  }

XAML中一个字段的示例:

 <TextBox Grid.Column="1" Grid.Row="0"  x:Name="LastnameTextBox" TextWrapping="Wrap" Text="{Binding UpdateSourceTrigger=PropertyChanged, Path= MyUser.Lastname  ,Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=true}" LostFocus="LastnameTextBox_LostFocus" />

TextBoxStyle.Xaml:

 <Style TargetType="TextBox" x:Key="StandardTextBox">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <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>
        </Setter.Value>
    </Setter>

    <Setter Property="VerticalAlignment" Value="Center"></Setter>

</Style>

1 个答案:

答案 0 :(得分:1)

有时,当内部视图发生变化时,窗口AdornerLayer无法正确更新。我在TabControl中观察到这一点,其中标签之间的切换并不总是触发正确的装饰器更新。其他类型的视图更改控件可能会受到同样的影响。

解决方案是指定特定于将动态渲染/隐藏的控件的装饰图层。通过在AdornerLayer中包装控件来创建本地AdornerDecorator

如果是TabControl,转换将如下:

<!-- Before -->
<TabControl>
    <TabItem>
        <Content/>
    </TabItem>
</TabControl>

<!-- After -->
<TabControl>
    <TabItem>
        <AdornerDecorator>
            <Content/>
        </AdornerDecorator>
    </TabItem>
</TabControl>

您的布局应该有一些类似的容器/内容布局,其中可以包含AdornerDecorator