2017-09-14 44 views
0

我在我的模型对象中使用IDataErrorInfo进行视图验证时遇到了问题。 我有一个使用ModernWindow控件的几个页面的应用程序。MVVMLight - ModernWindow - 验证

在启动时,验证工作正常。但是,一旦我在视图中进行了一次导航,当我回到已经访问过的视图之一时,验证不再起作用,但IDataErrorInfo赋值方法被调用,在框架的运行知识中有些东西想我。

如果有人已经遇到了这个问题,他是对的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> 
+0

您能否给我们提供您的代码 – Coding4Fun

+1

请尝试以下操作:将相关XAML零件包装在一个''元素中。在一些特殊情况下,当共享装饰层时,错误模板可视化会变得有缺陷。我在其中一个项目中观察到了一个可能类似的问题,并通过为每个“TabItem”使用单独的装饰层来解决它。我不知道你的问题是否一样。 – grek40

+0

grek40,对不起,我忘了加入textboxstyle文件代码。我已经使用它。如何,我注意到,一旦ViewModelLocator通过IOC机制得到了viewmodel实例,sendUser方法就不再被调用。 MyUser对象的RaisePropertyChanged也不再被触发。 –

回答

1

有时窗口AdornerLayer不能正常更新时内心观念的转变。我注意到这是TabControl,其中标签之间的切换并不总是触发正确的装饰者更新。其他类型的视图更改控件可能受同一事物影响。

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

TabControl情况下,转型将是如下:

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

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

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

+0

确定你在之前的评论中是完全正确的,我通过这种方式修复了它;) –