WPF Validation & IDataErrorInfo

4

请注意 - 我拥有的类是 EntityObject 类!

我有以下类:

public class Foo
{
    public Bar Bar { get; set; }
}

public class Bar : IDataErrorInfo
{
    public string Name { get; set; }

    #region IDataErrorInfo Members
    string IDataErrorInfo.Error
    {
        get { return null; }
    }

    string IDataErrorInfo.this[string columnName]
    {
        get
        {
            if (columnName == "Name")
            {
                return "Hello error!";
            }
            Console.WriteLine("Validate: " + columnName);
            return null;
        }
    }
    #endregion
}

XAML的语法如下:

<StackPanel Orientation="Horizontal" DataContext="{Binding Foo.Bar}">
     <TextBox Text="{Binding Path=Name, ValidatesOnDataErrors=true}"/>
</StackPanel>

我在那里加了一个断点和Console.Writeline,但是验证没有执行,也没有任何中断。有谁能指出我的错误所在吗?

6个回答

2
这可能是一个愚蠢的答案,但默认情况下,当 LostFocus 发生时,绑定会调用 setter。如果你还没有这样做,请尝试这样做。
如果你想在每次按键时触发错误代码,请在绑定中使用 UpdateSourceTrigger=PropertyChanged

1
你忘记在“Bar”类上实现INotifyPropertyChanged了,那么只有绑定系统才会触发setter。
所以你的'Name'属性很可能是这样的。
public string Name 
    { 
          get{ return _name; } 
      set
      {
          _name = value;
          RaisePropertyChanged("Name"); // Or the call might OnPropertyChanged("Name");
      }
    }

但正如我上面提到的 - Foo和Bar都是EntityObject类的子类(该类会通知OnPropertyChange)。 - Jefim
我其实在想,这个EntityObject父类可能会对此产生影响,因为IDataErrorInfo通常都能正常工作。 - Jefim
@Jefim:你所说的父/子类是什么意思?你所展示的Foo和Bar并没有继承任何东西。如果你的意思是Foo和Bar被声明为某个EntityObject派生类的内部类,那这根本不会改变任何事情。在C#中,内部类只影响外部类成员的public/protected/private可见性。它们对代码/事件/属性/继承等行为没有任何影响。 - quetzalcoatl

1

我不熟悉EntityObject类,也无法在.NET Framework文档或快速谷歌搜索中找到它。

无论如何,你需要使用NotifyOnValidationError

<TextBox Text="{Binding Path=Name, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"/>

1

您应该创建包含Bar类引用的本地窗口资源,并使用其键设置StackPanel数据上下文属性。此外,不要忘记在窗口或用户控件中导入其命名空间。

您的XAML代码应该像以下这样:

<Window x:Class="Project.WindowName"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:BarNamespace">  
<Window.Resources>
 <local:Bar x:Key="bar" />
</Window.Resources>
<StackPanel Orientation="Horizontal" DataContext="{StaticResource bar}">
      <TextBox Text="{Binding Path=Name, ValidatesOnDataErrors=true}"/>
</StackPanel> 
</Window>

1

尝试在绑定上设置Mode=TwoWay


我认为这是WPF的TextBox.Text依赖属性的默认设置,所以在这里并不重要。 - quetzalcoatl

-1

您应该将实现IDataErrorInfo的方法设置为公共方法。


OP正在使用显式接口实现;当这样做时,可见性修饰符是被禁止的。 - Bevan
在使用显式接口实现时,根本不需要 public。这仍然是接口的有效实现,并且将被接口客户端看到。 - quetzalcoatl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接