@ -16,7 +16,7 @@ namespace Avalonia.Controls.Generators
/// </summary>
public class ItemContainerGenerator : IItemContainerGenerator
{
private List < ItemContainerInfo > _ containers = new List < ItemContainerInfo > ( ) ;
private Dictionary < int , ItemContainerInfo > _ containers = new Dictionary < int , ItemContainerInfo > ( ) ;
/// <summary>
/// Initializes a new instance of the <see cref="ItemContainerGenerator"/> class.
@ -30,7 +30,7 @@ namespace Avalonia.Controls.Generators
}
/// <inheritdoc/>
public IEnumerable < ItemContainerInfo > Containers = > _ containers . Where ( x = > x ! = null ) ;
public IEnumerable < ItemContainerInfo > Containers = > _ containers . Values ;
/// <inheritdoc/>
public event EventHandler < ItemContainerEventArgs > Materialized ;
@ -60,7 +60,7 @@ namespace Avalonia.Controls.Generators
var i = selector ! = null ? selector . Select ( item ) : item ;
var container = new ItemContainerInfo ( CreateContainer ( i ) , item , index ) ;
AddContainer ( container ) ;
_ containers . Add ( container . Index , container ) ;
Materialized ? . Invoke ( this , new ItemContainerEventArgs ( container ) ) ;
return container ;
@ -73,11 +73,8 @@ namespace Avalonia.Controls.Generators
for ( int i = startingIndex ; i < startingIndex + count ; + + i )
{
if ( i < _ containers . Count & & _ containers [ i ] ! = null )
{
result . Add ( _ containers [ i ] ) ;
_ containers [ i ] = null ;
}
result . Add ( _ containers [ i ] ) ;
_ containers . Remove ( i ) ;
}
Dematerialized ? . Invoke ( this , new ItemContainerEventArgs ( startingIndex , result ) ) ;
@ -88,18 +85,47 @@ namespace Avalonia.Controls.Generators
/// <inheritdoc/>
public virtual void InsertSpace ( int index , int count )
{
_ containers . InsertRange ( index , Enumerable . Repeat < ItemContainerInfo > ( null , count ) ) ;
if ( count > 0 )
{
var toMove = _ containers . Where ( x = > x . Key > = index ) . ToList ( ) ;
foreach ( var i in toMove )
{
_ containers . Remove ( i . Key ) ;
i . Value . Index + = count ;
_ containers [ i . Value . Index ] = i . Value ;
}
}
}
/// <inheritdoc/>
public virtual IEnumerable < ItemContainerInfo > RemoveRange ( int startingIndex , int count )
{
List < ItemContainerInfo > result = new List < ItemContainerInfo > ( ) ;
var result = new List < ItemContainerInfo > ( ) ;
if ( startingIndex < _ containers . Count )
if ( count > 0 )
{
result . AddRange ( _ containers . GetRange ( startingIndex , count ) ) ;
_ containers . RemoveRange ( startingIndex , count ) ;
for ( var i = startingIndex ; i < startingIndex + count ; + + i )
{
ItemContainerInfo found ;
if ( _ containers . TryGetValue ( i , out found ) )
{
result . Add ( found ) ;
}
_ containers . Remove ( i ) ;
}
var toMove = _ containers . Where ( x = > x . Key > = startingIndex ) . ToList ( ) ;
foreach ( var i in toMove )
{
_ containers . Remove ( i . Key ) ;
i . Value . Index - = count ;
_ containers . Add ( i . Value . Index , i . Value ) ;
}
Dematerialized ? . Invoke ( this , new ItemContainerEventArgs ( startingIndex , result ) ) ;
}
@ -119,8 +145,8 @@ namespace Avalonia.Controls.Generators
/// <inheritdoc/>
public virtual IEnumerable < ItemContainerInfo > Clear ( )
{
var result = _ containers . Where ( x = > x ! = null ) . ToList ( ) ;
_ containers = new List < ItemContainerInfo > ( ) ;
var result = Containers . ToList ( ) ;
_ containers . Clear ( ) ;
if ( result . Count > 0 )
{
@ -133,27 +159,20 @@ namespace Avalonia.Controls.Generators
/// <inheritdoc/>
public IControl ContainerFromIndex ( int index )
{
if ( index < _ containers . Count )
{
return _ containers [ index ] ? . ContainerControl ;
}
return null ;
ItemContainerInfo result ;
_ containers . TryGetValue ( index , out result ) ;
return result ? . ContainerControl ;
}
/// <inheritdoc/>
public int IndexFromContainer ( IControl container )
{
var index = 0 ;
foreach ( var i in _ containers )
{
if ( i ? . ContainerControl = = container )
if ( i . Value . ContainerControl = = container )
{
return index ;
return i . Key ;
}
+ + index ;
}
return - 1 ;
@ -176,33 +195,6 @@ namespace Avalonia.Controls.Generators
return result ;
}
/// <summary>
/// Adds a container to the index.
/// </summary>
/// <param name="container">The container.</param>
protected void AddContainer ( ItemContainerInfo container )
{
Contract . Requires < ArgumentNullException > ( container ! = null ) ;
while ( _ containers . Count < container . Index )
{
_ containers . Add ( null ) ;
}
if ( _ containers . Count = = container . Index )
{
_ containers . Add ( container ) ;
}
else if ( _ containers [ container . Index ] = = null )
{
_ containers [ container . Index ] = container ;
}
else
{
throw new InvalidOperationException ( "Container already created." ) ;
}
}
/// <summary>
/// Moves a container.
/// </summary>
@ -213,10 +205,11 @@ namespace Avalonia.Controls.Generators
protected ItemContainerInfo MoveContainer ( int oldIndex , int newIndex , object item )
{
var container = _ containers [ oldIndex ] ;
var newContainer = new ItemContainerInfo ( container . ContainerControl , item , newIndex ) ;
_ containers [ oldIndex ] = null ;
AddContainer ( newContainer ) ;
return newContainer ;
container . Index = newIndex ;
container . Item = item ;
_ containers . Remove ( oldIndex ) ;
_ containers . Add ( newIndex , container ) ;
return container ;
}
/// <summary>
@ -227,7 +220,7 @@ namespace Avalonia.Controls.Generators
/// <returns>The containers.</returns>
protected IEnumerable < ItemContainerInfo > GetContainerRange ( int index , int count )
{
return _ containers . GetRange ( index , count ) ;
return _ containers . Where ( x = > x . Key > = index & & x . Key < = index + count ) . Select ( x = > x . Value ) ;
}
/// <summary>