1
votes

I am finding the need to bind to the DataContext of a Page which is set like this:

<d:Page.DataContext>
    <designTime:PayeesPageDesignViewModel />
</d:Page.DataContext>

At design time. However, I need to bind to it from a child control that has a different data context:

<GridView x:Name="PayeesGridView"
          Margin="0,30,0,0"
          IsItemClickEnabled="True"
          ItemsSource="{Binding Payees}"
          SelectionChanged="PayeesGridView_OnSelectionChanged">

Since the ItemsSource is set for the GridView, the DataContext of my GridViewItems is set to the individual Payee objects in the Payees collection. My ViewModel has a property that I need to reference from the View in a converter to determine the visibility of an item.

I can set the visibility based on a property of the Payee object like this:

<Border Width="250"
        Height="250"
        Background="Gray"
        Opacity="0.85"
        Visibility="{Binding Path=IsOpen,
                     Converter={StaticResource AccountStatusToVisibilityConverter}}">

But what I really need to bind to is the Settings.ShowInactive property of the Page's DataContext. Is there a way to grab that context from a child control? I am using WinRT, so I don't have the benefit of the FindAncestor binding source.

EDIT

As suggested in the comments, I tried to change the binding to look like this:

Visibility="{Binding Path=DataContext.Settings.ShowInactivePayees, ElementName=PageName,
             Converter={StaticResource AccountStatusToVisibilityConverter}}">

But when I set a breakpoint in the AccountStatusToVisibilityConverter, the converter is never reached.

1
Give the Page an x:Name and use an ElementName Binding?Clemens
Ah, thanks. I knew there was a way to do it, but I couldn't figure it out. That's what I get for programming in the middle of the night :) I am trying to bind ElementName="PageName.DataContext" and Path="Settings.ShowInactivePayees" but the being passed is null even though the DesignTimeViewModel is hard-coded to be false and I try at runtime with ShowInactivePayees set to true or false.dub stylee
PageName.DataContext is not an element name. Your binding should certainly look like {Binding Path=DataContext.Settings.ShowInactive, ElementName=PageName}.Clemens
I thought that ElementName="PageName.DataContext" Path="Settings.ShowInactivePayees" and ElementName="PageName" Path="DataContext.Settings.ShowInactivePayees" were the same? Anyway, I am still getting null as the value being passed, regardless of the value of ShowInactivePayees.dub stylee
I added what the binding looks like now to my question. Now the converter isn't even firing. I am setting x:Name="PageName" and the compiler is recognizing everything, but I don't see why the converter is no longer firing.dub stylee

1 Answers

1
votes

How are you assigning the ItemTemplate in the GridView? What if instead of modifying the content of the template you changed the entire template? Like this pseudo xaml...

<Page.Resources>
    <DataTemplate x:Key="ActiveTemplate"></DataTemplate>
    <DataTemplate x:Key="InactiveTemplate"></DataTemplate>
    <local:IsActiveToItemTemplateConverter x:Key="IsActiveToTemplate"
        ActiveTemplate="{StaticResource ActiveTemplate}"
        InactiveTemplate="{StaticResource InactiveTemplate}"
        />
</Page.Resources>

<GridView
    ItemsSoucre="{Binding Payees}"
    ItemTemplate="{Binding Settings.ShowInactive, Converter={StaticResource IsActiveToTemplate}}"
    IsItemClickEnabled="{Binding Settings.ShowInactive, Converter={StaticResource BooleanNot}}"
    />