Browse Source

DataSource, Sort by One Column

reports
Peter Forstmeier 12 years ago
parent
commit
0808f8cb40
  1. 2
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj
  2. 2
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/AbstractColumn.cs
  3. 16
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Collections.cs
  4. 156
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataManager/Listhandling/CollectionSource.cs
  5. 103
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataSource/Comparer/SortComparer.cs
  6. 32
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataSource/Comparer/SortExtension.cs
  7. 4
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Interfaces/Data/IDataViewHandling.cs
  8. 5
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/ReportSettings.cs
  9. 43
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/DataSource/CollectionHandlingFixture.cs
  10. 43
      src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/DataSource/ContributorsList.cs

2
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/ICSharpCode.Reporting.csproj

@ -81,6 +81,8 @@ @@ -81,6 +81,8 @@
<Compile Include="Src\DataManager\Listhandling\CollectionSource.cs" />
<Compile Include="Src\DataManager\Listhandling\IndexList.cs" />
<Compile Include="Src\DataSource\Comparer\BaseComparer.cs" />
<Compile Include="Src\DataSource\Comparer\SortComparer.cs" />
<Compile Include="Src\DataSource\Comparer\SortExtension.cs" />
<Compile Include="Src\DataSource\DataCollection.cs" />
<Compile Include="Src\DataSource\ExtendedPropertyDescriptor.cs" />
<Compile Include="Src\DataSource\ExtendedTypeDescriptor.cs" />

2
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/BaseClasses/AbstractColumn.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.Reporting.BaseClasses @@ -31,7 +31,7 @@ namespace ICSharpCode.Reporting.BaseClasses
// }
public AbstractColumn(string columnName, Type dataType){
this.columnName = columnName;
this.ColumnName = columnName;
this.dataType = dataType;
}

16
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Collections.cs

@ -62,14 +62,14 @@ namespace ICSharpCode.Reporting @@ -62,14 +62,14 @@ namespace ICSharpCode.Reporting
{
}
// public new AbstractColumn Find (string columnName)
// {
// if (String.IsNullOrEmpty(columnName)) {
// throw new ArgumentNullException("columnName");
// }
//
// return this.FirstOrDefault(x => 0 == String.Compare(x.ColumnName,columnName,true,CultureInfo.InvariantCulture));
// }
public new AbstractColumn Find (string columnName)
{
if (String.IsNullOrEmpty(columnName)) {
throw new ArgumentNullException("columnName");
}
return this.FirstOrDefault(x => 0 == String.Compare(x.ColumnName,columnName,true,CultureInfo.InvariantCulture));
}
public void AddRange (IEnumerable<SortColumn> items)

156
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataManager/Listhandling/CollectionSource.cs

@ -8,11 +8,15 @@ @@ -8,11 +8,15 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using ICSharpCode.Reporting.BaseClasses;
using ICSharpCode.Reporting.DataSource;
using ICSharpCode.Reporting.DataSource.Comparer;
using ICSharpCode.Reporting.Interfaces.Data;
using ICSharpCode.Reporting.Items;
@ -27,14 +31,12 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling @@ -27,14 +31,12 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling
private PropertyDescriptorCollection listProperties;
private DataCollection<object> baseList;
private ReportSettings reportSettings;
private object current;
public CollectionSource(IList list,ReportSettings reportSettings)
{
if (list.Count > 0) {
// firstItem = list[0];
var itemType = list[0].GetType();
this.baseList = new DataCollection <object>(itemType);
this.baseList.AddRange(list);
@ -54,11 +56,11 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling @@ -54,11 +56,11 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling
public Collection<AbstractColumn> AvailableFields {
get {
// base.AvailableFields.Clear();
var av = new Collection<AbstractColumn>();
var availableFields = new Collection<AbstractColumn>();
foreach (PropertyDescriptor p in this.listProperties){
av.Add (new AbstractColumn(p.Name,p.PropertyType));
availableFields.Add (new AbstractColumn(p.Name,p.PropertyType));
}
return av;
return availableFields;
}
}
@ -68,11 +70,24 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling @@ -68,11 +70,24 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling
}
}
public void Bind()
{
Sort();
Reset();
}
public void Sort()
{
throw new NotImplementedException();
if ((this.reportSettings.SortColumnsCollection != null)) {
if (this.reportSettings.SortColumnsCollection.Count > 0) {
IndexList = this.BuildSortIndex (reportSettings.SortColumnsCollection);
} else {
IndexList = this.UnsortedIndexList(reportSettings.SortColumnsCollection);
}
}
}
public bool MoveNext()
{
throw new NotImplementedException();
@ -80,10 +95,135 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling @@ -80,10 +95,135 @@ namespace ICSharpCode.Reporting.DataManager.Listhandling
public void Reset()
{
throw new NotImplementedException();
this.CurrentPosition = 0;
this.IndexList.CurrentPosition = -1;
}
public IndexList IndexList {get; private set;}
IndexList BuildSortIndex(SortColumnCollection sortColumnsCollection)
{
var indexList = new IndexList();
PropertyDescriptor[] sortProperties = BuildSortProperties (sortColumnsCollection);
for (int rowIndex = 0; rowIndex < this.baseList.Count; rowIndex++){
object rowItem = this.baseList[rowIndex];
object[] values = new object[sortColumnsCollection.Count];
// Hier bereits Wertabruf um dies nicht während des Sortierens tun zu müssen.
for (int criteriaIndex = 0; criteriaIndex < sortProperties.Length; criteriaIndex++){
object value = sortProperties[criteriaIndex].GetValue(rowItem);
// Hier auf Verträglichkeit testen um Vergleiche bei Sortierung zu vereinfachen.
// Muss IComparable und gleicher Typ sein.
if (value != null && value != DBNull.Value)
{
if (!(value is IComparable)){
throw new InvalidOperationException("ReportDataSource:BuildSortArray - > This type doesn't support IComparable." + value.ToString());
}
values[criteriaIndex] = value;
}
}
indexList.Add(new SortComparer(sortColumnsCollection, rowIndex, values));
}
if (indexList[0].ObjectArray.GetLength(0) == 1) {
List<BaseComparer> sortedList = GenericSorter (indexList);
indexList.Clear();
indexList.AddRange(sortedList);
}
else {
indexList.Sort();
}
return indexList;
}
#region Sorting delegates
static List<BaseComparer> GenericSorter (List<BaseComparer> list)
{
List<BaseComparer> sortedList = null;
ListSortDirection sortDirection = GetSortDirection(list);
if (sortDirection == ListSortDirection.Ascending) {
sortedList = list.AsQueryable().AscendingOrder().ToList();
} else {
sortedList = list.AsQueryable().DescendingOrder().ToList();
}
return sortedList;
}
static ListSortDirection GetSortDirection(List<BaseComparer> list)
{
BaseComparer bc = list[0];
SortColumn sortColumn = bc.ColumnCollection[0] as SortColumn;
ListSortDirection sd = sortColumn.SortDirection;
return sd;
}
#endregion
private PropertyDescriptor[] BuildSortProperties (SortColumnCollection sortColumnCollection)
{
PropertyDescriptor[] sortProperties = new PropertyDescriptor[sortColumnCollection.Count];
PropertyDescriptorCollection descriptorCollection = this.baseList.GetItemProperties(null);
for (int criteriaIndex = 0; criteriaIndex < sortColumnCollection.Count; criteriaIndex++){
PropertyDescriptor descriptor = descriptorCollection.Find (sortColumnCollection[criteriaIndex].ColumnName,true);
if (descriptor == null){
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
"Die Liste enthält keine Spalte [{0}].",
sortColumnCollection[criteriaIndex].ColumnName));
}
sortProperties[criteriaIndex] = descriptor;
}
return sortProperties;
}
IndexList UnsortedIndexList(SortColumnCollection sortColumnsCollection)
{
IndexList arrayList = new IndexList();
for (int rowIndex = 0; rowIndex < this.baseList.Count; rowIndex++){
object[] values = new object[1];
arrayList.Add(new SortComparer(sortColumnsCollection, rowIndex, values));
}
return arrayList;
}
public int CurrentPosition {
get {
return IndexList.CurrentPosition;
}
set {
if ((value > -1)|| (value > this.IndexList.Count)){
this.IndexList.CurrentPosition = value;
}
// var a = this.baseList[((BaseComparer)IndexList[value])];
BaseComparer bc = GetComparer(value);
// var bc = (BaseComparer)IndexList[value];
// var i = bc.ListIndex;
var myCurrent = baseList[bc.ListIndex];
current = baseList[bc.ListIndex];
// current = this.baseList[((BaseComparer)IndexList[value]).ListIndex];
}
}
BaseComparer GetComparer(int value)
{
var bc = (BaseComparer)IndexList[value];
// var i = bc.ListIndex;
return bc;
}
}
}

103
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataSource/Comparer/SortComparer.cs

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
/*
* Created by SharpDevelop.
* User: Peter Forstmeier
* Date: 22.05.2013
* Time: 20:06
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.ComponentModel;
using System.Globalization;
using ICSharpCode.Reporting.BaseClasses;
namespace ICSharpCode.Reporting.DataSource.Comparer
{
/// <summary>
/// Description of SortComparer.
/// </summary>
public class SortComparer : BaseComparer {
public SortComparer(ColumnCollection owner, int listIndex, object[] values):base(owner,listIndex,values)
{
}
internal int CompareTo(SortComparer value)
{
// we shouldn't get to this point
if (value == null)
throw new ArgumentNullException("value");
if (value.ObjectArray.Length != base.ObjectArray.Length)
throw new InvalidOperationException();
int compare = 0;
for (int index = 0; index < base.ObjectArray.Length; index++)
{
object leftValue = base.ObjectArray[index];
object rightValue = value.ObjectArray[index];
// Indizes sind hier deckungsgleich
SortColumn sortColumn = (SortColumn)base.ColumnCollection[index];
bool descending = (sortColumn.SortDirection == ListSortDirection.Descending);
// null means equl
if (leftValue == null || leftValue == System.DBNull.Value)
{
if (rightValue != null && rightValue != System.DBNull.Value)
{
return (descending) ? 1 : -1;
}
// Beide Null
continue;
}
if (rightValue == null || rightValue == System.DBNull.Value)
{
return (descending) ? -1 : 1;
}
if (leftValue.GetType() != rightValue.GetType()){
string s = String.Format(CultureInfo.CurrentCulture,
"{0} {1} {2}",this.GetType().ToString(),
leftValue.GetType().ToString(),
rightValue.GetType().ToString());
throw new ArgumentException(s);
}
if (leftValue.GetType() == typeof(string))
{
compare = String.Compare((string)leftValue, (string)rightValue,
!sortColumn.CaseSensitive, CultureInfo.CurrentCulture);
}
else
{
compare = ((IComparable)leftValue).CompareTo(rightValue);
}
// Sind ungleich, tauschen je nach Richtung
if (compare != 0)
{
return (descending) ? -compare : compare;
}
}
// Gleich Werte, dann Index bercksichtigen
return this.ListIndex.CompareTo(value.ListIndex);
}
public override int CompareTo(object obj) {
base.CompareTo(obj);
return this.CompareTo((SortComparer)obj);
}
}
}

32
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/DataSource/Comparer/SortExtension.cs

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
/*
* Created by SharpDevelop.
* User: Peter Forstmeier
* Date: 23.05.2013
* Time: 19:51
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Linq;
namespace ICSharpCode.Reporting.DataSource.Comparer
{
/// <summary>
/// Description of SortExtension.
/// </summary>
internal static class SortExtension
{
public static IOrderedQueryable<BaseComparer> AscendingOrder(this IQueryable<BaseComparer> source )
{
return source.OrderBy(x => x.ObjectArray[0]);
}
public static IOrderedQueryable<BaseComparer> DescendingOrder(this IQueryable<BaseComparer> source )
{
return source.OrderByDescending(x => x.ObjectArray[0]);
}
}
}

4
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Interfaces/Data/IDataViewHandling.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.Reporting.Interfaces.Data @@ -24,7 +24,7 @@ namespace ICSharpCode.Reporting.Interfaces.Data
// void Group();
// void Bind();
void Bind();
// void Fill (int position,ReportItemCollection collection);
@ -42,7 +42,7 @@ namespace ICSharpCode.Reporting.Interfaces.Data @@ -42,7 +42,7 @@ namespace ICSharpCode.Reporting.Interfaces.Data
int Count {get;}
// int CurrentPosition {get;set;}
int CurrentPosition {get;set;}
// IExpressionEvaluatorFacade ExpressionEvaluator {get;}
}

5
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Src/Items/ReportSettings.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.Reporting.Items @@ -50,7 +50,7 @@ namespace ICSharpCode.Reporting.Items
//
// this.availableFields = new AvailableFieldsCollection();
// this.groupingsCollection = new GroupColumnCollection();
// this.sortingCollection = new SortColumnCollection();
this.SortColumnsCollection = new SortColumnCollection();
// this.sqlParameters = new SqlParameterCollection();
// this.parameterCollection = new ParameterCollection();
// this.NoDataMessage = "No Data for this Report";
@ -135,5 +135,8 @@ namespace ICSharpCode.Reporting.Items @@ -135,5 +135,8 @@ namespace ICSharpCode.Reporting.Items
// [Browsable(true), Category("Base Settings")]
public GlobalEnums.ReportType ReportType {get;set;}
public SortColumnCollection SortColumnsCollection {get;private set;}
}
}

43
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/DataSource/CollectionHandlingFixture.cs

@ -8,6 +8,9 @@ @@ -8,6 +8,9 @@
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using ICSharpCode.Reporting.BaseClasses;
using ICSharpCode.Reporting.DataManager.Listhandling;
using ICSharpCode.Reporting.DataSource;
using ICSharpCode.Reporting.Items;
@ -39,15 +42,45 @@ namespace ICSharpCode.Reporting.Test.DataSource @@ -39,15 +42,45 @@ namespace ICSharpCode.Reporting.Test.DataSource
[Test]
public void AvailableFieldsEqualContibutorsPropertyCount() {
var collectionSource = new CollectionSource (list,new ReportSettings());
Assert.That(collectionSource.AvailableFields.Count,Is.EqualTo(7));
Assert.That(collectionSource.AvailableFields.Count,Is.EqualTo(6));
}
[Test]
public void CreateUnsortedIndex() {
var collectionSource = new CollectionSource (list,new ReportSettings());
collectionSource.Bind();
Assert.That(collectionSource.IndexList.Count,Is.EqualTo(collectionSource.Count));
Assert.That(collectionSource.IndexList.CurrentPosition,Is.EqualTo(-1));
}
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void SortColumnNotExist() {
var rs = new ReportSettings();
rs.SortColumnsCollection.Add(new SortColumn("aa",ListSortDirection.Ascending));
var collectionSource = new CollectionSource (list,rs);
collectionSource.Bind();
Assert.That(collectionSource.IndexList,Is.Not.Null);
Assert.That(collectionSource.IndexList.Count,Is.EqualTo(0));
}
[Test]
public void SortOneColumnAscending() {
var rs = new ReportSettings();
rs.SortColumnsCollection.Add(new SortColumn("Lastname",ListSortDirection.Ascending));
var collectionSource = new CollectionSource (list,rs);
collectionSource.Bind();
string compare = collectionSource.IndexList[0].ObjectArray[0].ToString();
foreach (var element in collectionSource.IndexList) {
Console.WriteLine(element.ObjectArray[0].ToString());
Assert.That(compare,Is.LessThanOrEqualTo(element.ObjectArray[0].ToString()));
compare = element.ObjectArray[0].ToString();
}
}
//http://stackoverflow.com/questions/5378293/simplest-way-to-filter-generic-list
//http://stackoverflow.com/questions/5378293/simplest-way-to-filter-generic-list
//http://netmatze.wordpress.com/2012/06/21/implementing-a-generic-iequalitycomparer-and-icomparer-class/
// http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
[SetUp]
public void CreateList() {
var contributorList = new ContributorsList();

43
src/AddIns/Misc/Reporting/ICSharpCode.Reporting/Test/ICSharpCode.Reporting.Test/src/DataSource/ContributorsList.cs

@ -66,43 +66,29 @@ namespace ICSharpCode.Reporting.Test.DataSource @@ -66,43 +66,29 @@ namespace ICSharpCode.Reporting.Test.DataSource
}
public class Contributor {
string last;
string first;
string job;
int randomInt;
DateTime randomDate;
public Contributor(string last, string first,string job,int randomInt,DateTime randomDate,string groupItem)
public Contributor(string lastname, string firstname,string job,int randomInt,DateTime randomDate,string groupItem)
{
this.last = last;
this.first = first;
this.job = job;
this.Lastname = lastname;
this.Firstname = firstname;
this.Job = job;
this.randomDate = randomDate;
this.randomInt = randomInt;
this.GroupItem = groupItem;
}
public string Last {
get {
return last;
}
public string Lastname {get;private set;}
}
public string First {
get {
return first;
}
public string Firstname {get;private set;}
}
public string Job {
get {
return job;
}
}
public string Job {get; private set;}
public int RandomInt {
get { return randomInt; }
@ -115,18 +101,5 @@ namespace ICSharpCode.Reporting.Test.DataSource @@ -115,18 +101,5 @@ namespace ICSharpCode.Reporting.Test.DataSource
public string GroupItem {get; set;}
public MyDummyClass DummyClass {get;set;}
}
public class MyDummyClass
{
public MyDummyClass()
{
}
public string DummyString {get;set;}
public int DummyInt {get;set;}
}
}

Loading…
Cancel
Save