wpf数据绑定时序问题

时间:2010-07-16 01:16:24

标签: wpf validation data-binding

我的装订有问题。但我找不到它

我有一个状态类型控件(UserControl),它有一个ItemsControl,其绑定依赖于提供BrokenRules列表的ViewModelBase对象,如下所示:

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

绑定按我想要的方式工作,从某种意义上说,显示任何和所有损坏的规则描述。规则几乎只是在规则被告知验证自身时执行的描述和委托。

在要求规则验证自身之前,大多数规则都有预先知道的描述。例如,如果验证委托!Name.IsNullOrEmptyAfterTrim()失败,则“Name not not valued”是对错误的详细描述。

问题在于一个特定的规则,它会检查重复的名称。如果重复检查失败,我希望能够说出重复的值是什么,这是不可能事先知道的。因此,规则需要在执行验证委托时更新描述。

当我在验证委托中进行单元测试或保留调试跟踪时,会更新损坏的规则说明。但是当我运行应用程序时,破坏的规则描述就是在更新之前的内容。

我猜测我的绑定不正确。任何人都可以建议问题/修复是什么?

干杯,
Berryl

更新====================

这是我的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;
    }

1 个答案:

答案 0 :(得分:1)

您必须确保BrokenRules可观察集合实例不会更改,View Model上的代码应如下所示:

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上。