2010-10-21 41 views
0

我希望这个问题在别处没有问过,但我很难找到正确的搜索条件来提出任何已经存在的对这个问题的答案。超越数据验证样式:基于其他属性的样式

我正在用C#WPF(MVVM)实现一个程序,其中有很多采访风格的屏幕,用户以有序的方式输入科学数据。我们希望TextboxDataGrid根据用户输入的该控件中的数据,程序输入的默认值还是模板,分别更改前景色和背景色来自用户导入的另一个文件的值。最重要的是,我们希望UI响应来自ViewModel中实现的IDataErrorInfo的验证检查。

因此,显示在文本框中的数据可能是蓝色的,如果它是一个模板值,如果程序默认为绿色,用户输入时为黑色,如果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 
} 

然后我在查看我所有的TextBox.Text属性的绑定,像这样:

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

和应用风格DataTriggers响应someAdornerString的属性来创建适当的颜色。

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

一个可能的方法,虽然不可取:

唯一的其他解决方案,我能想到的就是在视图模型的两个属性由用户一个用于数据本身和所输入的每个字段其他与上面相同的自定义类减去字符串。但是,这意味着我无法概括用于文本框的样式。每个文本框就必须有一个自定义的风格是这样的:

<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的每个屏幕,忽略混合中抛出的DataGrid(与parellel数组数组和他们的相关自定义类)。

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

+0

您是否无法简单地将TextBox的背景绑定到ViewModel上的属性,该属性将通过转换器运行并为您提供所需的“颜色”?忽略验证元素是因为从我收集的视觉概念来看,对于所有...只是不同的颜色。 – 2010-10-21 21:43:51

+0

@Aaron:那的确会解决非泛化风格的问题。嗯..它仍然会要求你至少有两个属性在ViewModel中用于UI中的每个字段:一个用于数据本身,另一个用于指示将其显示为哪种颜色的属性。我希望每个字段只有一个属性,但是如果我必须使用我发布的解决方案,您的建议将有所帮助。谢谢! – skybluecodeflier 2010-10-21 22:38:45

+0

@skybluecodeflier更多地将它看作定义状态。考虑到这一点,你有一个对象,其中包含字符串表示形式和数据来自哪里,即... TemplateValue。该对象类型将成为您将绑定到的ViewModel上的属性,因此可以根据需要封装相关数据。 – 2010-10-21 23:44:45

回答

0

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

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