Мой класс ViewModel имеет дочернее свойство типа 'Messages', которое имеет индексированное свойство, например:
public class ViewModel
{
// ...
public Messages Messages
{
get
{
if (_messages == null)
{
LoadMessagesAsync();
_messages = new Messages();
}
return _messages;
}
set
{
_messages = values;
PropertyChanged(new PropertyChangedArgs("Messages");
}
}
// ...
private void LoadMessagesAsync()
{
// Do the service call
Messages = theResult;
}
}
public class Messages
{
// ...
public String this[String name]
{
get { return _innerDictionary[name]; }
}
// ...
}
Не думаю, что мне нужно заполнять оставшиеся пробелы, так как все просто.
Проблема, с которой я столкнулся, заключается в том, что привязка не обновляется, когда я устанавливаю свойство Messages для нового объекта. Вот как я ссылаюсь на свойство в XAML (с ViewModel в качестве DataContext):
<TextBlock Text="{Binding Messages[HelloWorld]}" />
Я предполагал, что привязка обновится, когда будет вызвано событие PropertyChanged для свойства «Сообщения».
В другом месте я читал, что мой класс Messages должен вызывать событие PropertyChanged с пустой строкой (""), "Item []" или "Item [" + name + "]" для имени свойства. Однако, так как я полностью заменяю объект Messages, это не сработает, так как я никогда не изменяю содержимое.
Как мне сделать эту работу?
UPDATE
Итак, я немного покопался в поведении и в исходном коде BCL, чтобы увидеть, что ожидается, как способ выяснить, как заставить мой код работать. То, что я узнал, состоит из двух частей:
Во-первых, привязка данных Silverlight фактически рассматривает возвращаемый объект из свойства Messages в качестве источника привязки. Таким образом, поднятие PropertyChanged из ViewModel (отправитель ViewModel) не обрабатывается привязкой. На самом деле мне нужно вызвать событие из класса Messages.
Это ничем не отличается от использования следующего: Text = {Binding Messages.HelloWorld} "
Причина, по которой работает код Майлза, заключается в том, что «Данные» возвращают «это», поэтому привязка обманывается, рассматривая родительский класс как источник привязки.
Тем не менее, даже если я сделаю так, чтобы мой дочерний объект вызвал событие, он все равно не будет работать. Это связано с тем, что привязка использует System.Windows.IndexerListener в качестве цели привязки. В методе SourcePropertyChanged слушатель проверяет, является ли имя свойства "Item []", но не предпринимает никаких действий. Следующий оператор делегирует PropertyListener, который проверяет имя свойства и обрабатывает событие, только если оно равно "Item [HelloWorld]".
Итак, если я не вызову явное событие для каждого возможного значения в моей коллекции, пользовательский интерфейс никогда не будет обновляться. Это разочаровывает, потому что другие статьи и сообщения указывают, что «Item []» должен работать, но если посмотреть на источник, это доказывает обратное.
Тем не менее, я все еще надеюсь, что есть способ достичь моих целей.