簡體   English   中英

MVVM:僅當數據有效時,使綁定更新ViewModel

[英]MVVM: Make Binding update ViewModel only when data is VALID

我有一個實現IDataErrorInfo接口的ViewModel。 它只有一個屬性:MyNumber。

在我看來,有一個TextBox,用戶可以在其中輸入任何數字,但只有0到9之間的數字有效。

到目前為止,驗證失敗時,文本框將標記為紅色,但是我有一個問題:這無法避免在ViewModel中設置bound屬性。

簡而言之,無論輸入是否有效,都將設置MyNumber屬性。 我不希望MyNumber獲取無效數據。

如何以純MVVM方法實現這一目標?

非常感謝!

我建議您使用錯誤的方法。

如果您只想限制數字輸入,請不要使用標准的文本框。 而是使用一個限制輸入/格式有效的控件,例如WPF控件工具包中的IntegerUpDown / DecimalUpDown / DoubleUpDown-可通過Nuget獲得。 然后,您可以將此控件的值綁定到視圖模型中適當數字類型的字段。

經過一段時間的研究,我得出了一個非常令人滿意的解決方案:

由於我使用的是Sacha BarberCinch MVVM Framework ,因此ViewModel中需要驗證的屬性使用了一個非常方便的類,稱為DataWrapper。 它包裝了實際的屬性並提供了一些有用的功能。 實際上,我之前提到的MyProperty是一個DataWrapper。 我在其“規則”集合中添加了所需的規則“ x <= 5”。

關於DataWrapper類的一個很好的事情是,它包含一個名為“ IsValid”的屬性,該屬性指示實際值是否違反您為其設置的規則。

這會將所有需要檢查驗證的屬性封裝在包裝器中!

下一步是在XAML中設置到DataWrapper的綁定,但是我決定該綁定在DataWrapper包含VALID值時適用

警告。 前面有復雜的解釋。

您可以問我為什么需要這種行為。 這有點復雜。 該視圖就像一個向導,用戶可以在其中選擇模型的大小,顏色和其他圖形方面。 使用控件在視圖中表示模型。 為了簡化理解(比這稍微復雜一點),您可以假設模型是一個名為Portrait的類 ,它將在View中使用Border控件表示。 用戶在其中輸入Portrait的粗細的TextBox具有對ViewModel(前述的DataWrapper)中一個屬性的綁定,我將其稱為“ BorderThicknessWrapper”。 實際上,將Binding設置為BorderThicknessWraper.DataValue,因此在TextBox中鍵入內容會修改DataWrapper中保存的數據的實際值。

這樣,我們就擁有了用戶在ViewModel的TextBox中輸入的值。

現在,我們要制作代表模型的控件以反映更改。 我們說過,我們將以Border作為肖像的表示,因此BorderThicknessWrapper的每次更改都會修改Border的BorderThickness。 但是,等等,我們確實希望它代表有效值,所以在XAML中我有這個! 魔術;)

<Border>
  <Border.Style>
    <Style TargetType="{x:Type Border}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding BorderThickessWrapper.IsValid}" Value="True">
                <Setter Property="BorderThickness" Value="{Binding GutterWidth.DataValue}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Border.Style>

如您所見,Border具有帶DataTrigger的樣式,該樣式指出“當包裝器具有有效值時,請設置綁定”。 當該屬性無效時,將應用默認值。

到目前為止我們需要什么!

希望您了解解決方案。 它是純基於MVVM的:D,而且非常堅固!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM