├── Demo ├── Order.cs ├── Customer.cs ├── Database.cs ├── MainForm.cs ├── Program.cs ├── app.config ├── Demo.exe.config ├── Properties │ ├── Settings.settings │ ├── AssemblyInfo.cs │ ├── Settings.Designer.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Demo.csproj ├── MainForm.Designer.cs └── MainForm.resx ├── MasterDetailDemo ├── Program.cs ├── Customer.cs ├── MainForm.cs ├── customers.dat ├── CustomerProgram.cs ├── CustomerProgramComparers.cs ├── Properties │ ├── Settings.settings │ ├── DataSources │ │ └── Customer.datasource │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── MasterDetailDemo.csproj └── MainForm.resx ├── ObjectListView ├── Predicate.cs ├── ObjectView.cs ├── ObjectViewT.cs ├── Tests │ ├── IList.cs │ ├── Order.cs │ ├── Company.cs │ ├── Customer.cs │ ├── AccountRep.cs │ ├── FilterNode.cs │ ├── ITypedList.cs │ ├── IBindingList.cs │ ├── ICancelAddNew.cs │ ├── ICollection.cs │ ├── IEnumerable.cs │ ├── NotifyingList.cs │ ├── SimpleClass.cs │ ├── ViewFactory.cs │ ├── CustomerProgram.cs │ ├── ObjectListView.cs │ ├── ExtendedProperty.cs │ ├── IBindingListView.cs │ ├── NotifyingListItem.cs │ ├── DateTimeDayComparer.cs │ ├── RelationalExpression.cs │ ├── SimpleEditableObject.cs │ ├── StringLengthComparer.cs │ ├── ExplicitEditableObject.cs │ ├── IRaiseItemChangedEvents.cs │ └── NotifyingListItemEvents.cs ├── AnalysisForm.cs ├── ObjectListView.cs ├── VisualizerForm.cs ├── ExtendedProperty.cs ├── FilterEvaluator.cs ├── FilterEvaluatorT.cs ├── ObjectListViewT.cs ├── SortDescription.cs ├── VisualizerTForm.cs ├── RelationalOperator.cs ├── TestsGeneric │ ├── IList.cs │ ├── IListT.cs │ ├── ICollection.cs │ ├── IEnumerable.cs │ ├── ITypedList.cs │ ├── ViewFactory.cs │ ├── IBindingList.cs │ ├── ICancelAddNew.cs │ ├── ICollectionT.cs │ ├── IEnumerableT.cs │ ├── NotifyingList.cs │ ├── IBindingListView.cs │ ├── ObjectListView.cs │ └── IRaiseItemChangedEvents.cs ├── IEditableObjectEvents.cs ├── ListItemChangeEvents.cs ├── RelationalExpression.cs ├── RemovingItemEventArgs.cs ├── ObjectListViewVisualizer.cs ├── PropertyPathDescriptor.cs ├── StringComparerPredicate.cs ├── StringComparerPredicateT.cs ├── ExtendedPropertyDescriptor.cs ├── ExtendedPropertyEventArgs.cs ├── PropertyComparerCollection.cs ├── PropertyComparerPredicate.cs ├── SortDescriptionCollection.cs ├── LogicalOperator.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.resx │ └── Resources.Designer.cs ├── AnalysisForm.Designer.cs ├── AnalysisForm.resx ├── VisualizerTForm.resx ├── VisualizerForm.resx ├── ObjectListView.csproj └── FilterNode.cs ├── LICENSE ├── ObjectListView.sln ├── .gitignore └── README.md /Demo/Order.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/Demo/Order.cs -------------------------------------------------------------------------------- /Demo/Customer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/Demo/Customer.cs -------------------------------------------------------------------------------- /Demo/Database.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/Demo/Database.cs -------------------------------------------------------------------------------- /Demo/MainForm.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/Demo/MainForm.cs -------------------------------------------------------------------------------- /Demo/Program.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/Demo/Program.cs -------------------------------------------------------------------------------- /MasterDetailDemo/Program.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/Program.cs -------------------------------------------------------------------------------- /ObjectListView/Predicate.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Predicate.cs -------------------------------------------------------------------------------- /MasterDetailDemo/Customer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/Customer.cs -------------------------------------------------------------------------------- /MasterDetailDemo/MainForm.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/MainForm.cs -------------------------------------------------------------------------------- /ObjectListView/ObjectView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ObjectView.cs -------------------------------------------------------------------------------- /ObjectListView/ObjectViewT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ObjectViewT.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/IList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/IList.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/Order.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/Order.cs -------------------------------------------------------------------------------- /MasterDetailDemo/customers.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/customers.dat -------------------------------------------------------------------------------- /ObjectListView/AnalysisForm.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/AnalysisForm.cs -------------------------------------------------------------------------------- /ObjectListView/ObjectListView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ObjectListView.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/Company.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/Company.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/Customer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/Customer.cs -------------------------------------------------------------------------------- /ObjectListView/VisualizerForm.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/VisualizerForm.cs -------------------------------------------------------------------------------- /ObjectListView/ExtendedProperty.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ExtendedProperty.cs -------------------------------------------------------------------------------- /ObjectListView/FilterEvaluator.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/FilterEvaluator.cs -------------------------------------------------------------------------------- /ObjectListView/FilterEvaluatorT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/FilterEvaluatorT.cs -------------------------------------------------------------------------------- /ObjectListView/ObjectListViewT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ObjectListViewT.cs -------------------------------------------------------------------------------- /ObjectListView/SortDescription.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/SortDescription.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/AccountRep.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/AccountRep.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/FilterNode.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/FilterNode.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ITypedList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ITypedList.cs -------------------------------------------------------------------------------- /ObjectListView/VisualizerTForm.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/VisualizerTForm.cs -------------------------------------------------------------------------------- /MasterDetailDemo/CustomerProgram.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/CustomerProgram.cs -------------------------------------------------------------------------------- /ObjectListView/RelationalOperator.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/RelationalOperator.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/IBindingList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/IBindingList.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ICancelAddNew.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ICancelAddNew.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ICollection.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ICollection.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/IEnumerable.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/IEnumerable.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/NotifyingList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/NotifyingList.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/SimpleClass.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/SimpleClass.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ViewFactory.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ViewFactory.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IList.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IListT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IListT.cs -------------------------------------------------------------------------------- /ObjectListView/IEditableObjectEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/IEditableObjectEvents.cs -------------------------------------------------------------------------------- /ObjectListView/ListItemChangeEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ListItemChangeEvents.cs -------------------------------------------------------------------------------- /ObjectListView/RelationalExpression.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/RelationalExpression.cs -------------------------------------------------------------------------------- /ObjectListView/RemovingItemEventArgs.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/RemovingItemEventArgs.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/CustomerProgram.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/CustomerProgram.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ObjectListView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ObjectListView.cs -------------------------------------------------------------------------------- /ObjectListView/ObjectListViewVisualizer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ObjectListViewVisualizer.cs -------------------------------------------------------------------------------- /ObjectListView/PropertyPathDescriptor.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/PropertyPathDescriptor.cs -------------------------------------------------------------------------------- /ObjectListView/StringComparerPredicate.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/StringComparerPredicate.cs -------------------------------------------------------------------------------- /ObjectListView/StringComparerPredicateT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/StringComparerPredicateT.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ExtendedProperty.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ExtendedProperty.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/IBindingListView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/IBindingListView.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/NotifyingListItem.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/NotifyingListItem.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ICollection.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ICollection.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IEnumerable.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IEnumerable.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ITypedList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ITypedList.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ViewFactory.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ViewFactory.cs -------------------------------------------------------------------------------- /MasterDetailDemo/CustomerProgramComparers.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/MasterDetailDemo/CustomerProgramComparers.cs -------------------------------------------------------------------------------- /ObjectListView/ExtendedPropertyDescriptor.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ExtendedPropertyDescriptor.cs -------------------------------------------------------------------------------- /ObjectListView/ExtendedPropertyEventArgs.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/ExtendedPropertyEventArgs.cs -------------------------------------------------------------------------------- /ObjectListView/PropertyComparerCollection.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/PropertyComparerCollection.cs -------------------------------------------------------------------------------- /ObjectListView/PropertyComparerPredicate.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/PropertyComparerPredicate.cs -------------------------------------------------------------------------------- /ObjectListView/SortDescriptionCollection.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/SortDescriptionCollection.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/DateTimeDayComparer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/DateTimeDayComparer.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/RelationalExpression.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/RelationalExpression.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/SimpleEditableObject.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/SimpleEditableObject.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/StringLengthComparer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/StringLengthComparer.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IBindingList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IBindingList.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ICancelAddNew.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ICancelAddNew.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ICollectionT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ICollectionT.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IEnumerableT.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IEnumerableT.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/NotifyingList.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/NotifyingList.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/ExplicitEditableObject.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/ExplicitEditableObject.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/IRaiseItemChangedEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/IRaiseItemChangedEvents.cs -------------------------------------------------------------------------------- /ObjectListView/Tests/NotifyingListItemEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/Tests/NotifyingListItemEvents.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IBindingListView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IBindingListView.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/ObjectListView.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/ObjectListView.cs -------------------------------------------------------------------------------- /ObjectListView/TestsGeneric/IRaiseItemChangedEvents.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jessejohnston/ObjectListView/HEAD/ObjectListView/TestsGeneric/IRaiseItemChangedEvents.cs -------------------------------------------------------------------------------- /ObjectListView/LogicalOperator.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace JesseJohnston 3 | { 4 | internal enum LogicalOperator 5 | { 6 | None = 0, 7 | Or, 8 | And 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Demo/Demo.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/DataSources/Customer.datasource: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | MasterDetailDemo.Customer, MasterDetailDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /Demo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?xml version="1.0" encoding="utf-16"?> 7 | <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 8 | <ConnectionString>Data Source=DADBOX;Initial Catalog=Northwind;Integrated Security=True</ConnectionString> 9 | <ProviderName>System.Data.SqlClient</ProviderName> 10 | </SerializableConnectionString> 11 | Data Source=DADBOX;Initial Catalog=Northwind;Integrated Security=True 12 | 13 | 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jesse Johnston 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MasterDetailDemo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Demo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Demo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Demo")] 13 | [assembly: AssemblyCopyright("Copyright © 2006 Jesse Johnston. All rights reserved.")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8ae082d7-be2c-4929-af99-218677570541")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | [assembly: AssemblyVersion("1.0.0.0")] 33 | [assembly: AssemblyFileVersion("1.0.0.0")] 34 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MasterDetailDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MasterDetailDemo")] 13 | [assembly: AssemblyCopyright("Copyright © 2006")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1bb74c07-a8f4-41d3-8f81-c7ab06d02a19")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | [assembly: AssemblyVersion("1.0.0.0")] 33 | [assembly: AssemblyFileVersion("1.0.0.0")] 34 | -------------------------------------------------------------------------------- /ObjectListView/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // ObjectListView 2 | // Copyright © 2006-2015 Jesse Johnston. All rights reserved. 3 | 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | using System.Runtime.InteropServices; 7 | 8 | // General Information about an assembly is controlled through the following 9 | // set of attributes. Change these attribute values to modify the information 10 | // associated with an assembly. 11 | [assembly: AssemblyTitle("ObjectListView")] 12 | [assembly: AssemblyDescription("Sorting, filtering view for lists of arbitrary objects.")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("Jesse Johnston")] 15 | [assembly: AssemblyProduct("ObjectListView")] 16 | [assembly: AssemblyCopyright("Copyright © 2006-2015 Jesse Johnston. All rights reserved.")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // Setting ComVisible to false makes the types in this assembly not visible 21 | // to COM components. If you need to access a type in this assembly from 22 | // COM, set the ComVisible attribute to true on that type. 23 | [assembly: ComVisible(false)] 24 | 25 | // The following GUID is for the ID of the typelib if this project is exposed to COM 26 | [assembly: Guid("4e650ab2-e61e-4b02-840a-1b9491c65367")] 27 | 28 | // Version information for an assembly consists of the following four values: 29 | // 30 | // Major Version 31 | // Minor Version 32 | // Build Number 33 | // Revision 34 | // 35 | // You can specify all the values or you can default the Revision and Build Numbers 36 | // by using the '*' as shown below: 37 | [assembly: AssemblyVersion("1.0.0.13")] 38 | -------------------------------------------------------------------------------- /Demo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Demo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.ApplicationScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)] 29 | [global::System.Configuration.DefaultSettingValueAttribute("Data Source=DADBOX;Initial Catalog=Northwind;Integrated Security=True")] 30 | public string NorthwindConnectionString { 31 | get { 32 | return ((string)(this["NorthwindConnectionString"])); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ObjectListView.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C4D2C0D1-27C1-468C-B53D-95EF111E34CD}" 7 | ProjectSection(SolutionItems) = preProject 8 | README.md = README.md 9 | EndProjectSection 10 | EndProject 11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectListView", "ObjectListView\ObjectListView.csproj", "{3A62F36D-4E53-4532-B9EF-3B303A578B5E}" 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{1667EA56-F447-4D34-A433-7D16A2AE1DF1}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterDetailDemo", "MasterDetailDemo\MasterDetailDemo.csproj", "{15156FE2-17EC-44C5-A096-80961C06B753}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug - Test|Any CPU = Debug - Test|Any CPU 20 | Release - Test|Any CPU = Release - Test|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Debug - Test|Any CPU.ActiveCfg = Debug|Any CPU 25 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Debug - Test|Any CPU.Build.0 = Debug|Any CPU 26 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Release - Test|Any CPU.ActiveCfg = Release - Test|Any CPU 27 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Release - Test|Any CPU.Build.0 = Release - Test|Any CPU 28 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Debug - Test|Any CPU.ActiveCfg = Debug|Any CPU 31 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Debug - Test|Any CPU.Build.0 = Debug|Any CPU 32 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Release - Test|Any CPU.ActiveCfg = Release - Test|Any CPU 33 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Release - Test|Any CPU.Build.0 = Release - Test|Any CPU 34 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {15156FE2-17EC-44C5-A096-80961C06B753}.Debug - Test|Any CPU.ActiveCfg = Debug|Any CPU 37 | {15156FE2-17EC-44C5-A096-80961C06B753}.Debug - Test|Any CPU.Build.0 = Debug|Any CPU 38 | {15156FE2-17EC-44C5-A096-80961C06B753}.Release - Test|Any CPU.ActiveCfg = Release - Test|Any CPU 39 | {15156FE2-17EC-44C5-A096-80961C06B753}.Release - Test|Any CPU.Build.0 = Release - Test|Any CPU 40 | {15156FE2-17EC-44C5-A096-80961C06B753}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {15156FE2-17EC-44C5-A096-80961C06B753}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /Demo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Demo.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MasterDetailDemo.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MasterDetailDemo.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | [Dd]ebug/ 11 | [Dd]ebugPublic/ 12 | [Rr]elease/ 13 | [Rr]eleases/ 14 | x64/ 15 | x86/ 16 | build/ 17 | bld/ 18 | [Bb]in/ 19 | [Oo]bj/ 20 | 21 | # Roslyn cache directories 22 | *.ide/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | #NUNIT 29 | *.VisualState.xml 30 | TestResult.xml 31 | 32 | # Build Results of an ATL Project 33 | [Dd]ebugPS/ 34 | [Rr]eleasePS/ 35 | dlldata.c 36 | 37 | *_i.c 38 | *_p.c 39 | *_i.h 40 | *.ilk 41 | *.meta 42 | *.obj 43 | *.pch 44 | *.pdb 45 | *.pgc 46 | *.pgd 47 | *.rsp 48 | *.sbr 49 | *.tlb 50 | *.tli 51 | *.tlh 52 | *.tmp 53 | *.tmp_proj 54 | *.log 55 | *.vspscc 56 | *.vssscc 57 | .builds 58 | *.pidb 59 | *.svclog 60 | *.scc 61 | 62 | # Chutzpah Test files 63 | _Chutzpah* 64 | 65 | # Visual C++ cache files 66 | ipch/ 67 | *.aps 68 | *.ncb 69 | *.opensdf 70 | *.sdf 71 | *.cachefile 72 | 73 | # Visual Studio profiler 74 | *.psess 75 | *.vsp 76 | *.vspx 77 | 78 | # TFS 2012 Local Workspace 79 | $tf/ 80 | 81 | # Guidance Automation Toolkit 82 | *.gpState 83 | 84 | # ReSharper is a .NET coding add-in 85 | _ReSharper*/ 86 | *.[Rr]e[Ss]harper 87 | *.DotSettings.user 88 | 89 | # JustCode is a .NET coding addin-in 90 | .JustCode 91 | 92 | # TeamCity is a build add-in 93 | _TeamCity* 94 | 95 | # DotCover is a Code Coverage Tool 96 | *.dotCover 97 | 98 | # NCrunch 99 | _NCrunch_* 100 | .*crunch*.local.xml 101 | 102 | # MightyMoose 103 | *.mm.* 104 | AutoTest.Net/ 105 | 106 | # Web workbench (sass) 107 | .sass-cache/ 108 | 109 | # Installshield output folder 110 | [Ee]xpress/ 111 | 112 | # DocProject is a documentation generator add-in 113 | DocProject/buildhelp/ 114 | DocProject/Help/*.HxT 115 | DocProject/Help/*.HxC 116 | DocProject/Help/*.hhc 117 | DocProject/Help/*.hhk 118 | DocProject/Help/*.hhp 119 | DocProject/Help/Html2 120 | DocProject/Help/html 121 | 122 | # Click-Once directory 123 | publish/ 124 | 125 | # Publish Web Output 126 | *.[Pp]ublish.xml 127 | *.azurePubxml 128 | # TODO: Comment the next line if you want to checkin your web deploy settings 129 | # but database connection strings (with potential passwords) will be unencrypted 130 | *.pubxml 131 | *.publishproj 132 | 133 | # NuGet Packages 134 | *.nupkg 135 | # The packages folder can be ignored because of Package Restore 136 | **/packages/* 137 | # except build/, which is used as an MSBuild target. 138 | !**/packages/build/ 139 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 140 | #!**/packages/repositories.config 141 | 142 | # Windows Azure Build Output 143 | csx/ 144 | *.build.csdef 145 | 146 | # Windows Store app package directory 147 | AppPackages/ 148 | 149 | # Others 150 | sql/ 151 | *.Cache 152 | ClientBin/ 153 | [Ss]tyle[Cc]op.* 154 | ~$* 155 | *~ 156 | *.dbmdl 157 | *.dbproj.schemaview 158 | *.pfx 159 | *.publishsettings 160 | node_modules/ 161 | 162 | # RIA/Silverlight projects 163 | Generated_Code/ 164 | 165 | # Backup & report files from converting an old project file 166 | # to a newer Visual Studio version. Backup files are not needed, 167 | # because we have git ;-) 168 | _UpgradeReport_Files/ 169 | Backup*/ 170 | UpgradeLog*.XML 171 | UpgradeLog*.htm 172 | 173 | # SQL Server files 174 | *.mdf 175 | *.ldf 176 | 177 | # Business Intelligence projects 178 | *.rdl.data 179 | *.bim.layout 180 | *.bim_*.settings 181 | 182 | # Microsoft Fakes 183 | FakesAssemblies/ 184 | -------------------------------------------------------------------------------- /ObjectListView/AnalysisForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace JesseJohnston 2 | { 3 | partial class AnalysisForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.richTextBox = new System.Windows.Forms.RichTextBox(); 32 | this.buttonClose = new System.Windows.Forms.Button(); 33 | this.panel1 = new System.Windows.Forms.Panel(); 34 | this.panel1.SuspendLayout(); 35 | this.SuspendLayout(); 36 | // 37 | // richTextBox 38 | // 39 | this.richTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; 40 | this.richTextBox.Dock = System.Windows.Forms.DockStyle.Fill; 41 | this.richTextBox.Location = new System.Drawing.Point(0, 0); 42 | this.richTextBox.Name = "richTextBox"; 43 | this.richTextBox.ReadOnly = true; 44 | this.richTextBox.Size = new System.Drawing.Size(492, 226); 45 | this.richTextBox.TabIndex = 0; 46 | this.richTextBox.Text = ""; 47 | // 48 | // buttonClose 49 | // 50 | this.buttonClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 51 | this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; 52 | this.buttonClose.FlatStyle = System.Windows.Forms.FlatStyle.System; 53 | this.buttonClose.Location = new System.Drawing.Point(222, 251); 54 | this.buttonClose.Name = "buttonClose"; 55 | this.buttonClose.Size = new System.Drawing.Size(75, 23); 56 | this.buttonClose.TabIndex = 1; 57 | this.buttonClose.Text = "Close"; 58 | this.buttonClose.UseVisualStyleBackColor = true; 59 | // 60 | // panel1 61 | // 62 | this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 63 | | System.Windows.Forms.AnchorStyles.Left) 64 | | System.Windows.Forms.AnchorStyles.Right))); 65 | this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 66 | this.panel1.Controls.Add(this.richTextBox); 67 | this.panel1.Location = new System.Drawing.Point(12, 12); 68 | this.panel1.Name = "panel1"; 69 | this.panel1.Size = new System.Drawing.Size(494, 228); 70 | this.panel1.TabIndex = 2; 71 | // 72 | // AnalysisForm 73 | // 74 | this.AcceptButton = this.buttonClose; 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.CancelButton = this.buttonClose; 78 | this.ClientSize = new System.Drawing.Size(518, 286); 79 | this.Controls.Add(this.panel1); 80 | this.Controls.Add(this.buttonClose); 81 | this.MaximizeBox = false; 82 | this.MinimizeBox = false; 83 | this.Name = "AnalysisForm"; 84 | this.ShowIcon = false; 85 | this.ShowInTaskbar = false; 86 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 87 | this.Text = "Analysis: List and List Item Types"; 88 | this.panel1.ResumeLayout(false); 89 | this.ResumeLayout(false); 90 | 91 | } 92 | 93 | #endregion 94 | 95 | private System.Windows.Forms.RichTextBox richTextBox; 96 | private System.Windows.Forms.Button buttonClose; 97 | private System.Windows.Forms.Panel panel1; 98 | } 99 | } -------------------------------------------------------------------------------- /Demo/Demo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {1667EA56-F447-4D34-A433-7D16A2AE1DF1} 9 | WinExe 10 | Properties 11 | Demo 12 | Demo 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | v2.0 22 | 23 | 24 | 25 | 26 | 2.0 27 | 28 | 29 | true 30 | full 31 | false 32 | bin\Debug\ 33 | DEBUG;TRACE 34 | prompt 35 | 4 36 | 37 | 38 | pdbonly 39 | true 40 | bin\Release\ 41 | TRACE 42 | prompt 43 | 4 44 | 45 | 46 | bin\Release - Test\ 47 | TRACE 48 | true 49 | pdbonly 50 | AnyCPU 51 | prompt 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Form 67 | 68 | 69 | MainForm.cs 70 | 71 | 72 | 73 | 74 | 75 | Designer 76 | MainForm.cs 77 | 78 | 79 | ResXFileCodeGenerator 80 | Resources.Designer.cs 81 | Designer 82 | 83 | 84 | True 85 | Resources.resx 86 | True 87 | 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | True 95 | Settings.settings 96 | True 97 | 98 | 99 | 100 | 101 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E} 102 | ObjectListView 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /MasterDetailDemo/MasterDetailDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {15156FE2-17EC-44C5-A096-80961C06B753} 9 | WinExe 10 | Properties 11 | MasterDetailDemo 12 | MasterDetailDemo 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | v2.0 22 | 23 | 24 | 25 | 26 | 2.0 27 | 28 | 29 | true 30 | full 31 | false 32 | bin\Debug\ 33 | DEBUG;TRACE 34 | prompt 35 | 4 36 | 37 | 38 | pdbonly 39 | true 40 | bin\Release\ 41 | TRACE 42 | prompt 43 | 4 44 | 45 | 46 | bin\Release - Test\ 47 | TRACE 48 | true 49 | pdbonly 50 | AnyCPU 51 | prompt 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Form 68 | 69 | 70 | MainForm.cs 71 | 72 | 73 | 74 | 75 | Designer 76 | MainForm.cs 77 | 78 | 79 | ResXFileCodeGenerator 80 | Resources.Designer.cs 81 | Designer 82 | 83 | 84 | True 85 | Resources.resx 86 | True 87 | 88 | 89 | PreserveNewest 90 | 91 | 92 | 93 | SettingsSingleFileGenerator 94 | Settings.Designer.cs 95 | 96 | 97 | True 98 | Settings.settings 99 | True 100 | 101 | 102 | 103 | 104 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E} 105 | ObjectListView 106 | 107 | 108 | 109 | 116 | -------------------------------------------------------------------------------- /Demo/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /MasterDetailDemo/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /ObjectListView/AnalysisForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ObjectListView/VisualizerTForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /ObjectListView/VisualizerForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 46 125 | 126 | -------------------------------------------------------------------------------- /ObjectListView/ObjectListView.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {3A62F36D-4E53-4532-B9EF-3B303A578B5E} 9 | Library 10 | Properties 11 | JesseJohnston 12 | ObjectListView 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | false 22 | 23 | 24 | v2.0 25 | 26 | 27 | 28 | 29 | 2.0 30 | 31 | 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | TRACE;DEBUG;TEST 37 | prompt 38 | 4 39 | docs\ObjectListView.xml 40 | 41 | 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | docs\ObjectListView.xml 49 | 50 | 51 | bin\Release - Test\ 52 | TRACE;TEST 53 | true 54 | pdbonly 55 | AnyCPU 56 | prompt 57 | docs\ObjectListView.xml 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Form 71 | 72 | 73 | AnalysisForm.cs 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | True 84 | True 85 | Resources.resx 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | Form 148 | 149 | 150 | VisualizerForm.cs 151 | 152 | 153 | Form 154 | 155 | 156 | VisualizerTForm.cs 157 | 158 | 159 | 160 | 161 | Designer 162 | AnalysisForm.cs 163 | 164 | 165 | Designer 166 | VisualizerForm.cs 167 | 168 | 169 | Designer 170 | VisualizerTForm.cs 171 | 172 | 173 | 174 | 175 | Designer 176 | ResXFileCodeGenerator 177 | Resources.Designer.cs 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | PreserveNewest 186 | 187 | 188 | 189 | 190 | 191 | 192 | 199 | -------------------------------------------------------------------------------- /MasterDetailDemo/MainForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | 17, 17 125 | 126 | 127 | 148, 17 128 | 129 | 130 | 131 | 132 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 133 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAU1JREFUOE9jYBi0 134 | 4O4C9v+35nH+vzqH6//FGbz/SXbodaDGP48a//952PD/5GQB0g04P50XbsDBHhHSDTg+SRBoe93/Pw+q 135 | /u9oFydswKWZPP/PTuX7fxKo8Ui/0P993SJAzeX//94r+r++Qeb/qhq5/0srFf/PL1X+P6tIFdPAU0B/ 136 | /nlYD9RUC8SV///cKwHivP9/72b+/3sn+f/f23H//92MAOKQ/5NyNDENONQrDHbu3/ulQI0FQI3ZQI2p 137 | QI0J///digZqDPv/70bQ/3/X/f53peliGrCzXeL/lmap/+vAzpX/v6RC8f/fWzFAjeH/p+Zp/J+QpfW/ 138 | O0P3f3uq/v/mREPCYTIb6E+Qc//dCPjfk6FDWAN6QgH5898NfyD2+9+arE+6Ad3pumD/gnB9nBHpBrQk 139 | GfxviDf8XxNr/L8y2oR0A0hO++RqAAAkI9ieo+gjUwAAAABJRU5ErkJggg== 140 | 141 | 142 | 143 | 144 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 145 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAW9JREFUOE+tkk0o 146 | w3EYx3dV3kq5uKBWDiPT8hISMiQsMiEyQ9qBg0hoFwcHUi7kgIvkQFJSTrQ4zdvmrTW1/kuT0i74x+X3 147 | MRal/fEnv8tz+H2fz/N8vz0azX88PG6wmcDp4E881hYR3VUIixF2Nr+FcO2DlbnPGjaWoM+M6DAiOitg 148 | YUoR8rqhsJTBWG/kP6fOMKTegGjKh/7mTyIx0oUw58C0/XubLM8iKtPeQIx2gfcMJgbD0FBVlRE+D7QU 149 | hS2ZshANuTDQqq75fQIHe6GVcxHV6VCr/2VzQIKmAshOQNbHc6+PhTqDOggBP5jzoDCJoLUaLo7fwr3V 150 | hSCr8z8EeHcLbSU8FCfjLU0nuL/70cB4Py5tDLL7UBnC8xMMW6EkhRNdIsGt9QjhTXkGUnsN8rVf4Q72 151 | tpFzEnGlRiH1NIL8qDjJoY1DdjkVADNjSGnReI2ZIF196VW22+D8SAFw6YLJITjaV5e2qotSIXoBiiMD 152 | HEVvQ/IAAAAASUVORK5CYII= 153 | 154 | 155 | 156 | 157 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 158 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAStJREFUOE9jYBg0 159 | oHDW8/9NC57/z5z4+D8uR4W3P8Apx5A789n/VUfe/8elKL77wf/ghmu4DciY8vT/wn0fsCqK73n4f+n+ 160 | ///9qy/gNiCh58n/aVveYyiKaL8P1pw56/9/r9ITuA2I7Hr0v3f1BxRFoa33wJpb1wFt7/z73yX/AG4D 161 | Apsf/q+b/w6uKLjl7v9Fe///7wBqzpjz879d3c//9hnbcRvgUXX/f/60NyiK7Ipv/0+f8/u/f9e3/zqF 162 | 7/5bJKzHbYB96d3/2ZNfYyjSTzn/36ToxX+VrE//jSOX4TbAIu/O/9T+11gVGSSd+C+b9vW/bvA83AYY 163 | Zt3+H9byEqci/dTL/zV8p+E2QCftxn+/6od4Fal4TMBtgFPulf8gBXgVDZqMh+wQAPB2wKsSwCgmAAAA 164 | AElFTkSuQmCC 165 | 166 | 167 | 168 | 169 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 170 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAL1JREFUOE9jYBgy 171 | ILz9wX+yHRvf/eB/cMM18gyI73n4f+n+///9qy+QbkBE+32w5sxZ//97lZ4gzYDQ1ntgza3rgLZ3/v3v 172 | kn+AeAOCW+7+X7T3//8OoOaMOT//29X9/G+fsZ14A0ChbVd8+3/6nN///bu+/dcpfPffImE9aQaADNFP 173 | Of/fpOjFf5WsT/+NI5eRbgDIEIOkE/9l077+1w2eR54BYJekXv6v4TuNfANAhqh4TKDMALKTMc01AgDQ 174 | FGCYkuTLEQAAAABJRU5ErkJggg== 175 | 176 | 177 | 178 | 179 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 180 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAKtJREFUOE9jYBh0 181 | oHDW8/8UOSp35rP/Cd33yDckY8rT//P2//6f0HWHPEMSep78n73v1//OrX//u5VeJt2QyK5H/6ds+/W/ 182 | ZOnf/wnT//63yT1LmiGBzQ//t659D9ZsXPLlv3T0tf/GkcuIN8Sj6v7/krnv4JoVXXqI1wyKPvvSu/8D 183 | W56BbSZZM8gAi7w7/20KrpCnGWSAYdZt8jWDDNBJu0GanylKtoNCMwCgfl+gC2KedgAAAABJRU5ErkJg 184 | gg== 185 | 186 | 187 | 188 | 189 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 190 | YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAATBJREFUOE9jYBhU 191 | oHDW8/+4HASSa1rw/H/mxMc41TDkznz2P6H7HlYFILlVR97/D29/gNuAjClP/8/b//t/QtcdDEUguYX7 192 | PvwPbriG24CEnif/Z+/79b9z69//bqWXURSC5KZtef/fv/oCbgMiux79n7Lt1/+SpX//J0z/+98m9yxc 193 | MUiud/WH/16lJ3AbENj88H/r2vdgzcYlX/5LR1/7bxy5DKwBJFc3/91/l/wDuA3wqLr/v2TuO7hmRZce 194 | uGKQXP60N//tM7bjNsC+9O7/wJZnYJuRNYNcAJLLnvz6v0XCetwGWOTd+W9TcAVDM8gAkFxq/2u4l7Cm 195 | F8Os21g1gxSD5MJaXv7XDZ6H2wU6aTdwSoLk/Kof/tfwnYbbAHz5yin3yn8VjwlgPKjyHwMAvtG/s0Vm 196 | x8MAAAAASUVORK5CYII= 197 | 198 | 199 | 200 | 295, 17 201 | 202 | 203 | 49 204 | 205 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ObjectListView 2 | 3 | ## .NET DataView for objects 4 | 5 | 6 | A DataView-like sorting and filtering view of a collection of arbitrary objects. This is intended primarily for use in .NET WinForms applications with DataGridViews. It allows you to bind a list of your own classes (e.g. List\) to a DataGridView and get a sorted, filtered view of your list without having to use an intermediary DataTable. ObjectListView is a full implementation of IBindingListView. See the demo code and tests for examples of how to use it. In general, just create your list, create an ObjectListView for that list, and use the ObjectListView as the DataSource for your Windows Forms control. You'll need to reference ObjectListView.dll in your project. The full class name is JesseJohnston.ObjectListView. Two versions are provided: 7 | Class | Usage 8 | ----- | ----- ObjectListView | Works with any list item type. List items are always referenced as type **object**. ObjectListView\ | Works with any list item type. List items are always referenced as type T. The functionality of the two versions is identical. The generic ObjectListView offers slightly better performance and convenience (not having to cast back and forth from object to list item type). **Note:** ObjectListView/ObjectListView\ work with any list type that implements IList, and any list item type. However, the best list type to use is BindingList\, and your list item types should implement INotifyPropertyChanged. If you don't use BindingList\ and/or your list items don't support INotifyPropertyChanged, ObjectListView won't update properly as list items change or when list items are added or removed from the underlying list. If your underlying list and list items are unchanging, it doesn't matter what kind of list or list item types you have; ObjectListView will work just fine in that case. ## Usage Here's an abridged example from the Demo.exe project. Database.GetCustomers() returns a List\ and Database.GetOrders() returns a List\. public partial class MainForm : Form 9 | { 10 | private ObjectListView viewCompanies; 11 | private ObjectListView viewOrders; 12 | 13 | private void buttonGetData_Click(object sender, EventArgs e) 14 | { 15 | Database db = new Database(); 16 | db.ConnectionString = this.textBoxConnectionString.Text; 17 | 18 | this.viewCompanies = new ObjectListView(db.GetCustomers()); 19 | this.viewOrders = new ObjectListView(db.GetOrders()); 20 | 21 | this.comboBoxCustomers.DataSource = viewCompanies; 22 | this.comboBoxCustomers.DisplayMember = "Company"; 23 | this.comboBoxCustomers.ValueMember = "Id"; 24 | 25 | this.dataGridView.AutoGenerateColumns = false; 26 | this.dataGridView.DataSource = viewOrders; 27 | 28 | this.textBoxFilter.Text = ""; 29 | this.textBoxFilter.Enabled = true; 30 | } 31 | } 32 | ## License ObjectListView is free. You are granted a perpetual, non-exclusive, royalty-free license to use the code in any commercial and non-commercial software development works. No attribution is required. Jesse Johnston retains the copyright to ObjectListView and reserves all rights not explicitly granted in this license. ## Building the source Tests are included in the same project as ObjectListView, for ease of testing internal methods. However, the test code is automatically compiled out of the release build. The build configurations containing the word "test" define the TEST pragma which includes all of the unit testing code. ## Demos Two example demos are provided. **Demo.exe** shows customer and order data from the Northwind database, illustrating data binding of ObjectListView to a ComboBox and a DataGridView. **MasterDetailDemo.exe** is a simple but real-world data entry form showing a master-detail view of customer data, with currency management through a BindingNavigator, editing in both the DataGridView and details controls, and multi-column sorting in the DataGridView. This demo also illustrates saving and loading data and the use of BeginUpdate()/EndUpdate() for better view performance. ### To run the demos MasterDetailDemo.exe requires no database or special configuration. The following steps are for Demo.exe only, which requires the Northwind database. 1. SQL Server 2000/Express (or newer) must be installed. 2. Install the Microsoft sample Northwind database, which can be downloaded from: [http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&displaylang=en][2] 3. Edit the connection string in Demo.exe.config to reference your computer name in the data source (instead of "DADBOX"). Note that SQL Server is not required for general use of ObjectListView. This demo reads data from the Northwind database, and that's the only reason why SQL Server is involved. ### Demo.exe The form shows a ComboBox and a DataGridView, each bound to a separate ObjectListView. The two ObjectListViews share a common list of Customer objects. Select a list type and a list item type to observe the behavior of the ObjectListView with those types. List item type | Description 33 | -------------- | ----------- Customer | A simple list item with no property change notification. CustomerNotifying | A list item that implements INotifyPropertyChanged. List type | Description 34 | --------- | ----------- ArrayList | An ArrayList of the selected list item type (Customer or CustomerNotifying) List\ | A generic list of the selected list item type (behaves identically to ArrayList). BindingList\ | A generic BindingList of the selected list item type. BindingList provides a ListChanged event. Using CustomerNotifying and BindingList\ produces optimal results: both list changes (add/delete) and list item changes (changing column values) are reflected correctly in the DataGridView and the ComboBox. ### MasterDetailDemo.exe The form shows TextBoxes in the top half of the form, for editing an individual list item. The New button adds a row (a new Customer object) to the DataGridView in the bottom half of the form. Click on a grid row to change the current list item, or use the navigation controls in the BindingNavigator at the bottom of the form. The data bindings for the TextBoxes cause the properties of the current grid row to be reflected in the TextBoxes. Edits in the grid rows are reflected in the TextBoxes and vice versa. Click on the grid column headers to change the sort. Clicking on a column that is already sorted will reverse the order of the sort. Holding down the shift key while clicking adds an additional column to the sort. Holding down the control key while clicking removes the column from the sort. As the sort changes, the current grid row position is changed to keep the previously selected item current. The main menu options for "Program Sort" allow you to select different custom sorts for the Program column. Changing one of these options changes the IComparer used for the Customer.Program property by updating the entry in the PropertyComparers collection of IComparers. 35 | The main menu option "Use New Row" allows you to switch between the new row in the DataGridView and the New button to add new rows to the grid. The main menu options for "Program Filter" allow you to specify a custom filter for the Program column. Check any combination of Program values to include them in the filter. Uncheck values to remove them. Check "Unfiltered" to remove the filter and display all items in the list. Use the File/Load and Save menu options to load/save the data displayed in the grid. Some sample data is provided in the file customers.dat. 36 | ## Change Log 37 | 38 | 39 | ### Version 1.0.0.13, 2/7/15 40 | 1. Upgraded solution to Visual Studio 2013. The project still targets .NET 2.0 and above. 41 | 2. Removed dependency on NUnit. The project now uses the Visual Studio test framework. 42 | 3. Merged readme and change list into a single markdown document. 43 | 4. Added sample data file to MasterDetailsDemo project. 44 | 45 | ### Version 1.0.0.12, 5/28/07 46 | 1. Added option in BeginUpdate() to defer sorting and filtering until call to EndUpdate(). 47 | 2. Fixed bug where ListChanged events were raised for list items not in the view. 48 | 3. Added Sort property that takes a string parameter containing sort property names and directions (ala DataView.Sort). 49 | 4. Added support for property paths in sorting. 50 | 51 | ### Version 1.0.0.11, 5/6/07 52 | 1. Added Select() methods to return list items that match some criteria. 53 | 2. Added Find() convenience methods and made IBindingListView.Find() an explicit interface implementation. 54 | 3. Added property path support to refer to properties of list item properties in Filter, Find() and Select(). 55 | 4. Fixed bug when deleting items from a sorted view (ListChanged+Reset and Sorted events are no longer raised). 56 | 5. Fixed bug with trailing whitespace in Filter expression. 57 | 6. Added RemovingItem event. This is raised just prior a list item removal, but only when the removal is done through 58 | a method of ObjectListView. 59 | 7. Replaced ListItemFilter usage with equivalent Predicate (and non-generic Predicate) for better framework consistency. 60 | 8. Added documentation XML file for Intellisense. 61 | 62 | ### Version 1.0.0.10, 4/1/07 63 | 1. Added documentation file. 64 | 2. Made the following properties explicit interface implementations: 65 | IBindingList.SupportsChangeNotification 66 | IBindingList.SupportsSearching 67 | IBindingList.SupportsSorting 68 | IBindingListView.SupportsAdvancedSorting 69 | IBindingListView.SupportsFiltering 70 | 3. Changed the accessibility of the following classes to internal: 71 | AnalysisForm 72 | SortDescription 73 | SortDescriptionCollection 74 | VisualizerForm 75 | VisualizerTForm 76 | 4. IList.Remove() no longer throws an exception if the item is not present in the list. 77 | 5. Fixed Filter expression bug: quotes not parsed correctly (e.g. Filter = "FirstName = 'Smi*' AND LastName = 'J*'"). 78 | 79 | 80 | ### Version 1.0.0.9, 3/11/07 81 | 1. Don't invalidate enumerators when a list item property is changed, unless the property is in the view's sort or filter criteria. 82 | 2. Exposed OnListChanged(), OnSorted(), and OnAddingNew() as protected virtual for extensibility. 83 | 3. Added ToArray() method. 84 | 4. Fixed buttonNew_Click() bug in MasterDetail demo code. 85 | 5. Fixed bug where list item property change events were not wired for items already in list at ObjectListView construction time. 86 | 6. Included license terms in Readme.txt (it's free!). 87 | 7. Added debugger visualizer! 88 | 89 | ### Version 1.0.0.8, 2/25/07 90 | 1. Extended Filter property to allow complex expressions. 91 | 2. Added ApplyFilter() method to update view when FilterPredicate criteria has changed (but the delegate has not). 92 | 93 | ### Version 1.0.0.7, 1/1/07 94 | 1. Added a generic version of ObjectListView: ObjectListView. 95 | 2. Bug fix: during AddNew() when the view is filtered, return the last view position as the index of the added item (instead of the last list position). 96 | 3. Bug fix: Raise ListChanged+Reset event when FilterPredicate property is set. 97 | 98 | ### Version 1.0.0.6, 12/26/06 99 | 1. Added ICancelAddNew support. A list item added via AddNew() is now "uncommitted" until EndNew() is called. "Uncommitted" means 100 | that the item will appear as the last item in the view, and will not be repositioned due to sorting, or excluded due to filtering. 101 | Also, no ListChanged+ItemChanged events will be raised for the uncommitted row. The uncommitted item is available through the indexer and 102 | reflected in the Count property however. 103 | 2. Behavior changes for list item types implementing IEditableObject: 104 | - During a call to AddNew(), the new (uncommitted) item is added immediately to the underlying list. 105 | - The uncommitted item is available through the indexer and Count properties. 106 | 3. Bug fix: Events are not raised when a lock is held. 107 | 108 | ### Version 1.0.0.5, 12/17/06 109 | 1. Added FilterPredicate property for code-based filtering. 110 | 2. Bug fix: When raising ListChanged+ItemDeleted for a call to ObjectListView.Remove() for a non-notifying list, set ListChangedEventArgs.NewIndex to the correct value (was zero). 111 | 112 | 113 | ### Version 1.0.0.4, 12/10/06 114 | Added property comparers for custom sorting. 115 | 116 | 117 | ### Version 1.0.0.3, 12/3/06 118 | 1. Ensure that sorting is stable (preserves original list order when item sort values are equal). 119 | 2. Added BeginUpdate() and EndUpdate() methods to improve performance when making large changes to the underlying list. 120 | 3. Added ITypedList support, allowing binding components to detect the properties of the list items. 121 | 4. Added Sorted event, which is raised after an explicit sort (ApplySort()) or an implicit sort (item property change). 122 | 5. Bug fix: Raise ListChanged+Reset only once during a sort operation when items have been added to the underlying list, unknown to the view. 123 | 6. Added additional filter operators (!=, <>, <, <=, >, >=). 124 | 125 | ### Version 1.0.0.1, 10/11/06 126 | 1. Fixed RemovedFilter (previously threw NotImplementedException). 127 | 2. Respect IsSynchronized and SyncRoot properties of underlying list 128 | - All ObjectListView methods and properties are now thread-safe IF the underlying list is synchronized. 129 | - ListChanged events are raised after the view is unlocked, to avoid deadlocks on list access in event handlers. 130 | 131 | ### Version 1.0.0.0, 10/9/06 132 | 133 | Initial version. 134 | 135 | --- 136 | Questions? Comments? Email me at or post a comment to my blog at [www.teamjohnston.net/blog][1]. Cheers, 137 | Jesse Johnston 138 | Februrary 2015 139 | 140 | [1]: http://www.teamjohnston.net/blog/ 141 | [2]: http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&displaylang=en -------------------------------------------------------------------------------- /ObjectListView/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Verdana;}{\f1{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;\red0\green128\blue0;}\fswiss\fcharset0 Arial;}} 122 | 123 | 124 | {\*\generator Msftedit 5.41.21.2506;}\viewkind4\uc1\pard\cf0\f0\fs20 If you're having trouble with ObjectListView, consider the following analysis of your list and list item types. The list is the object that you provided in the ObjectListView constructor. The list items are the objects contained in the list.\par\par 125 | 126 | 127 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support IEditableObject, which means that you cannot cancel changes made through a bound control such as the DataGridView.\par 128 | 129 | 130 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support INotifyPropertyChanged, but \cf3 does\cf0 supply one or more property change events. This means some or all changes to property values will be reflected in the view.\par 131 | 132 | 133 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support INotifyPropertyChanged or property change events, which means that changes to property values will not be refected in the view.\par 134 | 135 | 136 | \cf3\b Your list item type \cf0\i {0}\cf3\i0 is optimal.\cf0\b0\par 137 | 138 | 139 | \pard\cf1\b\f0\fs20 Your list item type \cf0\i {0}\cf1\i0 is sub-optimal.\cf0\b0\par 140 | 141 | 142 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support IEditableObject, which allows you to cancel changes made through a bound control such as the DataGridView.\par 143 | 144 | 145 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support INotifyPropertyChanged, which means that changes to property values will be refected in the view.\par 146 | 147 | 148 | \pard\par\cf2\b List modifications:\cf0\b0\par 149 | 150 | 151 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support IRaiseItemChangedEvents, which means that list item changes reported as PropertyChanged events will not be reflected in the view.\par 152 | 153 | 154 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support the ListChanged event, which means that added and deleted items will not be reflected in the view.\par 155 | 156 | 157 | The list makes no claims to thread safety.\par 158 | 159 | 160 | \pard\par\cf3\b Your list type \cf0\i {0}\cf3\i0 is optimal.\cf0\b0\par 161 | 162 | 163 | The list is read-only, which means that you cannot add, change, or delete list items through the view or a bound control.\par 164 | 165 | 166 | \pard\par\cf1\b Your list type \cf0\i {0}\cf1\i0 is sub-optimal.\cf0\b0\par 167 | 168 | 169 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support IRaiseItemChangedEvents, which means that list item changes reported as PropertyChanged events will be reflected in the view.\par 170 | 171 | 172 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support the ListChanged event, which means that added and deleted items will be reflected in the view.\par 173 | 174 | 175 | The list claims to be thread-safe, and offers a SyncRoot object for lock operations.\par 176 | 177 | 178 | \pard\par\cf2\b List thread safety:\cf0\b0\par 179 | 180 | 181 | The list is writable but is fixed in size, which means that you can change or replace list items through the view or a bound control, but cannot add or remove items.\par 182 | 183 | 184 | The list is writable and can change in size, which allows you to add, change, and remove list items through the view or a bound control.\par 185 | 186 | 187 | \pard\par\cf2\b Recommendations:\cf0\b0\par 188 | 189 | 190 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360\f1 A recommended list type is BindingList<T>, where T is your list item type. BindingList<T> implements both IBindingList and IRaiseItemChangedEvents.\par 191 | 192 | 193 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IEditableObject for your list item type (\cf2 optional\cf0 ).\par 194 | 195 | 196 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement INotifyPropertyChanged for your list item type (\cf1 important\cf0 ).\par 197 | 198 | 199 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IRaiseItemChangedEvents for your list type (\cf1 important\cf0 ).\par 200 | 201 | 202 | \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IBindingList or provide a ListChanged event for your list type (\cf1 important\cf0 ).\par 203 | 204 | -------------------------------------------------------------------------------- /Demo/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Demo 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.comboBoxCustomers = new System.Windows.Forms.ComboBox(); 34 | this.labelMatches = new System.Windows.Forms.Label(); 35 | this.textBoxFilter = new System.Windows.Forms.TextBox(); 36 | this.dataGridView = new System.Windows.Forms.DataGridView(); 37 | this.columnOrderId = new System.Windows.Forms.DataGridViewTextBoxColumn(); 38 | this.columnEmployeeId = new System.Windows.Forms.DataGridViewTextBoxColumn(); 39 | this.columnOrderDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); 40 | this.columnRequiredDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); 41 | this.columnShippedDate = new System.Windows.Forms.DataGridViewTextBoxColumn(); 42 | this.columnShipVia = new System.Windows.Forms.DataGridViewTextBoxColumn(); 43 | this.columnFreight = new System.Windows.Forms.DataGridViewTextBoxColumn(); 44 | this.columnShipName = new System.Windows.Forms.DataGridViewTextBoxColumn(); 45 | this.columnShipAddress = new System.Windows.Forms.DataGridViewTextBoxColumn(); 46 | this.columnShipCity = new System.Windows.Forms.DataGridViewTextBoxColumn(); 47 | this.columnShipRegion = new System.Windows.Forms.DataGridViewTextBoxColumn(); 48 | this.columnShipPostalCode = new System.Windows.Forms.DataGridViewTextBoxColumn(); 49 | this.columnShipCountry = new System.Windows.Forms.DataGridViewTextBoxColumn(); 50 | this.label2 = new System.Windows.Forms.Label(); 51 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 52 | this.textBoxConnectionString = new System.Windows.Forms.TextBox(); 53 | this.label3 = new System.Windows.Forms.Label(); 54 | this.buttonGetData = new System.Windows.Forms.Button(); 55 | this.groupBox2 = new System.Windows.Forms.GroupBox(); 56 | this.label4 = new System.Windows.Forms.Label(); 57 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); 58 | this.groupBox1.SuspendLayout(); 59 | this.groupBox2.SuspendLayout(); 60 | this.SuspendLayout(); 61 | // 62 | // label1 63 | // 64 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 65 | this.label1.AutoSize = true; 66 | this.label1.Location = new System.Drawing.Point(17, 57); 67 | this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 68 | this.label1.Name = "label1"; 69 | this.label1.Size = new System.Drawing.Size(69, 16); 70 | this.label1.TabIndex = 3; 71 | this.label1.Text = "Company:"; 72 | // 73 | // comboBoxCustomers 74 | // 75 | this.comboBoxCustomers.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 76 | this.comboBoxCustomers.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 77 | this.comboBoxCustomers.FlatStyle = System.Windows.Forms.FlatStyle.System; 78 | this.comboBoxCustomers.FormattingEnabled = true; 79 | this.comboBoxCustomers.Location = new System.Drawing.Point(97, 54); 80 | this.comboBoxCustomers.Margin = new System.Windows.Forms.Padding(4); 81 | this.comboBoxCustomers.Name = "comboBoxCustomers"; 82 | this.comboBoxCustomers.Size = new System.Drawing.Size(309, 24); 83 | this.comboBoxCustomers.TabIndex = 4; 84 | this.comboBoxCustomers.SelectedValueChanged += new System.EventHandler(this.comboBoxCustomers_SelectedValueChanged); 85 | // 86 | // labelMatches 87 | // 88 | this.labelMatches.AutoSize = true; 89 | this.labelMatches.Location = new System.Drawing.Point(975, 33); 90 | this.labelMatches.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 91 | this.labelMatches.Name = "labelMatches"; 92 | this.labelMatches.Size = new System.Drawing.Size(0, 16); 93 | this.labelMatches.TabIndex = 2; 94 | // 95 | // textBoxFilter 96 | // 97 | this.textBoxFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 98 | this.textBoxFilter.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 99 | this.textBoxFilter.Enabled = false; 100 | this.textBoxFilter.Location = new System.Drawing.Point(97, 22); 101 | this.textBoxFilter.Margin = new System.Windows.Forms.Padding(4); 102 | this.textBoxFilter.Name = "textBoxFilter"; 103 | this.textBoxFilter.Size = new System.Drawing.Size(161, 22); 104 | this.textBoxFilter.TabIndex = 2; 105 | this.textBoxFilter.TextChanged += new System.EventHandler(this.textBoxFilter_TextChanged); 106 | // 107 | // dataGridView 108 | // 109 | this.dataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 110 | | System.Windows.Forms.AnchorStyles.Left) 111 | | System.Windows.Forms.AnchorStyles.Right))); 112 | this.dataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells; 113 | this.dataGridView.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single; 114 | this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 115 | this.dataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 116 | this.columnOrderId, 117 | this.columnEmployeeId, 118 | this.columnOrderDate, 119 | this.columnRequiredDate, 120 | this.columnShippedDate, 121 | this.columnShipVia, 122 | this.columnFreight, 123 | this.columnShipName, 124 | this.columnShipAddress, 125 | this.columnShipCity, 126 | this.columnShipRegion, 127 | this.columnShipPostalCode, 128 | this.columnShipCountry}); 129 | this.dataGridView.Location = new System.Drawing.Point(13, 259); 130 | this.dataGridView.Margin = new System.Windows.Forms.Padding(4); 131 | this.dataGridView.Name = "dataGridView"; 132 | this.dataGridView.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single; 133 | this.dataGridView.RowHeadersWidth = 25; 134 | this.dataGridView.Size = new System.Drawing.Size(669, 193); 135 | this.dataGridView.TabIndex = 5; 136 | // 137 | // columnOrderId 138 | // 139 | this.columnOrderId.DataPropertyName = "OrderId"; 140 | this.columnOrderId.HeaderText = "Order ID"; 141 | this.columnOrderId.Name = "columnOrderId"; 142 | this.columnOrderId.Width = 83; 143 | // 144 | // columnEmployeeId 145 | // 146 | this.columnEmployeeId.DataPropertyName = "EmployeeId"; 147 | this.columnEmployeeId.HeaderText = "Employee ID"; 148 | this.columnEmployeeId.Name = "columnEmployeeId"; 149 | this.columnEmployeeId.Width = 111; 150 | // 151 | // columnOrderDate 152 | // 153 | this.columnOrderDate.DataPropertyName = "OrderDate"; 154 | this.columnOrderDate.HeaderText = "Ordered"; 155 | this.columnOrderDate.Name = "columnOrderDate"; 156 | this.columnOrderDate.Width = 83; 157 | // 158 | // columnRequiredDate 159 | // 160 | this.columnRequiredDate.DataPropertyName = "RequiredDate"; 161 | this.columnRequiredDate.HeaderText = "Required"; 162 | this.columnRequiredDate.Name = "columnRequiredDate"; 163 | this.columnRequiredDate.Width = 89; 164 | // 165 | // columnShippedDate 166 | // 167 | this.columnShippedDate.DataPropertyName = "ShippedDate"; 168 | this.columnShippedDate.HeaderText = "Shipped"; 169 | this.columnShippedDate.Name = "columnShippedDate"; 170 | this.columnShippedDate.Width = 84; 171 | // 172 | // columnShipVia 173 | // 174 | this.columnShipVia.DataPropertyName = "ShipVia"; 175 | this.columnShipVia.HeaderText = "Ship Via"; 176 | this.columnShipVia.Name = "columnShipVia"; 177 | this.columnShipVia.Width = 83; 178 | // 179 | // columnFreight 180 | // 181 | this.columnFreight.HeaderText = "Freight"; 182 | this.columnFreight.Name = "columnFreight"; 183 | this.columnFreight.Width = 74; 184 | // 185 | // columnShipName 186 | // 187 | this.columnShipName.DataPropertyName = "ShipName"; 188 | this.columnShipName.HeaderText = "Name"; 189 | this.columnShipName.Name = "columnShipName"; 190 | this.columnShipName.Width = 70; 191 | // 192 | // columnShipAddress 193 | // 194 | this.columnShipAddress.DataPropertyName = "ShipAddress"; 195 | this.columnShipAddress.HeaderText = "Address"; 196 | this.columnShipAddress.Name = "columnShipAddress"; 197 | this.columnShipAddress.Width = 84; 198 | // 199 | // columnShipCity 200 | // 201 | this.columnShipCity.DataPropertyName = "ShipCity"; 202 | this.columnShipCity.HeaderText = "City"; 203 | this.columnShipCity.Name = "columnShipCity"; 204 | this.columnShipCity.Width = 55; 205 | // 206 | // columnShipRegion 207 | // 208 | this.columnShipRegion.DataPropertyName = "ShipRegion"; 209 | this.columnShipRegion.HeaderText = "State"; 210 | this.columnShipRegion.Name = "columnShipRegion"; 211 | this.columnShipRegion.Width = 64; 212 | // 213 | // columnShipPostalCode 214 | // 215 | this.columnShipPostalCode.DataPropertyName = "ShipPostalCode"; 216 | this.columnShipPostalCode.HeaderText = "Zip Code"; 217 | this.columnShipPostalCode.Name = "columnShipPostalCode"; 218 | this.columnShipPostalCode.Width = 88; 219 | // 220 | // columnShipCountry 221 | // 222 | this.columnShipCountry.DataPropertyName = "ShipCountry"; 223 | this.columnShipCountry.HeaderText = "Country"; 224 | this.columnShipCountry.Name = "columnShipCountry"; 225 | this.columnShipCountry.Width = 78; 226 | // 227 | // label2 228 | // 229 | this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 230 | this.label2.AutoSize = true; 231 | this.label2.Location = new System.Drawing.Point(47, 25); 232 | this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 233 | this.label2.Name = "label2"; 234 | this.label2.Size = new System.Drawing.Size(40, 16); 235 | this.label2.TabIndex = 1; 236 | this.label2.Text = "Filter:"; 237 | // 238 | // groupBox1 239 | // 240 | this.groupBox1.Controls.Add(this.textBoxConnectionString); 241 | this.groupBox1.Controls.Add(this.label3); 242 | this.groupBox1.Controls.Add(this.buttonGetData); 243 | this.groupBox1.Location = new System.Drawing.Point(13, 15); 244 | this.groupBox1.Margin = new System.Windows.Forms.Padding(4); 245 | this.groupBox1.Name = "groupBox1"; 246 | this.groupBox1.Padding = new System.Windows.Forms.Padding(4); 247 | this.groupBox1.Size = new System.Drawing.Size(420, 108); 248 | this.groupBox1.TabIndex = 0; 249 | this.groupBox1.TabStop = false; 250 | this.groupBox1.Text = "Data Source"; 251 | // 252 | // textBoxConnectionString 253 | // 254 | this.textBoxConnectionString.Location = new System.Drawing.Point(136, 29); 255 | this.textBoxConnectionString.Name = "textBoxConnectionString"; 256 | this.textBoxConnectionString.Size = new System.Drawing.Size(277, 22); 257 | this.textBoxConnectionString.TabIndex = 7; 258 | // 259 | // label3 260 | // 261 | this.label3.AutoSize = true; 262 | this.label3.Location = new System.Drawing.Point(17, 32); 263 | this.label3.Name = "label3"; 264 | this.label3.Size = new System.Drawing.Size(113, 16); 265 | this.label3.TabIndex = 6; 266 | this.label3.Text = "Connection string:"; 267 | // 268 | // buttonGetData 269 | // 270 | this.buttonGetData.FlatStyle = System.Windows.Forms.FlatStyle.System; 271 | this.buttonGetData.Location = new System.Drawing.Point(20, 64); 272 | this.buttonGetData.Margin = new System.Windows.Forms.Padding(4); 273 | this.buttonGetData.Name = "buttonGetData"; 274 | this.buttonGetData.Size = new System.Drawing.Size(100, 28); 275 | this.buttonGetData.TabIndex = 5; 276 | this.buttonGetData.Text = "Get Data"; 277 | this.buttonGetData.UseVisualStyleBackColor = true; 278 | this.buttonGetData.Click += new System.EventHandler(this.buttonGetData_Click); 279 | // 280 | // groupBox2 281 | // 282 | this.groupBox2.Controls.Add(this.textBoxFilter); 283 | this.groupBox2.Controls.Add(this.label1); 284 | this.groupBox2.Controls.Add(this.label2); 285 | this.groupBox2.Controls.Add(this.comboBoxCustomers); 286 | this.groupBox2.Location = new System.Drawing.Point(13, 130); 287 | this.groupBox2.Name = "groupBox2"; 288 | this.groupBox2.Size = new System.Drawing.Size(413, 96); 289 | this.groupBox2.TabIndex = 6; 290 | this.groupBox2.TabStop = false; 291 | this.groupBox2.Text = "Company"; 292 | // 293 | // label4 294 | // 295 | this.label4.AutoSize = true; 296 | this.label4.Location = new System.Drawing.Point(12, 239); 297 | this.label4.Name = "label4"; 298 | this.label4.Size = new System.Drawing.Size(52, 16); 299 | this.label4.TabIndex = 7; 300 | this.label4.Text = "Orders:"; 301 | // 302 | // MainForm 303 | // 304 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 305 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 306 | this.ClientSize = new System.Drawing.Size(695, 465); 307 | this.Controls.Add(this.label4); 308 | this.Controls.Add(this.groupBox2); 309 | this.Controls.Add(this.groupBox1); 310 | this.Controls.Add(this.dataGridView); 311 | this.Controls.Add(this.labelMatches); 312 | this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 313 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 314 | this.Margin = new System.Windows.Forms.Padding(4); 315 | this.Name = "MainForm"; 316 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 317 | this.Text = "ObjectListView Demo"; 318 | ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); 319 | this.groupBox1.ResumeLayout(false); 320 | this.groupBox1.PerformLayout(); 321 | this.groupBox2.ResumeLayout(false); 322 | this.groupBox2.PerformLayout(); 323 | this.ResumeLayout(false); 324 | this.PerformLayout(); 325 | 326 | } 327 | 328 | #endregion 329 | 330 | private System.Windows.Forms.Label label1; 331 | private System.Windows.Forms.ComboBox comboBoxCustomers; 332 | private System.Windows.Forms.Label labelMatches; 333 | private System.Windows.Forms.TextBox textBoxFilter; 334 | private System.Windows.Forms.DataGridView dataGridView; 335 | private System.Windows.Forms.Label label2; 336 | private System.Windows.Forms.GroupBox groupBox1; 337 | private System.Windows.Forms.Button buttonGetData; 338 | private System.Windows.Forms.TextBox textBoxConnectionString; 339 | private System.Windows.Forms.Label label3; 340 | private System.Windows.Forms.GroupBox groupBox2; 341 | private System.Windows.Forms.Label label4; 342 | private System.Windows.Forms.DataGridViewTextBoxColumn columnOrderId; 343 | private System.Windows.Forms.DataGridViewTextBoxColumn columnEmployeeId; 344 | private System.Windows.Forms.DataGridViewTextBoxColumn columnOrderDate; 345 | private System.Windows.Forms.DataGridViewTextBoxColumn columnRequiredDate; 346 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShippedDate; 347 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipVia; 348 | private System.Windows.Forms.DataGridViewTextBoxColumn columnFreight; 349 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipName; 350 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipAddress; 351 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipCity; 352 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipRegion; 353 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipPostalCode; 354 | private System.Windows.Forms.DataGridViewTextBoxColumn columnShipCountry; 355 | } 356 | } 357 | 358 | -------------------------------------------------------------------------------- /Demo/MainForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | True 125 | 126 | 127 | True 128 | 129 | 130 | True 131 | 132 | 133 | True 134 | 135 | 136 | True 137 | 138 | 139 | True 140 | 141 | 142 | True 143 | 144 | 145 | True 146 | 147 | 148 | True 149 | 150 | 151 | True 152 | 153 | 154 | True 155 | 156 | 157 | True 158 | 159 | 160 | 55 161 | 162 | 163 | 164 | 165 | AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAAAA 166 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 167 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 168 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgWhW/2NJNf9jSTX/Y0k1/2NJ 169 | Nf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJ 170 | Nf9jSTX/Y0k1/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEa1n/9NvO/97A 171 | sf/cvq7/27ys/9u7qv/Zuaj/2Lel/9i1o//Xs6H/1rGf/9awnP/UrZr/1KuX/9Kqlv/SqJP/0KaR/9Ck 172 | j//Po43/z6CL/82fif/Nnof/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZu 173 | W//03NH/+u7p//ns5v/56uP/9+ff//jl3P/349r/9uDX//Xf1P/03dH/9NvO//PYy//z1sj/8tPF//HR 174 | wv/xz7//8M28/+/Luf/vybb/7se0/82gif9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 175 | AAAAAAAAiXBe//Xf0//68Oz/+e7o//nr5v/56eL/+Off//jl3P/249r/9eHW//Xe1P/13dH/9NrN//PY 176 | y//z1cj/8tPF//HRwf/wz77/7828/+/Kuf/vyLf/z6GL/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 177 | AAAAAAAAAAAAAAAAAACLc2H/9uDW//vy7v/68ev/2Goy/9RoMf/QZjH/y2Qv/8VhLv/AXi3/uVor/7JX 178 | Kv+rVCn/pFAm/55NJv+YSiT/kkgi/45FIv+JQiH/8My7/+/Luf/Qoo3/Y0k1/wAAAAAAAAAAAAAAAAAA 179 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI12ZP/24tj//PTy//zz7v/78Ov/+u3o//rs5f/46eH/+Obf//fk 180 | 3P/24tn/9uHW//be0//13ND/9NnO//PYyv/z1cj/8dPE//HQwf/wzr//8My8/9Ckj/9jSTX/AAAAAAAA 181 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj3hn//fk2//89vT//PTx//vz7v/68Ov/+u7o//nr 182 | 5f/56eH/+Off//fk3P/24tn/9uDW//Xe0//03ND/9NrO//PXyv/z1cf/8tPE//HRwf/wzr7/0aaR/2NJ 183 | Nf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSe2n/+Obe//359v/89/P/2Goy/9Rp 184 | Mf/QZzD/zGMv/8ZhLv/AXS3/uVss/7JXKv+sVCj/pFEn/55NJf+YSiT/kkgj/45EIv+KQiH/8tLD//HR 185 | wf/SqZT/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJV9bP/46OH//vr5//34 186 | 9v/89vP/+/Tx//vy7f/67+v/+u7n//nr5f/46eH/+Obe//fk3P/34tn/9eDV//Xe0//03ND/9NnN//TX 187 | yv/y1cf/8tLE/9Orlv9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAln9v//nq 188 | 4//+/Pr//vr4//349f/89vP/+/Tx//zx7f/68Or/+u3n//nq5P/46eH/9+fe//bk2//24tj/9eDW//Xe 189 | 0v/03ND/9NnN//PXyf/z1Mb/1KyZ/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 190 | AACYgnH/+ezm///9/f/+/Pv/2Goy/9VoMf/QZjH/zGQv/8ZhLv/AXiz/uVor/7JXKf+rVCn/pVEn/55N 191 | Jv+YSiT/kkgj/45FIv+JQyH/9NrM//PXyf/Vrpv/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 192 | AAAAAAAAAAAAAJuEc//67uj///7+//79/f/++/r//fn4//349v/99vL/+/Tw//vy7f/67+r/+u3n//nq 193 | 5P/46OD/9+bd//fj2//24tj/9t/W//Xd0v/028//89nM/9axnv9jSTX/AAAAAAAAAAAAAAAAAAAAAAAA 194 | AAAAAAAAAAAAAAAAAAAAAAAAnYd2//rx6/////////7+//79/P/++/r//fr4//349v/89vP/+/Tw//vy 195 | 7f/67+r/+e3n//jq4//46OD/9+bd//fj2v/24tj/9uDV//Xd0//028//17Og/2NJNf8AAAAAAAAAAAAA 196 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACfiXn/+/Lu////////////2Goy/9RpMf/QZjD/zGQv/8Zh 197 | Lv/AXi3/ulsr/7NXKf+sVCj/pVEm/59NJf+YSiT/kkcj/41FIv+KQyH/9uDU//Xd0v/XtaP/Y0k1/wAA 198 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKKMe//79PH///////////////////7+//79 199 | /P/++/r//fn3//339f/89fL/+/Pv//vy7f/67+n/+ezn//jq4//46OD/+Obd//fj2v/24dj/9t/U/9m3 200 | pf9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApI5+//z28/////////////// 201 | //////////7+//78/P/++/r//fn3//z39f/89fL/+/Pv//vx7P/67+n/+ezm//jq4//46OD/+OXc//bj 202 | 2v/24df/2rmn/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmkYH//fj2//// 203 | ////////2Goy/9VpMv/QZzD/zGQv/8ZhLv/AXiz/uVss/7NXKv+rVCj/pVEn/55OJf+YSiT/k0cj/41E 204 | If+JQiD/+Obd//fj2v/buqr/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqU 205 | hP/++fj//////////////////////////////////v39//79/P/++/n//fn3//349P/89fL/+/Pv//rx 206 | 7P/67+j/+e3m//jq4v/46OD/+OXc/9u8rP9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 207 | AAAAAAAArJaH//77+v////////////////////////////////////////3+//78+//++/r//fn2//33 208 | 9P/89fL/+/Pu//vw7P/57un/+uzm//nq4//459//3L6u/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 209 | AAAAAAAAAAAAAAAAAACumYr//vz8////////////2Goy/9VoMf/RZjH/zGMv/8ZhLv/AXi3/ulor/7JX 210 | Kv+sVCj/pVEm/55NJv+YSyT/kkcj/41EIf+KQyD/+uvm//np4v/dwbH/Y0k1/wAAAAAAAAAAAAAAAAAA 211 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAALGcjf///v3///////////////////////////////////////// 212 | /////v////79//79+//9+/n//fn3//z29P/89PH/+/Lu//vw6//67uj/+evl/9/Cs/9jSTX/AAAAAAAA 213 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs56P//////////////////////////////////// 214 | /////////////////////////v79//78+//++/n//fn3//z39P/89PH/+/Lu//vw6//67uj/38S2/2NJ 215 | Nf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1oJL/////////////////2Goy/9Rp 216 | Mf/QZjD/zGMv/8ZhLv/AXi3/uVos/7JXKv+sVCj/pVAm/55OJf+YSiT//fn2//z29P/89fH/+/Pt//rw 217 | 6//gx7j/Y0k1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALijlP////////////// 218 | /////////////////////////////////////////////////////v7///78//77+//++vn//fj2/8m0 219 | qf+9pZf/spmJ/6SKeP9jSTX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuqaY//// 220 | //////////////////////////////////////////////////////////////////////7//v38//78 221 | +/+eh3b/Y0k1/2NJNf9jSTX/Y0k1/2NJNf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 222 | AAC8qJr///////////////////////////////////////////////////////////////////////// 223 | //////////38/6CJef/Vxb3/x7Gl/7mhkv9sUj7/Y0k1ZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 224 | AAAAAAAAAAAAAL6qnP////////////////////////////////////////////////////////////// 225 | //////////////////////7/oox8/+Pa0//Vxbz/eWBM/2xSPmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 226 | AAAAAAAAAAAAAAAAAAAAAAAAwK2f//////////////////////////////////////////////////// 227 | //////////////////////////////////+ljn7/8+/t/4hwXf95YExmAAAAAAAAAAAAAAAAAAAAAAAA 228 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCr6H////////////////////////9/P/++/v//fn4//34 229 | 9f/89fL/+/Pv//vw6//67ej/+evk//jp4v/3593/9+Tb/6eRgv+Wf27/iHBdZgAAAAAAAAAAAAAAAAAA 230 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMWxo//Dr6H/wq6g/8Csn/+/q5z/vamb/7yn 231 | mv+7ppf/uKSV/7eilP+2oZL/s5+Q/7Kdj/+wm43/rpqL/62YiP+rlof/qZSE/5Z/bmYAAAAAAAAAAAAA 232 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 233 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 234 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/////wAAAf8AAAH/AAAB/wAAAf8AAAH/AA 235 | AB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AA 236 | AB/wAAAf8AAAH/AAAB/wAAAf8AAAH/AAAD/wAAB/8AAA//AAAf//////KAAAABAAAAAgAAAAAQAgAAAA 237 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAt6KT/2NJNf9jSTX/Y0k1/2NJNf9jSTX/Y0k1/2NJ 238 | Nf9jSTX/Y0k1/2NJNf9jSTX/AAAAAAAAAAAAAAAAAAAAALeik//35dz/t6KT/7eik/+3opP/t6KT/7ei 239 | k/+3opP/t6KT/7eik/+3opP/Y0k1/wAAAAAAAAAAAAAAAAAAAAC3opP/+eni//jm3f/34tj/9d7T//Tb 240 | zv/z18r/8tTF//HQwf/wzbz/t6KT/2NJNf8AAAAAAAAAAAAAAAAAAAAAt6KT//nu6P/46uP/+Obe//fj 241 | 2f/139X/9dvQ//PYy//y1cb/8dHC/7eik/9jSTX/AAAAAAAAAAAAAAAAAAAAALeik//78u3/2Goy/9Bl 242 | Mf/EYC3/t1kr/6dRKP+aSyX/jkUi//PVx/+3opP/Y0k1/wAAAAAAAAAAAAAAAAAAAAC3opP//Pbz//vy 243 | 7v/77+r/+evm//no4f/35dv/9uHX//Te0//z2s3/t6KT/2NJNf8AAAAAAAAAAAAAAAAAAAAAuqWW//35 244 | 9v/YajL/0GYw/8RgLf+3WSv/qFIo/5pLJP+ORSL/9d/T/7eik/9jSTX/AAAAAAAAAAAAAAAAAAAAAL6p 245 | mv/+/Pv//fn4//339P/89PD/+/Ht//ru6P/46uT/9+ff//bi2v+3opP/Y0k1/wAAAAAAAAAAAAAAAAAA 246 | AADDrp7//v7+/9hqMv/QZjD/xGAu/7dZK/+nUif/mUsl/45FIv/46N//t6KT/2NJNf8AAAAAAAAAAAAA 247 | AAAAAAAAyLKj//////////////38//37+f/9+fb//PXy//vy7v/77+r/+ezm/7eik/9jSTX/AAAAAAAA 248 | AAAAAAAAAAAAAMy2p///////2Goy/9BmMP/EYC3/t1kq/6hSKP/89vP/+/Tv/7eik/+3opP/ZEo2/wAA 249 | AAAAAAAAAAAAAAAAAADRu6v////////////////////////+/f/++/v//fn4/7eik/9kSjb/ZEo2/2RK 250 | Nv8AAAAAAAAAAAAAAAAAAAAA1b+v//////////////////////////////7+//78+/+5pJX/1MW6/2NJ 251 | Nf+ii3qpAAAAAAAAAAAAAAAAAAAAANjCsv////////////////////////////////////7/wKuc/2NJ 252 | Nf+ii3qoAAAAAAAAAAAAAAAAAAAAAAAAAADYwrL/2MKy/9jCsv/YwrL/2MKy/9jCsv/Uvq7/z7mp/8mz 253 | pP/Js6SLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 254 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAwAAwAMAAMADAADAAwAAwANp/8AD3v/AA/b/wAPz/8AD 255 | Mv/AAzH/wAMw/8ADL//AAy7/wAct/8APLP///yr/ 256 | 257 | 258 | -------------------------------------------------------------------------------- /ObjectListView/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace JesseJohnston.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("JesseJohnston.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Verdana;}{\f1{\colortbl ;\red255\green0\blue0;\red0\green0\blue255;\red0\green128\blue0;}\fswiss\fcharset0 Arial;}}. 65 | /// 66 | internal static string analysisColorFontHeader { 67 | get { 68 | return ResourceManager.GetString("analysisColorFontHeader", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to {\*\generator Msftedit 5.41.21.2506;}\viewkind4\uc1\pard\cf0\f0\fs20 If you're having trouble with ObjectListView, consider the following analysis of your list and list item types. The list is the object that you provided in the ObjectListView constructor. The list items are the objects contained in the list.\par\par. 74 | /// 75 | internal static string analysisHeaderText { 76 | get { 77 | return ResourceManager.GetString("analysisHeaderText", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support IEditableObject, which means that you cannot cancel changes made through a bound control such as the DataGridView.\par. 83 | /// 84 | internal static string analysisListItemNoIEditableObject { 85 | get { 86 | return ResourceManager.GetString("analysisListItemNoIEditableObject", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support INotifyPropertyChanged, but \cf3 does\cf0 supply one or more property change events. This means some or all changes to property values will be reflected in the view.\par. 92 | /// 93 | internal static string analysisListItemNoINotifyPropertyChanged { 94 | get { 95 | return ResourceManager.GetString("analysisListItemNoINotifyPropertyChanged", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support INotifyPropertyChanged or property change events, which means that changes to property values will not be refected in the view.\par. 101 | /// 102 | internal static string analysisListItemNoINotifyPropertyChangedNoPropertyChangedEvents { 103 | get { 104 | return ResourceManager.GetString("analysisListItemNoINotifyPropertyChangedNoPropertyChangedEvents", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to \cf3\b Your list item type \cf0\i {0}\cf3\i0 is optimal.\cf0\b0\par. 110 | /// 111 | internal static string analysisListItemOptimal { 112 | get { 113 | return ResourceManager.GetString("analysisListItemOptimal", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to \pard\cf1\b\f0\fs20 Your list item type \cf0\i {0}\cf1\i0 is sub-optimal.\cf0\b0\par. 119 | /// 120 | internal static string analysisListItemSubOptimal { 121 | get { 122 | return ResourceManager.GetString("analysisListItemSubOptimal", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support IEditableObject, which allows you to cancel changes made through a bound control such as the DataGridView.\par . 128 | /// 129 | internal static string analysisListItemSupportsIEditableObject { 130 | get { 131 | return ResourceManager.GetString("analysisListItemSupportsIEditableObject", resourceCulture); 132 | } 133 | } 134 | 135 | /// 136 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support INotifyPropertyChanged, which means that changes to property values will be refected in the view.\par . 137 | /// 138 | internal static string analysisListItemSupportsINotifyPropertyChanged { 139 | get { 140 | return ResourceManager.GetString("analysisListItemSupportsINotifyPropertyChanged", resourceCulture); 141 | } 142 | } 143 | 144 | /// 145 | /// Looks up a localized string similar to \pard\par\cf2\b List modifications:\cf0\b0\par . 146 | /// 147 | internal static string analysisListModifications { 148 | get { 149 | return ResourceManager.GetString("analysisListModifications", resourceCulture); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support IRaiseItemChangedEvents, which means that list item changes reported as PropertyChanged events will not be reflected in the view.\par . 155 | /// 156 | internal static string analysisListNoIRaiseItemChangedEvents { 157 | get { 158 | return ResourceManager.GetString("analysisListNoIRaiseItemChangedEvents", resourceCulture); 159 | } 160 | } 161 | 162 | /// 163 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It does \cf1 not\cf0 support the ListChanged event, which means that added and deleted items will not be reflected in the view.\par . 164 | /// 165 | internal static string analysisListNoListChanged { 166 | get { 167 | return ResourceManager.GetString("analysisListNoListChanged", resourceCulture); 168 | } 169 | } 170 | 171 | /// 172 | /// Looks up a localized string similar to The list makes no claims to thread safety.\par . 173 | /// 174 | internal static string analysisListNotSynced { 175 | get { 176 | return ResourceManager.GetString("analysisListNotSynced", resourceCulture); 177 | } 178 | } 179 | 180 | /// 181 | /// Looks up a localized string similar to \pard\par\cf3\b Your list type \cf0\i {0}\cf3\i0 is optimal.\cf0\b0\par. 182 | /// 183 | internal static string analysisListOptimal { 184 | get { 185 | return ResourceManager.GetString("analysisListOptimal", resourceCulture); 186 | } 187 | } 188 | 189 | /// 190 | /// Looks up a localized string similar to The list is read-only, which means that you cannot add, change, or delete list items through the view or a bound control.\par . 191 | /// 192 | internal static string analysisListReadOnly { 193 | get { 194 | return ResourceManager.GetString("analysisListReadOnly", resourceCulture); 195 | } 196 | } 197 | 198 | /// 199 | /// Looks up a localized string similar to \pard\par\cf1\b Your list type \cf0\i {0}\cf1\i0 is sub-optimal.\cf0\b0\par. 200 | /// 201 | internal static string analysisListSubOptimal { 202 | get { 203 | return ResourceManager.GetString("analysisListSubOptimal", resourceCulture); 204 | } 205 | } 206 | 207 | /// 208 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support IRaiseItemChangedEvents, which means that list item changes reported as PropertyChanged events will be reflected in the view.\par. 209 | /// 210 | internal static string analysisListSupportsIRaiseItemChangedEvents { 211 | get { 212 | return ResourceManager.GetString("analysisListSupportsIRaiseItemChangedEvents", resourceCulture); 213 | } 214 | } 215 | 216 | /// 217 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 It \cf3 does\cf0 support the ListChanged event, which means that added and deleted items will be reflected in the view.\par. 218 | /// 219 | internal static string analysisListSupportsListChanged { 220 | get { 221 | return ResourceManager.GetString("analysisListSupportsListChanged", resourceCulture); 222 | } 223 | } 224 | 225 | /// 226 | /// Looks up a localized string similar to The list claims to be thread-safe, and offers a SyncRoot object for lock operations.\par . 227 | /// 228 | internal static string analysisListSynced { 229 | get { 230 | return ResourceManager.GetString("analysisListSynced", resourceCulture); 231 | } 232 | } 233 | 234 | /// 235 | /// Looks up a localized string similar to \pard\par\cf2\b List thread safety:\cf0\b0\par . 236 | /// 237 | internal static string analysisListThreadSafety { 238 | get { 239 | return ResourceManager.GetString("analysisListThreadSafety", resourceCulture); 240 | } 241 | } 242 | 243 | /// 244 | /// Looks up a localized string similar to The list is writable but is fixed in size, which means that you can change or replace list items through the view or a bound control, but cannot add or remove items.\par . 245 | /// 246 | internal static string analysisListWritableFixedSize { 247 | get { 248 | return ResourceManager.GetString("analysisListWritableFixedSize", resourceCulture); 249 | } 250 | } 251 | 252 | /// 253 | /// Looks up a localized string similar to The list is writable and can change in size, which allows you to add, change, and remove list items through the view or a bound control.\par . 254 | /// 255 | internal static string analysisListWritableVariableSize { 256 | get { 257 | return ResourceManager.GetString("analysisListWritableVariableSize", resourceCulture); 258 | } 259 | } 260 | 261 | /// 262 | /// Looks up a localized string similar to \pard\par\cf2\b Recommendations:\cf0\b0\par . 263 | /// 264 | internal static string analysisRecommendations { 265 | get { 266 | return ResourceManager.GetString("analysisRecommendations", resourceCulture); 267 | } 268 | } 269 | 270 | /// 271 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360\f1 A recommended list type is BindingList<T>, where T is your list item type. BindingList<T> implements both IBindingList and IRaiseItemChangedEvents.\par. 272 | /// 273 | internal static string analysisRecommendationsBindingListT { 274 | get { 275 | return ResourceManager.GetString("analysisRecommendationsBindingListT", resourceCulture); 276 | } 277 | } 278 | 279 | /// 280 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IEditableObject for your list item type (\cf2 optional\cf0 ).\par. 281 | /// 282 | internal static string analysisRecommendationsIEditableObject { 283 | get { 284 | return ResourceManager.GetString("analysisRecommendationsIEditableObject", resourceCulture); 285 | } 286 | } 287 | 288 | /// 289 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement INotifyPropertyChanged for your list item type (\cf1 important\cf0 ).\par. 290 | /// 291 | internal static string analysisRecommendationsINotifyPropertyChanged { 292 | get { 293 | return ResourceManager.GetString("analysisRecommendationsINotifyPropertyChanged", resourceCulture); 294 | } 295 | } 296 | 297 | /// 298 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IRaiseItemChangedEvents for your list type (\cf1 important\cf0 ).\par. 299 | /// 300 | internal static string analysisRecommendationsIRaiseItemChangedEvents { 301 | get { 302 | return ResourceManager.GetString("analysisRecommendationsIRaiseItemChangedEvents", resourceCulture); 303 | } 304 | } 305 | 306 | /// 307 | /// Looks up a localized string similar to \pard{\pntext\f2\'B7\tab}{\*\pn\pnlvlblt\pnf2\pnindent0{\pntxtb\'B7}}\fi-360\li360 Implement IBindingList or provide a ListChanged event for your list type (\cf1 important\cf0 ).\par. 308 | /// 309 | internal static string analysisRecommendationsListChanged { 310 | get { 311 | return ResourceManager.GetString("analysisRecommendationsListChanged", resourceCulture); 312 | } 313 | } 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /ObjectListView/FilterNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | 6 | namespace JesseJohnston 7 | { 8 | /// 9 | /// A node in the filter expression tree. A node may be a terminal expression (i.e. property name, value, and relational operator) 10 | /// or a sub-tree containing a logical operator, left and right terms. 11 | /// 12 | internal class FilterNode : IEnumerable 13 | { 14 | #region Types 15 | private class FilterNodeEnumerator : IEnumerator 16 | { 17 | private FilterNode tree; 18 | private FilterNode current; 19 | private Stack nodes = new Stack(); 20 | 21 | public FilterNodeEnumerator(FilterNode tree) 22 | { 23 | this.tree = tree; 24 | } 25 | 26 | #region IEnumerator Members 27 | public FilterNode Current 28 | { 29 | get 30 | { 31 | if (this.current == null) 32 | throw new InvalidOperationException("Current"); 33 | else 34 | return this.current; 35 | } 36 | } 37 | #endregion 38 | 39 | #region IDisposable Members 40 | public void Dispose() 41 | { 42 | } 43 | #endregion 44 | 45 | #region IEnumerator Members 46 | object IEnumerator.Current 47 | { 48 | get { return ((IEnumerator)this).Current; } 49 | } 50 | public bool MoveNext() 51 | { 52 | // Initially, current is null, so we traverse the left edge. 53 | if (this.current == null) 54 | { 55 | this.current = this.tree; 56 | 57 | if (this.current.left == null && this.current.right == null) 58 | return true; 59 | 60 | // don't return it; we want to go down the left side first. 61 | } 62 | else if (this.current.right != null) 63 | { 64 | this.current = this.current.right; 65 | 66 | if (this.current.left == null && this.current.right == null) 67 | return true; 68 | 69 | // don't return it; we want to go down the left side first. 70 | } 71 | 72 | if (this.current.left != null) 73 | { 74 | while (this.current.left != null) 75 | { 76 | this.nodes.Push(this.current); 77 | this.current = this.current.left; 78 | } 79 | 80 | return true; 81 | } 82 | else if (this.nodes.Count > 0) 83 | { 84 | this.current = this.nodes.Pop(); 85 | return true; 86 | } 87 | else 88 | return false; 89 | } 90 | public void Reset() 91 | { 92 | this.current = null; 93 | this.nodes.Clear(); 94 | } 95 | #endregion 96 | } 97 | private enum TokenType 98 | { 99 | Term, 100 | Relation, 101 | Condition, 102 | OpenParen, 103 | CloseParen, 104 | ResolvedExpression, 105 | ResolvedNode 106 | } 107 | private class Token 108 | { 109 | private string term; 110 | private LogicalOperator logOp; 111 | private RelationalOperator relOp; 112 | private RelationalExpression expr; 113 | private FilterNode node; 114 | private TokenType type; 115 | 116 | public LogicalOperator Condition 117 | { 118 | get 119 | { 120 | if (type != TokenType.Condition) 121 | throw new StrongTypingException("Token is not a condition."); 122 | return logOp; 123 | } 124 | } 125 | public RelationalOperator Relation 126 | { 127 | get 128 | { 129 | if (this.type != TokenType.Relation) 130 | throw new StrongTypingException("Token is not a relation."); 131 | return relOp; 132 | } 133 | } 134 | public RelationalExpression ResolvedExpression 135 | { 136 | get 137 | { 138 | if (this.type != TokenType.ResolvedExpression) 139 | throw new StrongTypingException("Token is not a resolved expression."); 140 | return this.expr; 141 | } 142 | } 143 | public FilterNode ResolvedNode 144 | { 145 | get 146 | { 147 | if (this.type != TokenType.ResolvedNode) 148 | throw new StrongTypingException("Token is not a resolved node."); 149 | return node; 150 | } 151 | } 152 | public string Term 153 | { 154 | get 155 | { 156 | if (this.type != TokenType.Term) 157 | throw new StrongTypingException("Token is not a term."); 158 | return term; 159 | } 160 | } 161 | public TokenType Type 162 | { 163 | get { return type; } 164 | } 165 | 166 | public Token(string term) 167 | { 168 | if (term == "(") 169 | this.type = TokenType.OpenParen; 170 | else if (term == ")") 171 | this.type = TokenType.CloseParen; 172 | else 173 | { 174 | this.type = TokenType.Term; 175 | this.term = term; 176 | } 177 | } 178 | public Token(LogicalOperator condition) 179 | { 180 | this.type = TokenType.Condition; 181 | this.logOp = condition; 182 | } 183 | public Token(RelationalOperator relation) 184 | { 185 | this.type = TokenType.Relation; 186 | this.relOp = relation; 187 | } 188 | public Token(RelationalExpression expression) 189 | { 190 | this.type = TokenType.ResolvedExpression; 191 | this.expr = expression; 192 | } 193 | public Token(FilterNode node) 194 | { 195 | this.type = TokenType.ResolvedNode; 196 | this.node = node; 197 | } 198 | } 199 | private class Tokenizer : IEnumerable 200 | { 201 | private List tokens = new List(); 202 | private static Dictionary logicalOps = new Dictionary(); 203 | private static Dictionary relationalOps = new Dictionary(); 204 | private static List multiCharRelationalOps = new List(); 205 | 206 | static Tokenizer() 207 | { 208 | logicalOps.Add("And", LogicalOperator.And); 209 | logicalOps.Add("Or", LogicalOperator.Or); 210 | 211 | relationalOps.Add("=", RelationalOperator.Equal); 212 | relationalOps.Add("==", RelationalOperator.Equal); 213 | relationalOps.Add("!=", RelationalOperator.NotEqual); 214 | relationalOps.Add("<>", RelationalOperator.NotEqual); 215 | relationalOps.Add("<", RelationalOperator.Less); 216 | relationalOps.Add("<=", RelationalOperator.LessEqual); 217 | relationalOps.Add(">", RelationalOperator.Greater); 218 | relationalOps.Add(">=", RelationalOperator.GreaterEqual); 219 | 220 | foreach (string op in relationalOps.Keys) 221 | { 222 | if (op.Length > 1) 223 | multiCharRelationalOps.Add(op); 224 | } 225 | } 226 | 227 | public Tokenizer(string expression) 228 | { 229 | if (expression == null) 230 | throw new ArgumentNullException("expression"); 231 | if (expression == "") 232 | throw new ArgumentException("expression"); 233 | 234 | // Split into tokens delimited by spaces, relational operators, and parentheses. Remove extra spaces. 235 | ICollection parts = ExtractTokens(expression, 236 | new char[] { ' ', '<', '>', '=', '!', '(', ')' }, 237 | new char[] { '<', '>', '=', '!', '(', ')' }, 238 | new char[] { '\'', '"' }); 239 | 240 | if (parts.Count == 0) 241 | throw new ArgumentException("expression"); 242 | 243 | // Parse into tokens that are either operators, terms or a paren. 244 | Token prevToken = null; 245 | int parenCount = 0; 246 | 247 | foreach (string part in parts) 248 | { 249 | Token t = null; 250 | 251 | // Because a condition could also be the rvalue of a relation (e.g. State = OR), evaluate as a condition 252 | // only if it does not follow a relational operator. 253 | if (prevToken == null || prevToken.Type != TokenType.Relation) 254 | { 255 | foreach (KeyValuePair pair in logicalOps) 256 | { 257 | if (string.Compare(part, pair.Key, true) == 0) 258 | { 259 | if (prevToken == null || (prevToken.Type != TokenType.Term && prevToken.Type != TokenType.CloseParen)) 260 | throw new ArgumentException("An operator must be preceded by an expression term or closing paren.", "expression"); 261 | t = new Token(pair.Value); 262 | break; 263 | } 264 | } 265 | } 266 | 267 | if (t == null) 268 | { 269 | foreach (KeyValuePair pair in relationalOps) 270 | { 271 | if (string.Compare(part, pair.Key, true) == 0) 272 | { 273 | if (prevToken == null || prevToken.Type != TokenType.Term) 274 | throw new ArgumentException("An operator must be preceded by an expression term.", "expression"); 275 | t = new Token(pair.Value); 276 | break; 277 | } 278 | } 279 | } 280 | 281 | if (t == null) 282 | { 283 | if (part == "(") 284 | { 285 | if (prevToken != null && prevToken.Type != TokenType.Condition && prevToken.Type != TokenType.Relation && prevToken.Type != TokenType.OpenParen) 286 | throw new ArgumentException("An opening paren must be preceded by an operator or an opening paren.", "expression"); 287 | parenCount++; 288 | } 289 | else if (part == ")") 290 | { 291 | if (prevToken == null || (prevToken.Type != TokenType.Term && prevToken.Type != TokenType.CloseParen)) 292 | throw new ArgumentException("A closing paren must be preceded by an expression term or a closing paren.", "expression"); 293 | if (parenCount == 0) 294 | throw new ArgumentException("Unbalanced parentheses.", "expression"); 295 | parenCount--; 296 | } 297 | else 298 | { 299 | if (prevToken != null && prevToken.Type != TokenType.Condition && prevToken.Type != TokenType.Relation && prevToken.Type != TokenType.OpenParen) 300 | throw new ArgumentException("An expression term must be preceded by an operator or opening paren.", "expression"); 301 | } 302 | 303 | t = new Token(part); 304 | } 305 | 306 | tokens.Add(t); 307 | prevToken = t; 308 | } 309 | 310 | // The expression must end with a term or a closing paren. 311 | Token last = tokens[tokens.Count - 1]; 312 | if (last.Type != TokenType.Term && last.Type != TokenType.CloseParen) 313 | throw new ArgumentException("An expression must end in an expression term or a closing paren.", "expression"); 314 | 315 | // The expression must contain at least two terms and a relation. 316 | int terms = 0; 317 | int relations = 0; 318 | foreach (Token t in tokens) 319 | { 320 | if (t.Type == TokenType.Term) 321 | terms++; 322 | else if (t.Type == TokenType.Relation) 323 | relations++; 324 | } 325 | 326 | if (terms < 2 || relations == 0) 327 | throw new ArgumentException("An expression must contain at least two terms and a relational operator.", "expression"); 328 | } 329 | 330 | private ICollection ExtractTokens(string expression, char[] delimiters, char[] delimitersIncludedAsTokens, char[] quotes) 331 | { 332 | List tokens = new List(); 333 | List delims = new List(delimiters); // delimiters 334 | List delimTokens = new List(delimitersIncludedAsTokens); // delimiters which are also tokens 335 | List quoteChars = new List(quotes); 336 | 337 | int tokenStart = 0; 338 | int tokenEnd = 0; 339 | bool inQuote = false; 340 | char prevQuote = ' '; 341 | 342 | // Remove leading and trailing whitespace. 343 | expression = expression.Trim(); 344 | 345 | for (int i = 0; i < expression.Length; i++) 346 | { 347 | char c = expression[i]; 348 | 349 | if (i == expression.Length - 1) // Remainder of string (not ending in a delimiter) 350 | { 351 | if (inQuote && c == prevQuote) 352 | tokens.Add(expression.Substring(tokenStart, i - tokenStart)); 353 | else if (!delims.Contains(c) || delimTokens.Contains(c)) 354 | tokens.Add(expression.Substring(tokenStart)); 355 | } 356 | else if (quoteChars.Contains(c)) // Quote found 357 | { 358 | if (inQuote) 359 | { 360 | if (c == prevQuote) 361 | { 362 | inQuote = false; 363 | 364 | tokenEnd = i; 365 | 366 | if (tokenEnd > tokenStart) // Non-empty? 367 | tokens.Add(expression.Substring(tokenStart, tokenEnd - tokenStart)); 368 | 369 | tokenStart = i + 1; // Start parsing the next token 370 | } 371 | } 372 | else 373 | { 374 | inQuote = true; 375 | prevQuote = c; 376 | tokenStart = i + 1; // Start parsing the next token 377 | } 378 | } 379 | else if (!inQuote && delims.Contains(c)) // Delimiter found 380 | { 381 | tokenEnd = i; 382 | 383 | if (tokenEnd > tokenStart) // Non-empty? 384 | tokens.Add(expression.Substring(tokenStart, tokenEnd - tokenStart)); 385 | 386 | if (delimTokens.Contains(c)) // If the delimiter is also a token, add it to the token list 387 | tokens.Add(new string(c, 1)); 388 | 389 | tokenStart = i + 1; // Start parsing the next token 390 | } 391 | } 392 | 393 | // Coalesce adjacent operators that form a multi-character operator (e.g. <>, !=, ==) 394 | string prevToken = ""; 395 | string[] tokenArray = tokens.ToArray(); 396 | int tokensRemoved = 0; 397 | for (int j = 0; j < tokenArray.Length ; j++) 398 | { 399 | string token = tokenArray[j]; 400 | string compoundToken = prevToken + token; 401 | if (multiCharRelationalOps.Contains(compoundToken)) 402 | { 403 | int newPosition = j - 1 - tokensRemoved; 404 | tokens.RemoveAt(newPosition); 405 | tokens.RemoveAt(newPosition); 406 | tokens.Insert(newPosition, compoundToken); 407 | tokensRemoved++; 408 | } 409 | 410 | prevToken = token; 411 | } 412 | 413 | return tokens; 414 | } 415 | 416 | #region IEnumerable Members 417 | public IEnumerator GetEnumerator() 418 | { 419 | return tokens.GetEnumerator(); 420 | } 421 | #endregion 422 | 423 | #region IEnumerable Members 424 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 425 | { 426 | return ((System.Collections.IEnumerable)tokens).GetEnumerator(); 427 | } 428 | #endregion 429 | } 430 | #endregion 431 | 432 | private LogicalOperator op; 433 | private RelationalExpression term; 434 | private FilterNode left; 435 | private FilterNode right; 436 | private bool? evaluated; 437 | 438 | public bool? Evaluated 439 | { 440 | get { return this.evaluated; } 441 | } 442 | public FilterNode Left 443 | { 444 | get { return this.left; } 445 | } 446 | public LogicalOperator Operator 447 | { 448 | get { return this.op; } 449 | } 450 | public FilterNode Right 451 | { 452 | get { return this.right; } 453 | } 454 | public RelationalExpression Term 455 | { 456 | get { return this.term; } 457 | } 458 | 459 | /// 460 | /// Initializes a new instance of the class that is a terminal node. 461 | /// 462 | /// 463 | /// A terminal node is a relational expression, and contains no child nodes. 464 | /// 465 | /// The expression term. 466 | public FilterNode(RelationalExpression term) 467 | { 468 | if (term == null) 469 | throw new ArgumentNullException("term"); 470 | this.term = term; 471 | } 472 | 473 | /// 474 | /// Initializes a new instance of the class that is not a terminal node. 475 | /// 476 | /// The left child node. 477 | /// The right node. 478 | /// The operator relating the child nodes. 479 | public FilterNode(FilterNode left, FilterNode right, LogicalOperator op) 480 | { 481 | if (left == null) 482 | throw new ArgumentNullException("left"); 483 | if (right == null) 484 | throw new ArgumentNullException("right"); 485 | if (op == LogicalOperator.None) 486 | throw new ArgumentException("op"); 487 | 488 | this.left = left; 489 | this.right = right; 490 | this.op = op; 491 | } 492 | 493 | /// 494 | /// Parses the specified text into a binary expression tree. 495 | /// 496 | /// The expression text to parse. 497 | /// 498 | public static FilterNode Parse(string expression) 499 | { 500 | List tokens = new List(new Tokenizer(expression)); 501 | 502 | // Combine terms and relational operators into expressions. 503 | while (true) 504 | { 505 | int evaluationIndex = -1; 506 | for (int i = 0; i < tokens.Count; i++) 507 | { 508 | if (tokens[i].Type == TokenType.Relation) 509 | { 510 | evaluationIndex = i; 511 | break; 512 | } 513 | } 514 | 515 | if (evaluationIndex > -1) 516 | { 517 | RelationalExpression expr = new RelationalExpression(tokens[evaluationIndex - 1].Term, 518 | tokens[evaluationIndex + 1].Term, 519 | tokens[evaluationIndex].Relation); 520 | tokens.RemoveAt(evaluationIndex - 1); 521 | tokens.RemoveAt(evaluationIndex - 1); 522 | tokens.RemoveAt(evaluationIndex - 1); 523 | 524 | tokens.Insert(evaluationIndex - 1, new Token(expr)); 525 | 526 | // Remove parentheses surrounding a resolved expression. 527 | if (evaluationIndex - 2 > -1 && tokens[evaluationIndex - 2].Type == TokenType.OpenParen && 528 | evaluationIndex < tokens.Count && tokens[evaluationIndex].Type == TokenType.CloseParen) 529 | { 530 | // New resolved expression is now at evaluationIndex - 1. 531 | tokens.RemoveAt(evaluationIndex - 2); 532 | // New resolved expression is now at evaluationIndex - 2. 533 | tokens.RemoveAt(evaluationIndex - 1); 534 | } 535 | } 536 | else 537 | break; 538 | } 539 | 540 | // If the token list contains only a single relational expression, we can return a simple filter node based on that. 541 | if (tokens.Count == 1 && tokens[0].Type == TokenType.ResolvedExpression) 542 | return new FilterNode(tokens[0].ResolvedExpression); 543 | 544 | // The token list now contains only RelationalExpressions, conditional operators (AND and OR) and parentheses. 545 | // Combine the expressions and operators into nodes, prioritizing binding according to the natural order of precedence 546 | // for boolean operators and parentheses. 547 | Dictionary operatorPriorities = new Dictionary(); 548 | operatorPriorities.Add(LogicalOperator.Or, 1); 549 | operatorPriorities.Add(LogicalOperator.And, 2); 550 | int parenAddedPriority = operatorPriorities.Count; 551 | 552 | while (true) 553 | { 554 | int contextPriority = 0; 555 | int evaluationPriorityMax = -1; 556 | int evaluationIndex = -1; 557 | 558 | for (int i = 0; i < tokens.Count; i++) 559 | { 560 | TokenType type = tokens[i].Type; 561 | 562 | if (type == TokenType.Condition) 563 | { 564 | int evaluationPriority = operatorPriorities[tokens[i].Condition] + contextPriority; 565 | if (evaluationPriority > evaluationPriorityMax) 566 | { 567 | evaluationIndex = i; 568 | evaluationPriorityMax = evaluationPriority; 569 | } 570 | } 571 | else if (type == TokenType.OpenParen) 572 | { 573 | contextPriority += parenAddedPriority; 574 | } 575 | else if (type == TokenType.CloseParen) 576 | { 577 | contextPriority -= parenAddedPriority; 578 | } 579 | } 580 | 581 | if (evaluationIndex > -1) 582 | { 583 | Token prevToken = tokens[evaluationIndex - 1]; 584 | Token nextToken = tokens[evaluationIndex + 1]; 585 | 586 | FilterNode nodeLeft = null; 587 | FilterNode nodeRight = null; 588 | 589 | // Tokens surrounding the AND or OR must now be either a relational expression or a resolved FilterNode. 590 | if (prevToken.Type == TokenType.ResolvedExpression) 591 | nodeLeft = new FilterNode(prevToken.ResolvedExpression); 592 | else 593 | nodeLeft = prevToken.ResolvedNode; 594 | if (nextToken.Type == TokenType.ResolvedExpression) 595 | nodeRight = new FilterNode(nextToken.ResolvedExpression); 596 | else 597 | nodeRight = nextToken.ResolvedNode; 598 | 599 | FilterNode node = new FilterNode(nodeLeft, nodeRight, tokens[evaluationIndex].Condition); 600 | 601 | tokens.RemoveAt(evaluationIndex - 1); 602 | tokens.RemoveAt(evaluationIndex - 1); 603 | tokens.RemoveAt(evaluationIndex - 1); 604 | 605 | tokens.Insert(evaluationIndex - 1, new Token(node)); 606 | 607 | // Remove parentheses surrounding a resolved node. 608 | if (evaluationIndex - 2 > -1 && tokens[evaluationIndex - 2].Type == TokenType.OpenParen && 609 | evaluationIndex < tokens.Count && tokens[evaluationIndex].Type == TokenType.CloseParen) 610 | { 611 | // New resolved node is now at evaluationIndex - 1. 612 | tokens.RemoveAt(evaluationIndex - 2); 613 | // New resolved node is now at evaluationIndex - 2. 614 | tokens.RemoveAt(evaluationIndex - 1); 615 | } 616 | } 617 | else 618 | break; 619 | } 620 | 621 | // The token list should now contain a single FilterNode. 622 | return tokens[0].ResolvedNode; 623 | } 624 | 625 | /// 626 | /// Evaluates the current node and it's child nodes. 627 | /// 628 | /// The delegate used to evaluate terminal nodes. 629 | /// True if the current node and it's children evaluate to true; false otherwise. 630 | public bool Evaluate(ExpressionEvaluator evaluator) 631 | { 632 | FilterNode current = this; 633 | Stack nodes = new Stack(); 634 | 635 | while (true) 636 | { 637 | // A terminal expression? 638 | if (current.op == LogicalOperator.None) 639 | { 640 | current.evaluated = evaluator(current); 641 | } 642 | else 643 | { 644 | if (!current.left.evaluated.HasValue) 645 | { 646 | nodes.Push(current); 647 | current = current.left; 648 | continue; 649 | } 650 | 651 | if (!current.right.evaluated.HasValue) 652 | { 653 | nodes.Push(current); 654 | current = current.right; 655 | continue; 656 | } 657 | 658 | if (current.op == LogicalOperator.And) 659 | current.evaluated = current.left.evaluated.Value && current.right.evaluated.Value; 660 | else 661 | current.evaluated = current.left.evaluated.Value || current.right.evaluated.Value; 662 | } 663 | 664 | if (nodes.Count > 0) 665 | current = nodes.Pop(); 666 | else 667 | return current.evaluated.Value; 668 | } 669 | } 670 | 671 | /// 672 | /// Resets the evaluation status for each node in the expression tree, so that it can be re-evaluated. 673 | /// 674 | public void Reset() 675 | { 676 | foreach (FilterNode node in this) 677 | { 678 | node.evaluated = null; 679 | } 680 | } 681 | 682 | #region IEnumerable Members 683 | public IEnumerator GetEnumerator() 684 | { 685 | return new FilterNodeEnumerator(this); 686 | } 687 | #endregion 688 | 689 | #region IEnumerable Members 690 | IEnumerator IEnumerable.GetEnumerator() 691 | { 692 | return ((IEnumerable)this).GetEnumerator(); 693 | } 694 | #endregion 695 | } 696 | 697 | internal delegate bool ExpressionEvaluator(FilterNode expression); 698 | } 699 | --------------------------------------------------------------------------------