Ошибки привязки при добавлении другого свойства - PullRequest
3 голосов
/ 13 декабря 2010

У меня есть основной вид, который привязывается к подобным подвидам (свойство поддержки имеет тип object):

<ContentControl Content="{Binding WalletsView}"/>

Теперь я добавил другое свойство в соответствующую модель представления, а именно

public SmartObservableCollection<Selectable<Type>> PriceGrabbers {get; private set;}

где SmartObservableCollection получено из ObservableCollection для упрощения многопоточных обновлений.

Теперь я получаю много ошибок привязки (на самом деле все привязки в подмоделях запускаются через окно отладки), как это (интересно, если я снова удалю свойство PriceGrabbers, все ошибки исчезают):

Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression: свойство 'OverviewHidden' не найдено в 'объекте' '' MainWindowViewModel '(HashCode = 30986197)'. BindingExpression: Path = OverviewHidden; DataItem = 'MainWindowViewModel' (HashCode = 30986197); целевой элемент - ColumnDefinition (HashCode = 22768693); Свойство target - «NoTarget» (тип «Объект»)

Таким образом, механизм привязки пытается найти любые привязки в основной модели представления. Привязки работают отлично. Хотя это нормально, я бы предпочел, чтобы ошибки исчезли. Кто-нибудь из вас уже сталкивался с этой проблемой, и если да, то как вы ее решили?

1 Ответ

0 голосов
/ 15 декабря 2010

Проблема не в WPF, а в том, что я использовал MEF в качестве контейнера композиции. Свойство изменяет порядок импорта классов, и ядро ​​ViewModel, отвечающее за MainWIndow, назначается сначала всем представлениям, после чего назначается правильный. Когда контекст данных обновляется, все привязки обновляются, поэтому приложение работает.

edit и теперь я нашел для этого полную причину.

SmartObservableCollection принимает параметр Action<Action>> для выполнения на CollectionChanged событиях, это необходимо из-за того, что большинство моих коллекций обновляется многопоточным способом, но события должны выполняться в потоке GUI, иначе вы получит исключение.

Для этого мои Виды выставляют Dispatcher.Invoke() и Dispatcher.BeginInvoke() как методы, которые я затем предоставляю коллекции.

При запуске DataContexts назначаются в базовом классе ViewModel следующими строками:

Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
{
    view.DataContext = this;
});

У кого уже есть идея?

Причиной такого подлога стал тот простой факт, что я добавил в коллекцию метод Dispatcher.Invoke() вместо Dispatcher.BeginInvoke(). Делая это (и факт, что это использовалось в MainWindowViewModel), он выполнялся до того, как любой DataContexts был назначен другому ViewModels.

Теперь, следующий шаг происходит - механизм WPF пытается привязать данные в вложенных представлениях. Поскольку DataContext равно null, механизм привязки перемещается вверх по визуальному дереву, пока не найдет набор DataContext, в этом случае первый набор DataContext находится в MainWindowView, и это MainWindowViewModel. Теперь, после завершения сбора, все остальные действия вызываются и DataContexts назначаются соответствующим образом, таким образом, повторно выполняется механизм привязки, который находит ненулевой DataContext во вложенных представлениях и правильно связывается.

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