14

I am trying to use the TiltEffect from the Silverlight toolkit within a LongListSelector. This is how the element is declared in XAML:

<controls:PivotItem Header="Pivot Item">

  <controls:PivotItem.Resources>

    <DataTemplate x:Key="LongListSelectorGroupHeaderTemplate">
      <Border Background="{StaticResource PhoneAccentBrush}"
              Margin="10,20,0,0"
              HorizontalAlignment="Left"
              VerticalAlignment="Center"
              Height="{StaticResource PhoneFontSizeExtraExtraLarge}"
              Width="{StaticResource PhoneFontSizeExtraExtraLarge}">
        <TextBlock Text="{Binding Name}"
                   Style="{StaticResource PhoneTextExtraLargeStyle}"
                   Foreground="White"
                   VerticalAlignment="Bottom"
                   HorizontalAlignment="Left" />
      </Border>
    </DataTemplate>

    <DataTemplate x:Key="LongListSelectorGroupItemTemplate">
      <Border Background="{StaticResource PhoneAccentBrush}"
              Margin="10"
              Height="{StaticResource PhoneFontSizeExtraExtraLarge}"
              Width="{StaticResource PhoneFontSizeExtraExtraLarge}">
        <TextBlock Text="{Binding Name}"
                   Style="{StaticResource PhoneTextExtraLargeStyle}"
                   Foreground="White"
                   VerticalAlignment="Bottom"
                   HorizontalAlignment="Left" />
      </Border>
    </DataTemplate>

    <DataTemplate x:Key="LongListSelectorItemTemplate">
      <StackPanel Grid.Column="1"
                  VerticalAlignment="Top"
                  Orientation="Horizontal"
                  toolkit:TiltEffect.IsTiltEnabled="True">

        <toolkit:GestureService.GestureListener>
          <toolkit:GestureListener Tap="OnLongListSelectorTapped" />
        </toolkit:GestureService.GestureListener>

        <Image  Source="{Binding ImageSource}"
                MinHeight="32"
                MinWidth="32"
                MaxHeight="48"
                MaxWidth="48" />

        <TextBlock Text="{Binding Name}"
                   Style="{StaticResource PhoneTextExtraLargeStyle}"
                   Margin="12,10,12,0" />

      </StackPanel>
    </DataTemplate>

  </controls:PivotItem.Resources>

  <toolkit:LongListSelector ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
                            GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemplate}"
                            GroupItemTemplate="{StaticResource LongListSelectorGroupItemTemplate}">

    <toolkit:LongListSelector.GroupItemsPanel>
      <ItemsPanelTemplate>
        <toolkit:WrapPanel />
      </ItemsPanelTemplate>
    </toolkit:LongListSelector.GroupItemsPanel>

  </toolkit:LongListSelector>

</controls:PivotItem>

Unfortunately, this isn't working. The tap gesture fires when tapping on an item, but the animation does not play. I've tried setting TiltEffect.IsTiltEnabled property on the LongListSelector, the PivotItem and the parent page but none of them work.

I have another PivotItem that contains a simple ListBox with an ItemTemplate that is very similar to LongListSelectorItemTemplate above. Setting the TiltEffect.IsTiltEnabled property to true within its DataTemplate works as desired.

What am I doing wrong in the case of the LongListSelector?

Praetorian
  • 106,671
  • 19
  • 240
  • 328

6 Answers6

23

If you wrap your ItemTemplate in a ListBoxItem, it will tilt accordingly:

<DataTemplate x:Key="LongListSelectorItemTemplate">
  <ListBoxItem>
    <StackPanel Grid.Column="1"
                VerticalAlignment="Top"
                Orientation="Horizontal"
                toolkit:TiltEffect.IsTiltEnabled="True">

      <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener Tap="OnLongListSelectorTapped" />
      </toolkit:GestureService.GestureListener>

      <Image  Source="{Binding ImageSource}"
              MinHeight="32"
              MinWidth="32"
              MaxHeight="48"
              MaxWidth="48" />

      <TextBlock Text="{Binding Name}"
                 Style="{StaticResource PhoneTextExtraLargeStyle}"
                 Margin="12,10,12,0" />
    </StackPanel>
  </ListBoxItem>
</DataTemplate>
RajenK
  • 1,403
  • 3
  • 15
  • 25
3

The way TiltEffect works is that is contains a list of Types that it will tilt, by deafult these are Button and ListBoxItem. It then drills down through the visual tree from where you turn it on and adds the effect to all instances of those classes. So your LongListSelector.ItemTemplate needs to contain a tiltable item. The easiest way to do this is with an invisible button, that way you do not need to edit your TiltEffect and can use it straight out of the toolkit. If you really don't want the button, then you need some other ContentControl to wrap your template from which you can trigger the tilting. Then add that class to the TiltEffect list.

TiltEffect.TiltableItems.Add(typeof(MyTiltingContentControl))

I use this style on my button to make it invisible.

<Style x:Key="TiltButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="{x:Null}" />
        <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
        <Setter Property="Padding" Value="0,0,0,0"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="Transparent">
                        <Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="0,8,0,0">
                            <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
Chris Sainty
  • 9,086
  • 1
  • 26
  • 31
1

Step-by-step instructions on how to use the tilt effect can be found on MSDN

Derek Lakin
  • 16,179
  • 36
  • 51
  • 1
    Thanks for the link, if I add `TiltEffect.TiltableItems.Add( typeof( LongListSelector ) );` to the page constructor it takes effect, but now the whole LongListSelector element tilts instead of just the item that was tapped! How do I get just that individual item to tilt? – Praetorian Feb 19 '11 at 23:08
1

Adding this portion of code between the "Style" Tag in a Button template did exactly what I wanted. Make the button keep it's color when "tilted". I have set the button background to PhoneAccentBrush, so the user decides on the app look and feel with his theme settings.

<Style x:Key="MetroButton" TargetType="Button">
    <Setter Property="Background" Value="{StaticResource PhoneAccentBrush}"/>
    <Setter Property="Height" Value="200"/>
    <Setter Property="Width" Value="200"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="0,8,0,0">
                        <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
0

TiltEffect.IsTiltEnabled="True" goes on the PhoneApplicationPage element, change your ItemTemplate to contain a button and it will work.

karl.r
  • 961
  • 1
  • 11
  • 28
  • TiltEffect does not have to be applied to the whole page, from MSDN `You can apply the dependency property globally so that all controls in the visual tree inherit the tilt effect, or you can apply the dependency property to only a single control if desired.` And I don't want a button in my ItemTemplate! – Praetorian Feb 19 '11 at 23:06
0

Create a new control inherits stackpanel

public class TiltStackPanel : StackPanel
    {
        public TiltStackPanel() {}
    }

then add this control TiltEffect.cs

static TiltEffect()
    {
      // For extra fun, add this to the list: typeof(Microsoft.Phone.Controls.PhoneApplicationPage)
      TiltableItems = new List<Type>() { typeof(ButtonBase), typeof(ListBoxItem), typeof(TiltStackPanel)};
      UseLogarithmicEase = false;
    }

Use this TiltStackPanel inside your template of longlistselector

Jan Michael.G
  • 183
  • 1
  • 11
  • I tried to do this but for some reason the individual StackPanels within the TiltableStackPanel were tilting, instead of the whole thing moving as a single entity. Also, you do not need to edit the TiltEffect source, just add `TiltEffect.TiltableItems.Add( typeof( TiltableStackPanel ) );` in your code. – Praetorian Feb 23 '11 at 17:38
  • use the TiltStackPanel as the main wrapper of the template to make it as one entity. Then inside this, you can use the regular stackpanel – Jan Michael.G Feb 24 '11 at 07:13