2011-12-06 31 views
5

我在多個字段之間進行驗證時遇到了問題。例如 - 我有一個名爲RangeDateViewModel的ViewModel,它包含一個名爲DateViewModel的類的兩個實例,它們分別代表開始日期和結束日期。不同級別的多個字段之間的驗證

所以我結合這個樣子的 -

<TextBox Text="{Binding StartDate.Date, ValidateOnDataError=True}"> 
<TextBox Text="{Binding EndDate.Date, ValidateOnDataError=True}"> 

我RangeDateViewModel類實現了IDataErrorInfo的接口。 在我的計劃中,RangeDateViewModel將驗證的開始日期爲結束日期之前,由IDataErrorInfo的[「PROPERTYNAME」]功能類似這樣的應用程序的驗證邏輯 -

public string this[string columnName] 
    { 
     get 
     { 
      return ValidationError(); 
     } 
    } 

的問題是,這是從來沒有被調用,而是每個DateViewModel類中駐留的IDataErrorInfo屬性被調用。

我想這是因爲bound屬性不在RangeDateViewModel的同一級別,而是在子級DateViewModel內。

我認爲我的需求是相當基礎的,必須有一個簡單的解決方案來解決這個問題。 我嘗試使用ValidationRules而不是IDataErrorInfo,但然後我會讓ViewModel知道來自ValidationRules的當前驗證狀態的問題。

回答

1

嘗試使用以下方法:

  1. 創建DataTemplateDateViewModel

    <DataTemplate DataType="{x:Type ViewModels:DateViewModel}"> 
        <TextBox Text="{Binding Date}"> 
    </DataTemplate> 
    
  2. 綁定該視圖模型的實例到ContentControl中,並設置ValidateOnDataErrortrue上結合:

    <ContentControl Content="{Binding StartDate, ValidateOnDataError=True}" /> 
    <ContentControl Content="{Binding EndDate, ValidateOnDataError=True}" /> 
    
  3. RangeDateViewModel訂閱PropertyChanged事件的StartDateEndDate並提出時,提出一個PropertyChanged事件與StartDate/EndDate

    StartDate.PropertyChanged += (s, e) => InvokePropertyChanged("StartDate"); 
    EndDate.PropertyChanged += (s, e) => InvokePropertyChanged("EndDate"); 
    
+0

謝謝丹尼爾!我嘗試了你的建議,但顯然它還不夠好。 IDataErrorInfo屬性實際上是訪問,但僅在模板初始化時,而不是在實際數據更改時。我想這是因爲StartDate和EndDate是複雜的對象,它們本身並沒有被改變,但它們內部的屬性並不足以形成PropertyChanged。也許我應該在內部日期屬性更改時以某種方式提出事件? – Dror

+0

@Dror:你說得對。請參閱已更新答案中的第三步。 –

+0

再次感謝丹尼爾!儘管我仍然面臨着最後一個小問題,但這一切都奏效。使用此解決方案時,結果是兩個控件在數值無效時標記爲紅色。我希望不是將它們標記爲紅色,而是將包含這兩個字段的Stackpanel標記爲已讀。最好這兩個字段不會被標記,但它不是必須的。我試圖在名爲「HasErrors」的RangeDateViewModel的bool屬性上應用DataTrigger,該屬性將「Validation.HasError」設置爲true,但不幸的是它是隻讀屬性。我希望你能幫我解決這個問題。 – Dror

1

我有public string this[string columnName]是根本不只是叫其他問題周。

該解決方案很簡單。 綁定WPF綁定引擎無法跟隨我的ViewModels的嵌套。

我認爲我需要實現在視圖模型的屬性,它是當前的DataContext,但而是它需要在視圖模型是綁定到控制實施。

實施例:

<TextBox Text="{Binding Path=ProductViewModel.DescriptionViewModel.ProductName, 
            Mode=TwoWay, 
            ValidatesOnDataErrors=True, 
            NotifyOnValidationError=True}" /> 

這裏DescriptionViewModel是包含綁定屬性的類。IDataErrorInfo需要在該類中實現(而不是ProductViewModel或其他可能包含它的層次結構中),那麼一切都會正常工作。

+0

嗨老師,謝謝你的評論。我知道IDataErrorInfo在綁定層次結構中的較低類中實現時工作正常,但我得到了兩個問題。 1 - 我得到了兩個參與驗證邏輯的類,但是這些低級類中的每一個都不知道對方。 2 - 如果該值無效,我不希望只有其中一個字段被標記爲紅色。我想把整個控件標爲紅色。 – Dror