Получить уведомление об изменении DataContext в ресурсе WPF - PullRequest
2 голосов
/ 11 мая 2010

У меня раздражающая проблема с привязкой WPF. По сути, я объявляю FrameworkElement в ресурсах моего UserControl, но этот элемент, похоже, не получает уведомление при изменении DataContext родительского UserControl.

По сути, в моем UserControl у меня есть всплывающее окно в ItemTemplate для ItemsControl. В этом всплывающем окне мне нужно было привязать что-то в ViewModel родительского представления, поэтому я придумал хитрый трюк. Пользуясь репликой из CollectionViewSource, я решил связать модель представления моего родителя с ресурсом, а затем использовать этот ресурс для перехода к ViewModel из DataTemplate, например, так:

    <UserControl.Resources>
        <cont:ViewModelSource Source="{Binding}" x:Key="ParentViewModel"/>
    </UserControl.Resources>

Чтобы потом я мог использовать его как:

CommandParameter="{Binding ViewModel.OpenEntity, Source={StaticResource ParentViewModel}}"

Казалось бы, все это работает , за исключением , что DataContext в ViewModelSource не сбрасывается, когда DataContext из UserControl сбрасывается. Прямо сейчас я делаю эту работу хакерски: устанавливая DataContext ресурса в code-behind для события DataContextChanged UserControl.

Я посмотрел в Reflector, чтобы увидеть, как CollectionViewSource делает это, но, похоже, он не делает ничего особенного.

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

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

У меня была такая же проблема, и я нашел решение.

Сначала я попытался установить ViewModel в качестве DataContext моего корневого элемента. неправильно.

Затем я попытался установить свой ViewModel в качестве ресурса и установить источник привязки моего корневого элемента к ресурсу. неправильно.

Наконец, я создал IValueConverter для преобразования модели (ведь это DataContext элемента управления) в ViewModel. Затем я связываю DataContext моего корневого элемента с конвертером.

<UserControl.Resources>

    <local:PersonToControllerConverter x:Key="PersonToControllerConverter"/>

    <!--<local:PersonController x:Key="controller"
        Value="{Binding}"
        Parent="{Binding Path=DataContext,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
        />-->

</UserControl.Resources>



<Border x:Name="root" BorderBrush="Black" BorderThickness="2" >
    <Border.DataContext>
        <MultiBinding Converter="{StaticResource PersonToControllerConverter}">
            <Binding/>
            <Binding Path="DataContext" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}"/>
        </MultiBinding>
    </Border.DataContext>

    <!--DataContext="{Binding Source={StaticResource controller}}">-->

    <!--<Border.DataContext>
        <local:PersonController
                    Value="{Binding}"
                    Parent="{Binding Path=DataContext,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
                    />
    </Border.DataContext>-->

Я думаю, что когда DataContext нарушает привязку в элементе, когда datacontext изменяется на корневом элементе, он останавливается на сломанной привязке.

1 голос
/ 09 января 2011

Может быть, вам нужно создать средний объект, который реализует интерфейс INotifyPropertyChanged.

...