2010-07-16 110 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