wpf проблема синхронизации данных - PullRequest
3 голосов
/ 16 июля 2010

Что-то не так с моей привязкой. Но я не могу найти это

У меня есть элемент управления типом состояния (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 () завершился неудачно.

Проблема связана с одним конкретным правилом, которое проверяет дубликаты имен. Если проверка на дублирование не удалась, я хочу иметь возможность сказать, что такое дублированное значение, которое невозможно узнать заранее. Таким образом, правило должно обновлять описание при выполнении делегата проверки.

Когда я выполняю модульное тестирование или оставляю трассировку отладки в делегате проверки, описание нарушенного правила обновляется. Но когда я запускаю приложение, описание нарушенного правила - это то, что было до того, как было обновлено.

Поэтому я предполагаю, что моя привязка неверна. Кто-нибудь может подсказать в чем проблема / починка?

Приветствия
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 Ответ

1 голос
/ 16 июля 2010

Вы должны убедиться, что экземпляр наблюдаемой коллекции 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, не уведомив об этом, и изменения не отразятся на пользовательском интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...