Note that there are some explanatory texts on larger screens.

plurals
  1. POCustomizing WPF ListView control to use SurfaceScrollViewer
    text
    copied!<p>Is there a way to customize the stock WPF ListView control so that it uses a SurfaceScrollViewer (from the <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=801907A7-B2DD-4E63-9FF3-8A2E63932A74" rel="nofollow">Microsoft Surface Toolkit for Windows Touch Beta</a>) instead of a stock ScrollViewer when presenting its GridView?</p> <p>I've tried looking at the <a href="http://msdn.microsoft.com/en-us/library/aa970773.asp" rel="nofollow">XAML files that describe the stock ListView control</a> but I am new to WPF programming so I'm not sure how I could customize that XAML for my desired behaviour.</p> <p>I tried using Expression Blend to retemplate the stock listbox control to use a SurfaceScrollViewer, and ended up with this template:</p> <pre><code> &lt;Style x:Key="SurfaceListView" TargetType="{x:Type ListView}"&gt; &lt;Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/&gt; &lt;Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/&gt; &lt;Setter Property="BorderThickness" Value="1"/&gt; &lt;Setter Property="Foreground" Value="#FF042271"/&gt; &lt;Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/&gt; &lt;Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/&gt; &lt;Setter Property="ScrollViewer.CanContentScroll" Value="true"/&gt; &lt;Setter Property="ScrollViewer.PanningMode" Value="Both"/&gt; &lt;Setter Property="Stylus.IsFlicksEnabled" Value="False"/&gt; &lt;Setter Property="VerticalContentAlignment" Value="Center"/&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type ListView}"&gt; &lt;Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true"&gt; &lt;s:SurfaceScrollViewer Padding="{TemplateBinding Padding}" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}"&gt; &lt;ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/&gt; &lt;/s:SurfaceScrollViewer&gt; &lt;/Microsoft_Windows_Themes:ListBoxChrome&gt; &lt;ControlTemplate.Triggers&gt; &lt;Trigger Property="IsGrouping" Value="true"&gt; &lt;Setter Property="ScrollViewer.CanContentScroll" Value="false"/&gt; &lt;/Trigger&gt; &lt;Trigger Property="IsEnabled" Value="false"&gt; &lt;Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/&gt; &lt;/Trigger&gt; &lt;/ControlTemplate.Triggers&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; </code></pre> <p>This didn't produce the effect I wanted, however, as the GridView seems to hijack the scrolling behaviour and it's still row-by-row rather than the smooth panning I would have expected with the SurfaceScrollViewer. I suspect the issue might be with the following ScrollViewer template, also defined in the template:</p> <pre><code> &lt;Style x:Key="{x:Static GridView.GridViewScrollViewerStyleKey}" TargetType="{x:Type ScrollViewer}"&gt; &lt;Setter Property="Focusable" Value="false"/&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type ScrollViewer}"&gt; &lt;Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true"&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width="*"/&gt; &lt;ColumnDefinition Width="Auto"/&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="*"/&gt; &lt;RowDefinition Height="Auto"/&gt; &lt;/Grid.RowDefinitions&gt; &lt;DockPanel Margin="{TemplateBinding Padding}"&gt; &lt;ScrollViewer DockPanel.Dock="Top" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"&gt; &lt;GridViewHeaderRowPresenter AllowsColumnReorder="{Binding TemplatedParent.View.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContainerStyle="{Binding TemplatedParent.View.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderToolTip="{Binding TemplatedParent.View.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderStringFormat="{Binding TemplatedParent.View.ColumnHeaderStringFormat, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderContextMenu="{Binding TemplatedParent.View.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderTemplate="{Binding TemplatedParent.View.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}" Columns="{Binding TemplatedParent.View.Columns, RelativeSource={RelativeSource TemplatedParent}}" ColumnHeaderTemplateSelector="{Binding TemplatedParent.View.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}" Margin="2,0,2,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/&gt; &lt;/ScrollViewer&gt; &lt;ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" KeyboardNavigation.DirectionalNavigation="Local" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/&gt; &lt;/DockPanel&gt; &lt;ScrollBar x:Name="PART_HorizontalScrollBar" Cursor="Arrow" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0.0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/&gt; &lt;ScrollBar x:Name="PART_VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0.0" Orientation="Vertical" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/&gt; &lt;DockPanel Background="{Binding Background, ElementName=PART_VerticalScrollBar}" Grid.Column="1" LastChildFill="false" Grid.Row="1"&gt; &lt;Rectangle DockPanel.Dock="Left" Fill="White" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Width="1"/&gt; &lt;Rectangle DockPanel.Dock="Top" Fill="White" Height="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/&gt; &lt;/DockPanel&gt; &lt;/Grid&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; </code></pre> <p>I'm not sure how to re-template this, as simply replacing all instances of ScrollViewer with s:SurfaceScrollViewer didn't seem to have any effect.</p> <p>My backup plan is to just use a SurfaceListBox control instead of the ListView, but I already have working ListView/GridView code that I'd prefer to modify (to get the nice touch panning provided by SurfaceScrollViewer) if possible.</p> <p><strong>UPDATE:</strong></p> <p>After struggling with the ListView/GridView combination I eventually gave up and implemented this as a data-bound SurfaceListBox that includes a horizontal StackPanel as the SurfaceListBoxItem. So far it seems to be working well. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload