超越数据验证样式:基于其他属性的样式

时间:2010-10-21 21:34:38

标签: c# wpf data-binding mvvm idataerrorinfo

我希望其他地方没有问过这个问题,但是我很难找到合适的搜索字词来提出这个问题已经存在的答案。

我正在C#WPF(MVVM)中实现一个程序,其中有许多采访式屏幕,用户可以有序地输入科学数据。我们希望TextboxDataGrid根据用户是否已输入该控件中的数据作为默认值,单独更改前景色和背景色。由程序,或者是用户导入的另一个文件的模板值。除此之外,我们希望UI响应来自ViewModel中实现的IDataErrorInfo的验证检查。

因此,TextBox中显示的数据如果是模板化值,则可以是蓝色;如果是程序默认值,则为绿色;如果是用户输入,则为蓝色,如果IDataErrorInfo表示数据为坏,则为红色。

我实现这个的最初答案是创建一个自定义类:

class AdornerString{

private string _myString;
private bool _isTemplate;
private bool _isDefault;

public string MyString{ 
  get{
      etc.
  }
  set{
      etc.
  }
}
// accessor properties and Constructors omitted for brevity
}

然后我在View中绑定了所有TextBox.Text属性,如下所示:

<TextBox Text="{Binding Path=someAdornerString.MyString,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}"/>

并应用DataTriggers的样式,该样式响应someAdornerString的属性以创建适当的颜色。

但是,ViewModel上的IDataErrorInfo不再验证TextBox。为什么会如此,是否有更好的方法来解决我的问题?我无法在AdornerString类中进行验证。

可能的解决办法,虽然不受欢迎:

我能想到的唯一其他解决方案是在ViewModel中为用户输入的每个字段提供两个属性 - 一个用于数据本身,另一个是与上面相同的自定义类减去字符串。但是,这意味着我无法概括用于文本框的样式。每个TextBox都必须有这样的自定义样式:

<TextBox.Style>
    <Style TargetType="{x:Type TextBox}"
           BasedOn="{StaticResource OtherStyle}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=**instanceCustomClass**.IsDefault}"
                         Value="True">
                <Setter Property="Foreground"
                        Value="Green" />
            </DataTrigger>
            <Trigger Property="Validation.HasError"
                     Value="true">
                <Setter Property="Foreground"
                        Value="OrangeRed" />
            </Trigger>
        </Style.Triggers>
    </Style>

因为每个UI字段都有一个与之关联的特定自定义类。

我真的不愿意这样实现,因为我可能有100多页输入屏幕,每个屏幕各有1-12 TextBox个,忽略混合中抛出的DataGrids(带有parellel数组)数据及其相关的自定义类)。

有什么想法吗?我已经阅读过有关自定义验证的内容,但在这种情况下,我还没有看到这可能会有什么帮助。

1 个答案:

答案 0 :(得分:0)

忽略一起使用IDataErrInfo验证,因为看起来你真的想让它成为4个值中的一个......而'坏'数据恰好就是其中之一。

你需要将物品保持在平坦的运动场上,因为你对它们的处理方式是相同的,只是区分颜色。使用单个属性,其中对象包含ViewModel中的值和模型的状态。忽略IDataErroInfo,然后使用转换器提供着色,然后将一个委托添加到AdornerString,该委托将设置为ViewModel中为其编写的验证函数。