Skip to content

Commit

Permalink
Merge pull request #173 from nstlaurent/bug/bindinglistview-interface…
Browse files Browse the repository at this point in the history
…-sort

fix idgames tab sorting
  • Loading branch information
nstlaurent authored Jun 21, 2020
2 parents 55140c9 + f7295c5 commit 5dedd83
Show file tree
Hide file tree
Showing 24 changed files with 3,616 additions and 31 deletions.
2,009 changes: 2,009 additions & 0 deletions BindingListView/AggregateBindingListView.cs

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions BindingListView/BindingListView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace Equin.ApplicationFramework
{
/// <summary>
/// A searchable, sortable, filterable, data bindable view of a list of objects.
/// </summary>
/// <typeparam name="T">The type of object in the list.</typeparam>
public class BindingListView<T> : AggregateBindingListView<T>
{
/// <summary>
/// Creates a new <see cref="BindingListView&lt;T&gt;"/> of a given IBindingList.
/// All items in the list must be of type <typeparamref name="T"/>.
/// </summary>
/// <param name="list">The list of objects to base the view on.</param>
public BindingListView(IList list)
: base()
{
DataSource = list;
}

public BindingListView(IContainer container)
: base(container)
{
DataSource = null;
}

[DefaultValue(null)]
[AttributeProvider(typeof(IListSource))]
public IList DataSource
{
get
{
IEnumerator<IList> e = GetSourceLists().GetEnumerator();
e.MoveNext();
return e.Current;
}
set
{
if (value == null)
{
// Clear all current data
SourceLists = new BindingList<IList<T>>();
NewItemsList = null;
FilterAndSort();
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
return;
}

if (!(value is ICollection<T>))
{
// list is not a strongy-type collection.
// Check that items in list are all of type T
foreach (object item in value)
{
if (!(item is T))
{
throw new ArgumentException(string.Format(Properties.Resources.InvalidListItemType, typeof(T).FullName), "DataSource");
}
}
}

SourceLists = new object[] { value };
NewItemsList = value;
}
}

private bool ShouldSerializeDataSource()
{
return (SourceLists.Count > 0);
}

protected override void SourceListsChanged(object sender, ListChangedEventArgs e)
{
if ((SourceLists.Count > 1 && e.ListChangedType == ListChangedType.ItemAdded) || e.ListChangedType == ListChangedType.ItemDeleted)
{
throw new Exception("BindingListView allows strictly one source list.");
}
else
{
base.SourceListsChanged(sender, e);
}
}
}
}
87 changes: 87 additions & 0 deletions BindingListView/BindingListView.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{75AF36A8-7797-4023-B183-5B63D448420A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Equin.ApplicationFramework</RootNamespace>
<AssemblyName>Equin.ApplicationFramework.BindingListView</AssemblyName>
<StartupObject>
</StartupObject>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AggregateBindingListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="BindingListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CompositeItemFilter.cs" />
<Compile Include="ObjectView.cs" />
<Compile Include="IItemFilter.cs" />
<Compile Include="INotifyingEditableObject.cs" />
<Compile Include="InvalidSourceListException.cs" />
<Compile Include="MultiSourceIndexList.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="ProvidedViewPropertyDescriptor.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
17 changes: 17 additions & 0 deletions BindingListView/BindingListView.nuspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<licenseUrl>https://github.com/waynebloss/BindingListView/blob/master/license.txt</licenseUrl>
<projectUrl>https://github.com/waynebloss/BindingListView</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<summary>$description$</summary>
<description>The BindingListView .NET library provides a type-safe, sortable, filterable, data-bindable view of one or more lists of objects. It is the business objects equivalent of using a DataView on a DataTable in ADO.NET. If you have a list of objects to display on a Windows Forms UI (e.g. in a DataGridView) and want to allow your user to sort and filter, then this is the library to use!</description>
<releaseNotes>Initial</releaseNotes>
<copyright>Copyright 2014</copyright>
<tags>.net IBindingListView winforms</tags>
</metadata>
</package>
38 changes: 38 additions & 0 deletions BindingListView/CompositeItemFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;

namespace Equin.ApplicationFramework
{
public class CompositeItemFilter<T> : IItemFilter<T>
{
private List<IItemFilter<T>> _filters;

public CompositeItemFilter()
{
_filters = new List<IItemFilter<T>>();
}

public void AddFilter(IItemFilter<T> filter)
{
_filters.Add(filter);
}

public void RemoveFilter(IItemFilter<T> filter)
{
_filters.Remove(filter);
}

public bool Include(T item)
{
foreach (IItemFilter<T> filter in _filters)
{
if (!filter.Include(item))
{
return false;
}
}
return true;
}

}
}
143 changes: 143 additions & 0 deletions BindingListView/IItemFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Equin.ApplicationFramework
{
/// <summary>
/// Defines a general method to test it an item should be included in a <see cref="BindingListView&lt;T&gt;"/>.
/// </summary>
/// <typeparam name="T">The type of item to be filtered.</typeparam>
public interface IItemFilter<T>
{
/// <summary>
/// Tests if the item should be included.
/// </summary>
/// <param name="item">The item to test.</param>
/// <returns>True if the item should be included, otherwise false.</returns>
bool Include(T item);
}

/// <summary>
/// A dummy filter that is used when no filter is needed.
/// It simply includes any and all items tested.
/// </summary>
public class IncludeAllItemFilter<T> : IItemFilter<T>
{
public bool Include(T item)
{
// All items are to be included.
// So always return true.
return true;
}

public override string ToString()
{
return Properties.Resources.NoFilter;
}

#region Singleton Accessor

private static IncludeAllItemFilter<T> _instance;

/// <summary>
/// Gets the singleton instance of <see cref="IncludeAllItemFilter&lt;T&gt;"/>.
/// </summary>
public static IncludeAllItemFilter<T> Instance
{
get
{
if (_instance == null)
{
_instance = new IncludeAllItemFilter<T>();
}
return _instance;
}
}

#endregion
}

/// <summary>
/// A filter that uses a user-defined <see cref="Predicate&lt;T&gt;"/> to test items for inclusion in <see cref="BindingListView&lt;T&gt;"/>.
/// </summary>
public class PredicateItemFilter<T> : IItemFilter<T>
{
/// <summary>
/// Creates a new <see cref="PredicateItemFilter&lt;T&gt;"/> that uses the specified <see cref="Predicate&lt;T&gt;"/> and default name.
/// </summary>
/// <param name="includeDelegate">The <see cref="Predicate&lt;T&gt;"/> used to test items.</param>
public PredicateItemFilter(Predicate<T> includeDelegate)
: this(includeDelegate, null)
{
// The other constructor is called to do the work.
}

/// <summary>
/// Creates a new <see cref="PredicateItemFilter&lt;T&gt;"/> that uses the specified <see cref="Predicate&lt;T&gt;"/>.
/// </summary>
/// <param name="includeDelegate">The <see cref="PredicateItemFilter&lt;T&gt;"/> used to test items.</param>
/// <param name="name">The name used for the ToString() return value.</param>
public PredicateItemFilter(Predicate<T> includeDelegate, string name)
{
// We don't allow a null string. Use the default instead.
_name = name ?? defaultName;
if (includeDelegate != null)
{
_includeDelegate = includeDelegate;
}
else
{
throw new ArgumentNullException("includeDelegate", Properties.Resources.IncludeDelegateCannotBeNull);
}
}

private Predicate<T> _includeDelegate;
private string _name;
private readonly string defaultName = Properties.Resources.PredicateFilter;

public bool Include(T item)
{
return _includeDelegate(item);
}

public override string ToString()
{
return _name;
}
}

// TODO: Implement this class
/*
public class ExpressionItemFilter<T> : IItemFilter<T>
{
public ExpressionItemFilter(string expression)
{
// TODO: Parse expression into predicate
}
public bool Include(T item)
{
// TODO: use expression...
return true;
}
}
*/

// TODO: Implement this class
/*
public class CSharpItemFilter<T> : IItemFilter<T>
{
public CSharpItemFilter(string filterSourceCode)
{
}
public bool Include(T item)
{
// TODO: implement this method...
return true;
}
}
*/
}
Loading

0 comments on commit 5dedd83

Please sign in to comment.