Получать уведомление об изменении DataContext в ресурсе WPF

У меня неприятная проблема с привязкой 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 ресурса в код программной части для события DataContextChanged UserControl.

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

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


person dks1983    schedule 11.05.2010    source источник


Ответы (2)


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

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

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

Наконец, я создал 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 разрывает привязку в элементе, когда текст данных изменяется в корневом элементе, он останавливается на разорванной привязке.

person Dargos    schedule 06.08.2010

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

person user526227    schedule 09.01.2011