2010-07-16 116 views
3

我的綁定有些問題。但我不能找到它wpf數據綁定時機問題

我有一個狀態類型控件(用戶控件),有一個ItemsControl與結合,依靠一個ViewModelBase對象,它提供BrokenRules的名單,像這樣的:

<ItemsControl ItemsSource="{Binding BrokenRules}" > 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <TextBlock> 
       <Hyperlink Foreground="Red" > 
        <TextBlock Text="{Binding Description}" /> 
       </Hyperlink> 
      </TextBlock> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

結合以我想要的方式工作,即顯示任何和所有破碎的規則說明。規則幾乎只是一個描述和一個委託,在規則被告知驗證自己時執行。

在規則被要求驗證自己之前,大多數規則都有預先知道的描述。例如,如果驗證委託!Name.IsNullOrEmptyAfterTrim()失敗,那麼「Name is not valued value」就是錯誤描述。

問題出現在一個特定的規則中,該規則檢查重複的名稱。如果重複檢查失敗,我想能夠說出重複的值是什麼,這是不可能知道的。所以規則需要在驗證委託執行時更新描述。

當我單元測試或在驗證委託中留下調試跟蹤時,更新了損壞的規則描述。但是當我運行應用程序時,破損的規則描述是之前被更新的內容。

因此,我猜測我的綁定是不正確的。任何人都可以提出什麼問題/修復?

乾杯,
Berryl

UPDATE ====================

這是從我ViewModelBase類代碼:

private readonly List<RuleBase> _rules = new List<RuleBase>(); 

// inheritors add rules as part of construction 
protected void _AddRule(RuleBase rule) { _rules.Add(rule); } 

public ObservableCollection<RuleBase> BrokenRules { get { return _brokenRules; } } 
protected ObservableCollection<RuleBase> _brokenRules; 

public virtual IEnumerable<RuleBase> GetBrokenRules()   { 
     return GetBrokenRules(string.Empty); 
} 

public virtual IEnumerable<RuleBase> GetBrokenRules(string property)  { 
    property = property.CleanString(); 

    _brokenRules = new ObservableCollection<RuleBase>(); 
    foreach (var r in _rules)   { 
     // Ensure we only validate this rule 
     if (r.PropertyName != property && property != string.Empty) continue; 

     var isRuleBroken = !r.ValidateRule(this); 

     if (isRuleBroken) _brokenRules.Add(r); 

     return _brokenRules; 
    } 
+0

您的ViewModelBase類是否實現INotifyPropertyChanged?即。 UI是否知道Description屬性何時更改? – 2010-07-16 01:20:21

+0

您是否將項目添加到BrokenRules集合中?它是一個ObservableCollection? – Anero 2010-07-16 01:25:45

+0

@Matt。是的,VmBase實現INPC。至於你的答案的第二部分,我認爲Aero接近它,如果我不每次都重新創建集合實例,那麼UI將保持與更改同步。需要通過tho工作。歡呼 – Berryl 2010-07-16 02:50:09

回答

1

您必須確保BrokenRules觀察集合實例不改變,你對視圖模型的代碼應該是這個樣子:

public ObservableCollection<BrokenRule> BrokenRules 
{ 
    get; 
    set; 
} 

private void ValidateRules() 
{ 
    // Validation code 
    if (!rule.IsValid) 
    { 
    this.BrokenRules.Add(new BrokenRule { Description = "Duplicated name found" }); 
    } 
} 

舉例來說,如果你做這樣的事情,而不是:

this.BrokenRules = this.ValidateRules(); 

你會改變這勢必會ItemsControl的集合而不通知它,變化不會在UI反映。

+0

我覺得你接近它。我的破碎規則列表不是ObservableCollection,它會在每個循環中創建一個新實例。我修復了集合類型,因爲這很簡單,下面我將看看如何使用相同的集合實例來完成此操作。你需要刪除不間斷的規則以及添加破碎的規則,所以它不是微不足道的。乾杯 – Berryl 2010-07-16 02:47:27

+1

@Berryl:你可以使用'.Clear()'而不是創建一個新的集合。這不會中斷數據綁定。 – Jens 2010-07-16 09:03:12

+0

這裏的所有評論的組合得到了這個正常工作。由於Anero是唯一可以標記爲答案的東西,因此我標記爲他的答案。謝謝大家! – Berryl 2010-07-16 16:59:32