http://www.codeproject.com/Articles/64865/Enable-MultiSelect-in-WPF-ListView-2
using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace QuickZip.UserControls
{
public class VirtualWrapPanel : VirtualizingPanel, IScrollInfo, IChildInfo
{
public VirtualWrapPanel()
{
// For use in the IScrollInfo implementation
this.RenderTransform = _trans;
}
#region Methods
#region Layout specific code
// I've isolated the layout specific code to this region. If you want to do something other than tiling, this is
// where you'll make your changes
/// <summary>
/// Calculate the extent of the view based on the available size
/// </summary>
/// <param name="availableSize">available size</param>
/// <param name="itemCount">number of data items</param>
/// <returns></returns>
private Size CalculateExtent(Size availableSize, int itemCount)
{
if (Orientation == Orientation.Horizontal)
{
int childPerRow = CalculateChildrenPerRow(availableSize);
return new Size(childPerRow * this.ItemSize.Width,
this.ItemSize.Height * Math.Ceiling((double)itemCount / childPerRow));
}
else
{
int childPerCol = CalculateChildrenPerCol(availableSize);
return new Size(this.ItemSize.Width * Math.Ceiling((double)itemCount / childPerCol),
childPerCol * this.ItemSize.Height);
}
}
/// <summary>
/// Get the range of children that are visible
/// </summary>
/// <param name="firstVisibleItemIndex">The item index of the first visible item</param>
/// <param name="lastVisibleItemIndex">The item index of the last visible item</param>
private void GetVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex)
{
if (Orientation == Orientation.Horizontal)
{
int childPerRow = CalculateChildrenPerRow(_extent);
firstVisibleItemIndex = (int)Math.Floor(_offset.Y / this.ItemSize.Height) * childPerRow;
lastVisibleItemIndex = (int)Math.Ceiling((_offset.Y + _viewport.Height) / this.ItemSize.Height) * childPerRow - 1;
ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
int itemCount = itemsControl.HasItems ? itemsControl.Items.Count : 0;
if (lastVisibleItemIndex >= itemCount)
lastVisibleItemIndex = itemCount - 1;
}
else
{
int childPerCol = CalculateChildrenPerCol(_extent);
firstVisibleItemIndex = (int)Math.Floor(_offset.X / this.ItemSize.Width) * childPerCol;
lastVisibleItemIndex = (int)Math.Ceiling((_offset.X + _viewport.Width) / this.ItemSize.Width) * childPerCol - 1;
ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
int itemCount = itemsControl.HasItems ? itemsControl.Items.Count : 0;
if (lastVisibleItemIndex >= itemCount)
lastVisibleItemIndex = itemCount - 1;
}
}
private Rect GetChildRect(int itemIndex, Size finalSize)
{
if (Orientation == Orientation.Horizontal)
{
int childPerRow = CalculateChildrenPerRow(finalSize);
int row = itemIndex / childPerRow;
int column = itemIndex % childPerRow;
return new Rect(column * this.ItemSize.Width, row * this.ItemSize.Height, this.ItemSize.Width, this.ItemSize.Height);
}
else
{