WPF ListView Always show complete items
I've got an app with multiple ListView controls where there's a requirement that the item's in the ListView must be fully visible. There should never be partial ListViewItem's showing in the list. If the user releases the ScrollViewer at a position that ends up showing a partial item, then the list should "snap" and correct itself so that only complete items are displayed.
Has anyone done this before? I think I'm going to need to overload ListView and/or ScrollViewer to do this. I'm looking for suggestions on how to approach this. Thanks.
Here is one of my lists:
<ctrls:SnapList x:Name="PART_ProductList"
ScrollViewer.CanContentScroll="False"
ScrollViewer.VerticalScrollBarVisibility="Auto"
开发者_如何学C ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ItemContainerStyle="{StaticResource ProductFinderItem}"
Canvas.Top="373" Canvas.Left="75"
Height="910" Width="900" >
<ctrls:SnapList.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard" />
</ItemsPanelTemplate>
</ctrls:SnapList.ItemsPanel>
<ctrls:SnapList.Template>
<ControlTemplate>
<ScrollViewer x:Name="Scroller" VerticalAlignment="Top" CanContentScroll="True" Style="{StaticResource VertScrollViewer}" Focusable="false" >
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ctrls:SnapList.Template>
</ctrls:SnapList>
I believe you're looking for the ScrollViewer.CanContentScroll Property
If you know the maximum size of the item in the ListView, make sure that the ListView's Height is the same size, or a multiple of the item height.
Working Example:
<ListView ScrollViewer.CanContentScroll="True"
Height="200">
<ListBoxItem Height="50"
Content="Test1" />
<ListBoxItem Height="50"
Content="Test2" />
<ListBoxItem Height="50"
Content="Test3" />
<ListBoxItem Height="50"
Content="Test4" />
<ListBoxItem Height="50"
Content="Test5" />
<ListBoxItem Height="50"
Content="Test6" />
<ListBoxItem Height="50"
Content="Test7" />
<ListBoxItem Height="50"
Content="Test8" />
<ListBoxItem Height="50"
Content="Test9" />
<ListBoxItem Height="50"
Content="Test10" />
</ListView>
Content in a ScrollViewer can be scrolled in terms of physical units or logical units. Physical units are device independent pixels. Logical units are used for scrolling items within an ItemsControl. The default behavior of the ScrollViewer is to use physical units to scroll its content. However, in cases where the CanContentScroll is set to true, the content could use logical units to scroll. For example, ListBox, ListView, and other controls that inherit from ItemsControl use logical units to scroll. If CanContentScroll is true, the values of the ExtentHeight, ScrollableHeight, ViewportHeight, and VerticalOffset properties are number of items, instead of physical units.
If you require physical scrolling instead of logical scrolling, wrap the host Panel element in a ScrollViewer and set its CanContentScroll property to false. Physical scrolling is the default scroll behavior for most Panel elements.
Have you tried ListView.ScrollIntoView
?
You could try keeping track of the scrollview's current scroll, then get the height of all items. Then you'll know how to calculate the correct offset for each item. When they release the scroll animate to the closest offset.
ScrollInfo to get the current scroll offset and info.
Scroll to vertical offset
精彩评论