2010-07-18 53 views
2

我有問題: 我在窗體(複選框,組合框,滑塊,文本框)上有一些控件。它們的值綁定到視圖模型的不同屬性。
當視圖模型的屬性具有特定值時,我想讓這些控件「固定」(顯示錯誤消息並將它們設置爲某個固定值(例如:當用戶未選中該複選框時試圖檢查它,滑塊設置爲一個特定的值,組合的選定項目是列表中的第二項) 我這樣做了這個(文本框的簡化示例): 在視圖中:使用MVVM模式強制驗證錯誤的視圖更新

  <TextBox 
       Text="{Binding ViewModelProperty, 
           NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, 
           ValidatesOnDataErrors=True, NotifyOnValidationError=True}" 
       /> 

在視圖模型: 的屬性被定義如下:

String _ViewModelProperty; 
public String ViewModelProperty 
{ 
    get 
    { 
     return _ViewModelProperty; 
    } 
    set 
    { 

     _ViewModelProperty = value; 
     OnPropertyChanged("ViewModelProperty"); 
    } 
} 

和IDataErrorInfo的實施:

String IDataErrorInfo.this[String propertyName] 
{ 
    get 
    { 
     String error = null; 
     if (propertyName == "ViewModelProperty") 
     { 
      if (ViewModelProperty != "FixedValue") 
      { 
       error = DisplayMessage("You can only set a fixed value here"); 
       ViewModelProperty= "FixedValue"; 
      } 
     } 
     return error; 
    } 
} 

這非常適用的複選框,但對於所有其他控件,它的功能是這樣的:用戶設置了「錯誤」的值,則顯示錯誤信息然後,而不是用固定值更新控件,仍然顯示錯誤的值(它不再與視圖模型同步)。

我想不出如何強制更新控件的值。

預先感謝您。

+0

爲什麼你允許用戶更改控件,如果它是固定的,它允許什麼? – Goblin 2010-07-18 12:34:22

回答

0

您可以將要修復的控件的IsEnabled屬性綁定到ViewModel上的一組屬性,如CanUserChangeSlider。因此,在二傳手的組合框綁定屬性

<Slider IsEnabled={Binding CanUserChangeSlider} ... /> 

set 
{ 
    // store value in backing store 
    // RaisePropertyChanged 

    if (value == true) 
    { 
    this.CanUserChangeSlider = false; 
    // the bound property for slider set to certain value 
    // the bound property for combobox changed to be a certain value 
    } 
} 
0

迫使重新綁定方法是調用BindingExpression.UpdateTarget()BindingExpression.UpdateSource()適當。

當然,你不希望這在你的視圖模型。

因爲我注入視圖模型轉換成我的看法,使他們可以在視圖構造函數中DataContext,我會做類似如下:

  • 聲明委託或事件的視圖模型將被稱爲或當數據被裹挾在視圖構造
  • 從屬性setter升高,附加一個處理程序,將調用上述(也,重寫Dispose()和刪除的處理程序)
如所描述的適當的更新方法的代表

基本上,每當數據被強制時就引發一個事件,並傳遞視圖需要重新綁定到視圖模型的數據。

這不在我的頭頂,所以我沒有計算出代理簽名中可能需要的確切參數,也沒有說明可以使處理程序與您的所有字段配合使用的程度。不過,這也許是一個起點。

0

我不使用IsEnabled屬性,因爲這些是要求:沒有禁用,只有設置「無效」值時才顯示消息。
其他要求不是將視圖模型注入到視圖中...我們有一些將視圖與視圖模型鏈接的「工作空間」類,因此沒有視圖知道附加到視圖模型實例。當然,注射可以從工作區中進行......我嘗試過這種方法,但仍然無法工作。
但是,沒有任何其他優雅和MVVM-ISH方法做到這一點? 我準備了一個非常簡單的例子來說明我的問題。
我有2個文本框,綁定到相同屬性的視圖模型:

<StackPanel> 
    <Label>First text box</Label> 
    <TextBox 
     Text="{Binding Path=Property, 
       NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, 
       ValidatesOnDataErrors=True, NotifyOnValidationError=True}" 
    /> 
    <Label>Second text box</Label> 
    <TextBox 
     Text="{Binding Path=Property, 
       NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, 
       ValidatesOnDataErrors=True, NotifyOnValidationError=True}" 
     /> 
</StackPanel> 

視圖模型具有IDataErrorInfo的實現:

public String this[String propertyName] 
{ 
    get 
    { 
     String error = null; 
     if (propertyName == "Property") 
     { 
      if (Property != "1000") 
      { 
       error ="Only value '1000' is accepted here."; 
       MessageBox.Show(error, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 
       Property = "1000"; 
      } 
     } 
     return error; 

    } 
} 

最初,該值是「1000」。
如果我在一個文本框中添加「0」,則會顯示該消息,另一個文本框會正確更新爲「1000」,但聚焦的文本框的值將保持爲「10000」。
我覺得我很想念這裏必不可少的東西。

Lucia