Wpf 在UI中使用数据模板时未触发IDataErrorInfo验证

Wpf 在UI中使用数据模板时未触发IDataErrorInfo验证,wpf,datatemplate,idataerrorinfo,Wpf,Datatemplate,Idataerrorinfo,我正在尝试根据ViewModel公开的属性构建我的应用程序设置页面。我将.NET4.0与MVVM一起使用。ViewModel公开单个“设置值组”集合。组表示相互依赖且属于wrt to域的逻辑组的属性。视图中的设置页面是使用DataTemplate创建的,如下所示:- <DataTemplate x:Key="contentSettingGroup1"> <TextBlock Text="{Binding Field1Description}" /> <Tex

我正在尝试根据ViewModel公开的属性构建我的应用程序设置页面。我将.NET4.0与MVVM一起使用。ViewModel公开单个“设置值组”集合。组表示相互依赖且属于wrt to域的逻辑组的属性。视图中的设置页面是使用DataTemplate创建的,如下所示:-

<DataTemplate x:Key="contentSettingGroup1">
  <TextBlock Text="{Binding Field1Description}" />
  <TextBox Text="{Binding Field1Value, Mode=TwoWay}" Grid.Column="2" />

  <TextBlock Text="{Binding Field2Description}"  />
  <TextBox Text="{Binding Field2Value, Mode=TwoWay}" Grid.Column="6" />
</DataTemplate>

<DataTemplate DataType="{x:Type vm:SettingGroup1}">
  <HeaderedContentControl Header="{Binding}" HeaderTemplate="{StaticResource titleArea}" Content="{Binding}" ContentTemplate="{StaticResource contentSettingGroup1}" />
</DataTemplate>

然后我在ViewModel模块中有一个类来表示“设置组”,如下所示:

public class SettingGroup1 : INotifyPropertyChanged, IDataErrorInfo
{
    public double Field1value { get; private set; }
    public double Field2value { get; private set; }

    private double mField1;
    public double Field1value
    {
        get { return mField1; }
        set
        {
            if (mField1 != value)
            {
                mField1 = value;
                RaisePropertyChanged(() => Field1value);
            }
        }
    }

    private double mField2;
    public double Field2value
    {
        get { return mField2; }
        set
        {
            if (mField2 != value)
            {
                mField2 = value;
                RaisePropertyChanged(() => Field2value);
            }
        }
    }

    public string Error
    {
        get { return null; }
    }

    public string this[string property]
    {
        get
        {
            string errorMsg = null;
            switch (property)
            {
                case "Field1value":
                    if (Field1value < 0.0)
                    {
                        errorMsg = "The entered value of Field1 is invalid !";
                    }
                    if (Field1value < Field2value)
                    {
                        errorMsg = "The Field1 should be greater than Field2 !";
                    }
                    break;
            }
            return errorMsg;
        }
    }
}
公共类设置组1:INotifyPropertyChanged,IDataErrorInfo
{
公共双字段1value{get;private set;}
public double Field2value{get;private set;}
私人双mField1;
公共双字段1值
{
获取{return mField1;}
设置
{
if(mField1!=值)
{
mField1=值;
RaisePropertyChanged(()=>Field1value);
}
}
}
私人双mField2;
公共双字段值
{
获取{return mField2;}
设置
{
if(mField2!=值)
{
mField2=值;
RaisePropertyChanged(()=>Field2value);
}
}
}
公共字符串错误
{
获取{return null;}
}
公共字符串此[字符串属性]
{
得到
{
字符串errorMsg=null;
交换机(属性)
{
案例“Field1value”:
如果(Field1value<0.0)
{
errorMsg=“字段1的输入值无效!”;
}
如果(Field1value
最后,viewModel公开了这组设置的集合:

public ObservableCollection<object> Settings
        {
            get
            {
                var pageContents = new ObservableCollection<object>();
                var group1 = new SettingGroup1();
                group1.Field1.Description = "Description value 1";
                group1.Field1.Value = mValue1;
                group1.Field2.Description = "Description value 2";
                group1.Field2.Value = mValue2;
                pageContents.Add(group1);

                // add other groups of controls
                // ...
                return pageContents;
            }
        }
公共可观测采集设置
{
得到
{
var pageContents=新的ObservableCollection();
var group1=新设置的group1();
group1.Field1.Description=“描述值1”;
group1.Field1.Value=mValue1;
group1.Field2.Description=“描述值2”;
group1.Field2.Value=mValue2;
pageContents.Add(group1);
//添加其他控件组
// ...
返回页面内容;
}
}
问题:属性设置器被调用,但只要用户界面值发生更改,数据验证就不会被调用。我也尝试过将IDataErrorInfo实现放在ViewModel类中,但都不起作用。我必须使用一组设置,因为这些应用程序设置在许多项目中使用,我们不希望每个应用程序都有重复的XAML。
注意:viewmodel没有公开UI绑定到的属性,例如Field1Value,而是公开了一个封装的对象。

您没有告诉视图您绑定到的属性需要验证。在绑定中使用“validateSondaerRors=true”

<TextBox Text="{Binding Field1Value, Mode=TwoWay, ValidatesOnDataErrors=True}" Grid.Column="2" />