我希望其他地方没有问过这个问题,但是我很难找到合适的搜索字词来提出这个问题已经存在的答案。
我正在C#WPF(MVVM)中实现一个程序,其中有许多采访式屏幕,用户可以有序地输入科学数据。我们希望Textbox
和DataGrid
根据用户是否已输入该控件中的数据作为默认值,单独更改前景色和背景色。由程序,或者是用户导入的另一个文件的模板值。除此之外,我们希望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数组)数据及其相关的自定义类)。
有什么想法吗?我已经阅读过有关自定义验证的内容,但在这种情况下,我还没有看到这可能会有什么帮助。
答案 0 :(得分:0)
忽略一起使用IDataErrInfo验证,因为看起来你真的想让它成为4个值中的一个......而'坏'数据恰好就是其中之一。
你需要将物品保持在平坦的运动场上,因为你对它们的处理方式是相同的,只是区分颜色。使用单个属性,其中对象包含ViewModel中的值和模型的状态。忽略IDataErroInfo,然后使用转换器提供着色,然后将一个委托添加到AdornerString,该委托将设置为ViewModel中为其编写的验证函数。