/Xceed.Silverlight.Data/DataSourceGroupContext.cs
C# | 428 lines | 321 code | 90 blank | 17 comment | 32 complexity | 5de6b18f4b7925c171551ff570587322 MD5 | raw file
- /************************************************************************
-
- Extended Silverlight Toolkit
-
- Copyright (C) 2010-2012 Xceed Software Inc.
-
- This program is provided to you under the terms of the Microsoft Public
- License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license
-
- Please purchase a commercial version of this toolkit if you are using
- it in a commercial product. The commercial versions support the project,
- and also include more features for each control, priority support,
- source code, updates, removed watermark, and a proprietary license.
-
- Visit http://xceed.com and follow @datagrid on Twitter.
-
- **********************************************************************/
-
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.ComponentModel;
- using System.Linq;
- using System.Windows.Data;
-
- namespace Xceed.Silverlight.Data
- {
- internal sealed class DataSourceGroupContext
- {
- #region Constructors
-
- internal DataSourceGroupContext( GroupHandler handler )
- : this(
- handler.GroupDescriptions,
- handler.GroupCollections,
- handler.GroupHeadersFootersSelector,
- handler.GroupStatFunctionsSelector,
- handler.GroupCountPolicy,
- handler.IncludeGroupItems,
- handler.IncludeGroupItemsCount )
- {
- }
-
- private DataSourceGroupContext()
- {
- m_readOnlyGroupDescriptions = new ReadOnlyCollection<GroupDescription>( m_groupDescriptions );
- }
-
- private DataSourceGroupContext( DataSourceGroupContext copy )
- : this(
- copy.GroupDescriptions,
- copy.GroupCollections,
- copy.GroupHeadersFootersSelector,
- copy.GroupStatFunctionsSelector,
- copy.GroupCountPolicy,
- copy.IncludeGroupItems,
- copy.IncludeGroupItemsCount )
- {
- }
-
- private DataSourceGroupContext(
- IEnumerable<GroupDescription> groupDescriptions,
- IEnumerable<IGroupCollection> groupCollections,
- IGroupHeadersFootersSelector groupHeadersFootersSelector,
- IGroupStatFunctionsSelector groupStatFunctionsSelector,
- GroupCountPolicy groupCountPolicy,
- bool includeGroupItems,
- bool includeGroupItemsCount )
- : this()
- {
- if( groupDescriptions.Count() != groupCollections.Count() )
- throw new ArgumentException( "groupCollections" );
-
- m_groupDescriptions.AddRange( groupDescriptions );
- m_groupCollections = new GroupLevelCollection( DataSourceGroupContext.Copy( groupCollections ) );
- m_groupHeadersFootersSelector = groupHeadersFootersSelector;
- m_groupStatFunctionsSelector = groupStatFunctionsSelector;
- m_groupCountPolicy = groupCountPolicy;
- m_includeGroupItems = includeGroupItems;
- m_includeGroupItemsCount = includeGroupItemsCount;
- }
-
- #endregion
-
- #region GroupDescriptions Property
-
- internal IList<GroupDescription> GroupDescriptions
- {
- get
- {
- return m_readOnlyGroupDescriptions;
- }
- }
-
- private readonly List<GroupDescription> m_groupDescriptions = new List<GroupDescription>();
- private readonly ReadOnlyCollection<GroupDescription> m_readOnlyGroupDescriptions;
-
- #endregion
-
- #region GroupCollections Property
-
- internal GroupLevelCollection GroupCollections
- {
- get
- {
- return m_groupCollections;
- }
- }
-
- private readonly GroupLevelCollection m_groupCollections;
-
- #endregion
-
- #region GroupNames Property
-
- internal IEnumerable<string> GroupNames
- {
- get
- {
- return DataUtils.GetGroupNames( this.GroupDescriptions );
- }
- }
-
- #endregion
-
- #region GroupHeadersFootersSelector Property
-
- internal IGroupHeadersFootersSelector GroupHeadersFootersSelector
- {
- get
- {
- return m_groupHeadersFootersSelector;
- }
- }
-
- private readonly IGroupHeadersFootersSelector m_groupHeadersFootersSelector;
-
- #endregion
-
- #region GroupStatFunctionsSelector Property
-
- internal IGroupStatFunctionsSelector GroupStatFunctionsSelector
- {
- get
- {
- return m_groupStatFunctionsSelector;
- }
- }
-
- private readonly IGroupStatFunctionsSelector m_groupStatFunctionsSelector;
-
- #endregion
-
- #region GroupCountPolicy Property
-
- internal GroupCountPolicy GroupCountPolicy
- {
- get
- {
- return m_groupCountPolicy;
- }
- }
-
- private readonly GroupCountPolicy m_groupCountPolicy;
-
- #endregion
-
- #region IncludeGroupItems Property
-
- internal bool IncludeGroupItems
- {
- get
- {
- return m_includeGroupItems;
- }
- }
-
- private readonly bool m_includeGroupItems;
-
- #endregion
-
- #region IncludeGroupItemsCount Property
-
- internal bool IncludeGroupItemsCount
- {
- get
- {
- return m_includeGroupItemsCount;
- }
- }
-
- private readonly bool m_includeGroupItemsCount;
-
- #endregion
-
- #region AnyHeaderFooter Property
-
- internal bool AnyHeaderFooter
- {
- get
- {
- IGroupHeadersFootersSelector selector = this.GroupHeadersFootersSelector;
-
- if( selector != null )
- {
- ICollection<GroupDescription> groupDescriptions = this.GroupDescriptions;
-
- for( int i = 0; i < groupDescriptions.Count; i++ )
- {
- DataPath dataPath = new DataPath( Enumerable.Repeat( GroupDataItem.Any, i + 1 ).ToArray() );
-
- if( ( selector.HasHeaders( dataPath ) ) || ( selector.HasFooters( dataPath ) ) )
- return true;
- }
- }
-
- return false;
- }
- }
-
- #endregion
-
- #region AnyCollapsedGroup Property
-
- internal bool AnyCollapsedGroup
- {
- get
- {
- foreach( IGroupCollection collection in m_groupCollections )
- {
- if( collection.AnyCollapsedGroup.GetValueOrDefault( collection.IsCollapsedByDefault ) )
- return true;
- }
-
- return false;
- }
- }
-
- #endregion
-
- #region AnyGroup Property
-
- internal bool AnyGroup
- {
- get
- {
- return ( m_groupCollections.Count > 0 );
- }
- }
-
- #endregion
-
- public override int GetHashCode()
- {
- int hashCode = 11;
-
- hashCode += 17 * this.GroupDescriptions.Count;
- hashCode += 17 * DataSourceGroupContext.GetHashCode( this.GroupHeadersFootersSelector );
- hashCode += 17 * DataSourceGroupContext.GetHashCode( this.GroupStatFunctionsSelector );
- hashCode += 17 * this.GroupCountPolicy.GetHashCode();
- hashCode += 17 * this.IncludeGroupItems.GetHashCode();
- hashCode += 17 * this.IncludeGroupItemsCount.GetHashCode();
-
- return hashCode;
- }
-
- public override bool Equals( object obj )
- {
- if( object.ReferenceEquals( obj, this ) )
- return true;
-
- DataSourceGroupContext context = obj as DataSourceGroupContext;
-
- if( object.ReferenceEquals( context, null ) )
- return false;
-
- if( context.GetHashCode() != this.GetHashCode() )
- return false;
-
- return ( object.Equals( context.GroupHeadersFootersSelector, this.GroupHeadersFootersSelector ) )
- && ( object.Equals( context.GroupStatFunctionsSelector, this.GroupStatFunctionsSelector ) )
- && ( object.Equals( context.GroupCountPolicy, this.GroupCountPolicy ) )
- && ( object.Equals( context.IncludeGroupItems, this.IncludeGroupItems ) )
- && ( object.Equals( context.IncludeGroupItemsCount, this.IncludeGroupItemsCount ) )
- && ( context.GroupDescriptions.SequenceEqual( this.GroupDescriptions ) )
- && ( context.GroupCollections.SequenceEqual( this.GroupCollections ) );
- }
-
- internal DataSourceGroupContext Clone()
- {
- return new DataSourceGroupContext( this );
- }
-
- internal IAsyncEnumerator<DataPath> GetHeadersEnumerator( DataPath groupPath )
- {
- IAsyncEnumerator<object> childEnumerator = this.GetHeadersFootersEnumerator( groupPath, true );
-
- return this.ConvertEnumerator( groupPath, HeaderFooterType.Header, childEnumerator );
- }
-
- internal IAsyncEnumerator<DataPath> GetFootersEnumerator( DataPath groupPath )
- {
- IAsyncEnumerator<object> childEnumerator = this.GetHeadersFootersEnumerator( groupPath, false );
-
- return this.ConvertEnumerator( groupPath, HeaderFooterType.Footer, childEnumerator );
- }
-
- private static int GetHashCode( object obj )
- {
- if( object.ReferenceEquals( obj, null ) )
- return 0;
-
- return obj.GetHashCode();
- }
-
- private static IEnumerable<IGroupCollection> Copy( IEnumerable<IGroupCollection> source )
- {
- foreach( IGroupCollection collection in source )
- {
- GroupCollection gc = collection as GroupCollection;
-
- if( gc != null )
- {
- yield return gc.Clone().AsReadOnly();
- }
- else
- {
- gc = new GroupCollection();
-
- if( collection.IsCollapsedByDefault )
- {
- gc.CollapseAll();
- }
- else
- {
- gc.ExpandAll();
- }
-
- ICollection<DataPath> groupCollection = gc;
-
- foreach( DataPath path in collection )
- {
- groupCollection.Add( path );
- }
-
- yield return gc.AsReadOnly();
- }
- }
- }
-
- private IAsyncEnumerator<object> GetHeadersFootersEnumerator(
- DataPath groupPath,
- bool isHeader )
- {
- if( groupPath == null )
- throw new ArgumentNullException( "groupPath" );
-
- if( !( groupPath.LastChild is GroupDataItem ) )
- throw new ArgumentException( "path must refer to a group", "groupPath" );
-
- IEnumerable<object> headersFooters = null;
- IGroupHeadersFootersSelector selector = this.GroupHeadersFootersSelector;
-
- if( selector != null )
- {
- if( isHeader )
- {
- headersFooters = selector.GetHeaders( groupPath );
- }
- else
- {
- headersFooters = selector.GetFooters( groupPath );
- }
- }
-
- List<object> data;
-
- if( headersFooters != null )
- {
- data = headersFooters.ToList();
- }
- else
- {
- data = new List<object>( 0 );
- }
-
- return new SyncToAsyncEnumerator<object>(
- new LocalListEnumerator<object>( data ) );
- }
-
- private IAsyncEnumerator<DataPath> ConvertEnumerator( DataPath groupPath, HeaderFooterType headerType, IAsyncEnumerator<object> childEnumerator )
- {
- return new HeaderFooterEnumerator( childEnumerator, groupPath, headerType );
- }
-
- #region HeaderFooterEnumerator Nested Type
-
- private class HeaderFooterEnumerator : ConversionEnumerator<object, DataPath>
- {
- internal HeaderFooterEnumerator( IAsyncEnumerator childEnumerator, DataPath groupPath, HeaderFooterType headerType )
- : base( childEnumerator )
- {
- if( groupPath == null )
- throw new ArgumentNullException( "groupPath" );
-
- m_groupPath = groupPath;
- m_type = headerType;
- }
-
- protected override DataPath Convert( DataSourceContext context, object value )
- {
- return m_groupPath.CreateChildPath( new HeaderFooterDataItem( value, m_type ) );
- }
-
- protected override object ConvertBack( DataSourceContext context, DataPath value )
- {
- HeaderFooterDataItem dataItem = ( HeaderFooterDataItem )value.LastChild;
-
- return dataItem.Data;
- }
-
- private readonly DataPath m_groupPath;
- private readonly HeaderFooterType m_type;
- }
-
- #endregion
- }
- }