Skip to content

Commit

Permalink
Merge branch 'v2'
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
#	src/VirtualizingWrapPanel/README-NUGET.md
#	src/VirtualizingWrapPanel/VirtualizingPanelBase.cs
#	src/VirtualizingWrapPanel/VirtualizingWrapPanel.csproj
  • Loading branch information
sbaeumlisberger committed Jan 9, 2024
2 parents f25434e + f7848d7 commit 2863209
Show file tree
Hide file tree
Showing 43 changed files with 3,892 additions and 865 deletions.
181 changes: 181 additions & 0 deletions GettingStarted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
## Getting started

### Installation

First, add the package to your project. For example via the .NET CLI:
`dotnet add package VirtualizingWrapPanel`

More installation options can be found [here](https://www.nuget.org/packages/VirtualizingWrapPanel/).

Then add the following namespace to the xaml files, where you want to use package:
`xmlns:vwp="clr-namespace:WpfToolkit.Controls;assembly=VirtualizingWrapPanel"`

### Basic usage

You can use the VirtualizingWrapPanel with an existing ItemsControl like a ListView as follows:

```
<Window xmlns:vwp="clr-namespace:WpfToolkit.Controls;assembly=VirtualizingWrapPanel">
<ListView
ItemsSource="{Binding YourItemsSource, Mode=OneWay}"
ItemTemplate="{StaticResource YourItemTemplate}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<vwp:VirtualizingWrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style x:Key="ItemContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Window>
```

Alternatively, you can use the included GridView control, which is using a VirtualizingWrapPanel by default:

```
<Window xmlns:vwp="clr-namespace:WpfToolkit.Controls;assembly=VirtualizingWrapPanel">
<vwp:GridView
ItemsSource="{Binding YourItemsSource, Mode=OneWay}"
ItemTemplate="{StaticResource YourItemTemplate}">
</Window>
```

### Spacing Behaviour

The `SpacingMode` property controls how the remaining space of a layout row is used. The default value is `Uniform` which means that the remaining space is evenly distributed between the items, as well as the start and end of each row.

```
<vwp:VirtualizingWrapPanel SpacingMode="Uniform" StretchItems="false"/>
```
```
<vwp:GridView SpacingMode="Uniform" StretchItems="false"/>
```

| SpacingMode | Description |
| ---------------- | ----------- |
| None | The items are placed next to each other without spacing. |
| Uniform | The remaining space is evenly distributed between the items on a layout row, as well as the start and end of each row. |
| BetweenItemsOnly | The remaining space is evenly distributed between the items on a layout row, but not the start and end of each row. |
| StartAndEndOnly | The remaining space is evenly distributed between start and end of each row. |

When the `StretchItems` property is set to `true` the items get stretched up to their maximum size to fill as much remaining space as possible. The still remaining space is distributed according to the `SpacingMode` property.

### Caching

The attached properties `VirtualizingPanel.CacheLength` and `VirtualizingPanel.CacheLengthUnit` can be used to control the caching behaviour.
For more information visit the official [.NET API documentation](https://learn.microsoft.com/dotnet/api/system.windows.controls.virtualizingpanel.cachelength).

```
<ListView
VirtualizingPanel.CacheLength="200"
VirtualizingPanel.CacheLengthUnit="Pixel">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<vwp:VirtualizingWrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
```
```
<GridView
VirtualizingPanel.CacheLength="200"
VirtualizingPanel.CacheLengthUnit="Pixel"/>
```
### Orientation

⚠️ This information is only valid for version 2.x

The `Orientation` property controls how the items are arranged. The default value is `Horizontal`, which means that the elements are arranged horizontally and wrap to the next row when the edge of the panel is reached. The scroll direction is vertical. When the property is set to `Vertical`, the items are arranged vertically and warp to a new column when the bottom of the panel is reached. The scroll direction is horizontal.
```
<vwp:VirtualizingWrapPanel Orientation="Vertical"/>
```
```
<vwp:GridView Orientation="Vertical"/>
```

### Grouping

Grouping is fully supported and can be used as shown in the following example:
```
<YouControl.Resources>
<CollectionViewSource
x:Key="GroupingItemsSource"
Source="{Binding YourItemsSource, Mode=OneWay}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="PropertyUsedForGrouping"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<YouControl.Resources/>
<ListView
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
ItemsSource='{Binding Source={StaticResource GroupingItemsSource}}'>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<vwp:VirtualizingWrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<!-- orginal WPF style but with zero Margin on the ItemsPresenter -->
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<ContentPresenter
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Name="PART_Header" />
<ItemsPresenter Name="ItemsPresenter" Margin="0" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
</ListView>
```
### Different Sized Items

⚠️ This information is only valid for version 2.x

In order to use different sized items the property `AllowDifferentSizedItems` must be set to `true`. If this property is enabled, it is strongly recommended to also set the `ItemSizeProvider` property to an instance of the `IItemSizeProvider` interface. Otherwise, the position of the items is not guaranteed to be correct when the user is scrolling fast.

The purpose of the `IItemSizeProvider` is to provide the size of the items based on the data. For example, when displaying images or other data where the resulting size is known without creating the UI elements. When the user scrolls quickly, it is not possible to realize all the items and get the desired size of the UI element. If this would be done, the performance would be really bad. Therefore, if no `IItemSizeProvider` is provided, the size of the items is assumed based on the size of the already realized items. Since in this case the size is assumed, it is not possible to guarantee that the items will always be shown at the right position.

### Item Expansion / Details View

The `GridDetailsView` provides the feature to show an inline details view. The `ExpandedItemTemplate` property can be used to specify a template for this view.
```
<vwp:GridDetailsView
ItemsSource="{Binding YourItemsSource, Mode=OneWay}"
ItemTemplate="{StaticResource ItemTemplate}"
ExpandedItemTemplate="{StaticResource ExpandedItemTemplate}">
```

### VirtualizingItemsControl

The `VirtualizingItemsControl` is an extension of the standard `ItemsControl` to support virtualization.
```
<vwp:VirtualizingItemsControl
ItemsSource="{Binding YourItemsSource, Mode=OneWay}"
ItemTemplate="{StaticResource ItemTemplate}">
```

### More Information / Help

To get more information checkout the [Issues page](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/issues) and feel free to open a new issue.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@

## VirtualizingWrapPanel

Implementation of a [VirtualizingWrapPanel](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.VirtualizingWrapPanel.html) control for WPF running .NET Framework 4.5.2+, .NET Core 3.1+ or .NET 5.0+. The additional [GridView](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.GridView.html) and [GridDetailsView](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.GridDetailsView.html) controls are providing a easy to use out-of-the-box experience.
Implementation of a [VirtualizingWrapPanel](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.VirtualizingWrapPanel.html) control for WPF running .NET Framework 4.6.2+ or .NET 6.0+. The additional [GridView](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.GridView.html) and [GridDetailsView](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.GridDetailsView.html) controls are providing a easy to use out-of-the-box experience.

### Features
* Horizontal and vertical orientation
* Caching by page, items or pixels
* Container recycling
* Grouping (experimental)
* Grouping / Hierarchical Virtualization
* Configurable spacing behaviour
* Displaying different sized items

### Resources
* [Getting started](https://github.com/sbaeumlisberger/VirtualizingWrapPanel/blob/v2/GettingStarted.md)
* [Getting started](GettingStarted.md)
* [Sample Application](SamplesApplication.md)
* [API-Documentation](https://sbaeumlisberger.github.io/VirtualizingWrapPanel/api/WpfToolkit.Controls.html)

### Contribution
Feel free to open an issue. I am also willing to accept pull requests, but please open an issue first to discuss.
Feel free to open an issue if you have a problem or suggestion. Pull requests are also accepted, but please open an issue first to allow for discussion.
You can also make a [donation](https://www.paypal.com/paypalme/sbaeumlisberger) to support the future development of the project.
4 changes: 3 additions & 1 deletion src/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vs/
packages/
packages/
obj/
bin/
10 changes: 8 additions & 2 deletions src/VirtualizingWrapPanel.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualizingWrapPanelSamples", "VirtualizingWrapPanelSamples\VirtualizingWrapPanelSamples.csproj", "{F3E7F4E3-787B-4CAD-A184-196C8B169268}"
EndProject
Expand All @@ -14,6 +14,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualizingWrapPanelTest", "VirtualizingWrapPanelTest\VirtualizingWrapPanelTest.csproj", "{AA7642F6-10AD-4F5D-89F4-CAD620FDF420}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -32,6 +34,10 @@ Global
{DD3AA1D2-10F2-48CA-A0E2-E03C03FD2A21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD3AA1D2-10F2-48CA-A0E2-E03C03FD2A21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD3AA1D2-10F2-48CA-A0E2-E03C03FD2A21}.Release|Any CPU.Build.0 = Release|Any CPU
{AA7642F6-10AD-4F5D-89F4-CAD620FDF420}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA7642F6-10AD-4F5D-89F4-CAD620FDF420}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA7642F6-10AD-4F5D-89F4-CAD620FDF420}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA7642F6-10AD-4F5D-89F4-CAD620FDF420}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
11 changes: 0 additions & 11 deletions src/VirtualizingWrapPanel/.gitignore

This file was deleted.

22 changes: 22 additions & 0 deletions src/VirtualizingWrapPanel/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// In SDK-style projects such as this one, several assembly attributes that were historically
// defined in this file are now automatically added during build and populated with
// values defined in project properties. For details of which attributes are included
// and how to customise this process see: https://aka.ms/assembly-info-properties


// Setting ComVisible to false makes the types in this assembly not visible to COM
// components. If you need to access a type in this assembly from COM, set the ComVisible
// attribute to true on that type.

[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM.

[assembly: Guid("f3c2fea6-c9db-4f44-81e8-adcb2f93ab19")]


[assembly: InternalsVisibleTo("VirtualizingWrapPanelTest")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq
6 changes: 2 additions & 4 deletions src/VirtualizingWrapPanel/GridDetailsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
StretchItems="{Binding StretchItems, ElementName=uc, Mode=OneWay}">
<local:VirtualizingWrapPanelWithItemExpansion.ExpandedItemTemplate>
<DataTemplate>
<StackPanel
Loaded="ExpandedItemContainerRoot_Loaded"
Orientation="{Binding Orientation, ElementName=uc, Mode=OneWay}">
<Grid Loaded="ExpandedItemContainerRoot_Loaded">
<ContentControl
ContentTemplate="{Binding ExpandedItemTemplate, Source={x:Reference uc}, Mode=OneWay}"
Content="{Binding Mode=OneWay}" />
</StackPanel>
</Grid>
</DataTemplate>
</local:VirtualizingWrapPanelWithItemExpansion.ExpandedItemTemplate>
</local:VirtualizingWrapPanelWithItemExpansion>
Expand Down
7 changes: 3 additions & 4 deletions src/VirtualizingWrapPanel/GridDetailsView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ private async void ExpandedItemContainerRoot_Loaded(object sender, RoutedEventAr

if (expandedItemContainerRoot == null)
{

expandedItemContainerRoot = (FrameworkElement)sender;
MaxContainerSize = 0;

Expand Down Expand Up @@ -125,7 +124,7 @@ private double DesiredContainerSize
{
throw new NullReferenceException($"{nameof(expandedItemContainerRoot)} is null");
}
if (Orientation == Orientation.Vertical)
if (Orientation == Orientation.Horizontal)
{
return expandedItemContainerRoot.DesiredSize.Height;
}
Expand All @@ -144,7 +143,7 @@ private double MaxContainerSize
{
throw new NullReferenceException($"{nameof(expandedItemContainerRoot)} is null");
}
if (Orientation == Orientation.Vertical)
if (Orientation == Orientation.Horizontal)
{
return expandedItemContainerRoot.MaxHeight;
}
Expand All @@ -159,7 +158,7 @@ private double MaxContainerSize
{
throw new NullReferenceException($"{nameof(expandedItemContainerRoot)} is null");
}
if (Orientation == Orientation.Vertical)
if (Orientation == Orientation.Horizontal)
{
expandedItemContainerRoot.MaxHeight = value;
}
Expand Down
Loading

0 comments on commit 2863209

Please sign in to comment.