Что-то не так с моей привязкой. Но я не могу найти егоwpf databinding timing issue
У меня есть контроль типа состояния (UserControl), который имеет 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() терпит неудачу.
Проблема связана с одним конкретным правилом, которое проверяет наличие дубликатов имен. Если проверка дубликатов не удалась, я хочу иметь возможность сказать, что такое дублированное значение, что невозможно узнать заранее. Поэтому правилу необходимо обновить описание, когда выполняется делегирование валидации.
Когда я тестирую модуль или оставляю трассировку отладки в делетете проверки, обновленное описание правила обновляется. Но когда я запускаю приложение, сломанное описание правила - это то, что было до было обновлено.
Я поэтому предполагаю, что привязка неверна. Может ли кто-нибудь предложить проблему/исправить?
Cheers,
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;
}
Включает ли ваш класс ViewModelBase INotifyPropertyChanged? то есть. Знает ли пользовательский интерфейс, когда свойство Description изменилось? –
Вы добавляете элементы в коллекцию BrokenRules? это ObservableCollection? – Anero
@ Matt. Да, VmBase реализует INPC. Что касается второй части вашего ответа, я думаю, что Aero близок к тому, что если я не буду воссоздавать экземпляр коллекции каждый раз, тогда пользовательский интерфейс останется синхронизированным с изменениями. Нужно работать с ним. Cheers – Berryl