Search code examples
xamldata-bindinguwpparallax

How to Bind Parallax View within GridView DataTemplate?


I am trying to use a ParallaxView to make an image within the GridViewItem parallax as the GridView is scrolled. The intended effect is the same as the newsfeed in the Xbox UWP app on PC; images on the listview items there parallax as you scroll. This is shown visually in the following image:

Annotated Layout Screenshot

I am running into a databinding data context issue, however. All of the examples I have seen are to make the background of the entire GridView or ListView parallax. A working example of that is as follows (very similar to the XAML Controls Gallery Sample found here):

    <Grid>
        <ParallaxView Name="GridViewParallaxView"
                      Source="{x:Bind MyGridView}"
                      VerticalShift="100">
            <!-- This is the background image that parallaxes. -->
            <Image></Image>
        </ParallaxView>

        <GridView Name="MyGridView">
            <!-- GridView Content Here... -->
        </GridView>
    </Grid>

The problem I am running into is when trying to place the ParallaxView INSIDE of the DataTemplate in the ItemTemplate in the GridView.

<GridView Name="MyGridView"
          ItemsSource="{x:Bind MyDataList}">
        <GridView.ItemTemplate>
            <DataTemplate x:DataType="models:MyDataType">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"></RowDefinition>
                        <RowDefinition Height="Auto"></RowDefinition>
                    </Grid.RowDefinitions>

                    <ParallaxView Name="GridViewParallaxView"
                                  Grid.Row="0"
                                  Source="{x:Bind MyGridView}"
                                  VerticalShift="100">
                        <!-- This is the image  ON EACH GRIDVIEW ITEM that parallaxes. -->
                        <Image Source="{x:Bind MySource}"></Image>
                    </ParallaxView>

                    <TextBlock Name="ItemTitleTextBlock"
                               Grid.Row="1"
                               Text="{x:Bind Title}"></TextBlock>
                </Grid>
            </DataTemplate>
        </GridView.ItemTemplate>
</GridView>

Note that some properties (like MinWidth and Margin) have been omitted for brevity.

The code behind (not totally relevant, but to add context to some of the bindings):

public class MyPage : Page
{
    public ObservableCollection<MyDataType> MyDataList { get; set; }
}

public class MyDataType
{
    public string Title { get; set; }
    public ImageSource MySource { get; set; }
}

This does not work because placing the 'ParallaxView' inside of the 'DataTemplate' changes the 'DataContext'. MyGridView can no longer be bound to directly like that. So how do I bind it?

Also, I read that the DataContext property is inherited by children in the XAML tree. I need the Image databinding to be in the same context as the DataTemplate. Is there a way to just change the DataContext for the ParallaxView?


Solution

  • You could use Binding, instead of x:Bind.

    <ParallaxView Name="GridViewParallaxView"
                                  Grid.Row="0"
                                  Source="{Binding ElementName=MyGridView}"
                                  VerticalShift="100">
                            <!-- This is the image  ON EACH GRIDVIEW ITEM that parallaxes. -->
                            <Image Source="{x:Bind MySource}"></Image>
    </ParallaxView>