├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.cake ├── build.ps1 ├── build.sh ├── src ├── .editoricon.png ├── .files │ └── AssemblyInfo.Version.cs ├── ListViewPrinter.NetCore │ └── ListViewPrinter.NetCore.csproj ├── ListViewPrinter │ ├── BrushForm.Designer.cs │ ├── BrushForm.cs │ ├── BrushForm.resx │ ├── BrushPen.DesignTime.cs │ ├── BrushPenData.cs │ ├── ListViewPrinter.cs │ ├── ListViewPrinter.csproj │ └── Properties │ │ └── AssemblyInfo.cs ├── ObjectListView.NetCore │ └── ObjectListView.NetCore.csproj ├── ObjectListView.sln ├── ObjectListView │ ├── CellEditing │ │ ├── CellEditKeyEngine.cs │ │ ├── CellEditors.cs │ │ └── EditorRegistry.cs │ ├── CustomDictionary.xml │ ├── DataListView.cs │ ├── DataTreeListView.cs │ ├── DragDrop │ │ ├── DragSource.cs │ │ ├── DropSink.cs │ │ └── OLVDataObject.cs │ ├── FastDataListView.cs │ ├── FastObjectListView.cs │ ├── Filtering │ │ ├── Cluster.cs │ │ ├── ClusteringStrategy.cs │ │ ├── ClustersFromGroupsStrategy.cs │ │ ├── DateTimeClusteringStrategy.cs │ │ ├── FilterMenuBuilder.cs │ │ ├── Filters.cs │ │ ├── FlagClusteringStrategy.cs │ │ ├── ICluster.cs │ │ ├── IClusteringStrategy.cs │ │ └── TextMatchFilter.cs │ ├── FullClassDiagram.cd │ ├── Implementation │ │ ├── Attributes.cs │ │ ├── Comparers.cs │ │ ├── DataSourceAdapter.cs │ │ ├── Delegates.cs │ │ ├── DragSource.cs │ │ ├── DropSink.cs │ │ ├── Enums.cs │ │ ├── Events.cs │ │ ├── GroupingParameters.cs │ │ ├── Groups.cs │ │ ├── Munger.cs │ │ ├── NativeMethods.cs │ │ ├── NullableDictionary.cs │ │ ├── OLVListItem.cs │ │ ├── OLVListSubItem.cs │ │ ├── OlvListViewHitTestInfo.cs │ │ ├── TreeDataSourceAdapter.cs │ │ ├── VirtualGroups.cs │ │ └── VirtualListDataSource.cs │ ├── OLVColumn.cs │ ├── ObjectListView.DesignTime.cs │ ├── ObjectListView.cs │ ├── ObjectListView.csproj │ ├── Package.nuspec │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Rendering │ │ ├── Adornments.cs │ │ ├── Decorations.cs │ │ ├── Overlays.cs │ │ ├── Renderers.cs │ │ ├── Styles.cs │ │ └── TreeRenderer.cs │ ├── Resources │ │ ├── clear-filter.png │ │ ├── coffee.jpg │ │ ├── filter-icons3.png │ │ ├── filter.png │ │ ├── sort-ascending.png │ │ └── sort-descending.png │ ├── SubControls │ │ ├── GlassPanelForm.cs │ │ ├── HeaderControl.cs │ │ ├── ToolStripCheckedListBox.cs │ │ └── ToolTipControl.cs │ ├── TreeListView.cs │ ├── Utilities │ │ ├── ColumnSelectionForm.Designer.cs │ │ ├── ColumnSelectionForm.cs │ │ ├── ColumnSelectionForm.resx │ │ ├── Generator.cs │ │ ├── OLVExporter.cs │ │ └── TypedObjectListView.cs │ └── VirtualObjectListView.cs ├── ObjectListViewDemo.NetCore │ └── ObjectListViewDemo.NetCore.csproj ├── ObjectListViewDemo │ ├── AnimatedDecoration.cs │ ├── AnimatedGifs │ │ ├── 3dlink1.gif │ │ ├── cd1.gif │ │ ├── circum.gif │ │ ├── cool3.gif │ │ ├── enter3.gif │ │ ├── envelope.gif │ │ ├── exclame.gif │ │ ├── eye2.gif │ │ ├── net2.gif │ │ └── new5.gif │ ├── BusinessCardOverlay.cs │ ├── BusinessCardRenderer.cs │ ├── ColumnSelectionForm.Designer.cs │ ├── ColumnSelectionForm.cs │ ├── ColumnSelectionForm.resx │ ├── Data │ │ ├── FamilyTree.xml │ │ └── Persons.xml │ ├── MainForm.Designer.cs │ ├── MainForm.cs │ ├── MainForm.resx │ ├── Models │ │ ├── MaritalStatus.cs │ │ ├── MyFileSystemInfo.cs │ │ └── Person.cs │ ├── MyFileSystemInfo.cs │ ├── OLVDemoCoordinator.cs │ ├── ObjectListViewDemo.csproj │ ├── OlvDemoTab.cs │ ├── Person.cs │ ├── Photos │ │ ├── ak.png │ │ ├── cp.png │ │ ├── cr.png │ │ ├── es.png │ │ ├── gab.png │ │ ├── gp.png │ │ ├── jp.png │ │ ├── jr.png │ │ ├── mb.png │ │ ├── np.png │ │ ├── ns.png │ │ ├── sj.png │ │ └── sp.png │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Resource1.Designer.cs │ ├── Resource1.resx │ ├── Resources │ │ ├── Espresso Maker.ico │ │ ├── coffee.jpg │ │ ├── down16.png │ │ ├── fav32.png │ │ ├── folder16.png │ │ ├── goldstar3.png │ │ ├── goldstart-32.png │ │ ├── limeleaf.png │ │ ├── movie16.png │ │ ├── music16.png │ │ ├── redback1.png │ │ ├── redbull.png │ │ ├── star16.png │ │ └── tick16.png │ ├── ShellUtilities.cs │ ├── TabComplexExample.Designer.cs │ ├── TabComplexExample.cs │ ├── TabComplexExample.resx │ ├── TabDataSet.Designer.cs │ ├── TabDataSet.cs │ ├── TabDataSet.resx │ ├── TabDataTreeListView.Designer.cs │ ├── TabDataTreeListView.cs │ ├── TabDataTreeListView.resx │ ├── TabDescribedTask.Designer.cs │ ├── TabDescribedTask.cs │ ├── TabDescribedTask.resx │ ├── TabDragAndDrop.Designer.cs │ ├── TabDragAndDrop.cs │ ├── TabDragAndDrop.resx │ ├── TabFastList.Designer.cs │ ├── TabFastList.cs │ ├── TabFastList.resx │ ├── TabFileExplorer.Designer.cs │ ├── TabFileExplorer.cs │ ├── TabFileExplorer.resx │ ├── TabPrinting.Designer.cs │ ├── TabPrinting.cs │ ├── TabPrinting.resx │ ├── TabSimpleExample.Designer.cs │ ├── TabSimpleExample.cs │ ├── TabSimpleExample.resx │ ├── TabTreeListView.Designer.cs │ ├── TabTreeListView.cs │ └── TabTreeListView.resx ├── SparkleLibrary.NetCore │ └── SparkleLibrary.NetCore.csproj └── SparkleLibrary │ ├── Adapters │ └── AnimationAdapter.cs │ ├── Animation │ ├── Animateable.cs │ ├── Animation.cs │ └── Events.cs │ ├── Effects │ ├── Effect.cs │ └── Effects.cs │ ├── Locators │ ├── Locators.cs │ ├── PointLocator.cs │ └── RectangleLocator.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── SparkleLibrary.csproj │ └── Sprites │ ├── Audio.cs │ ├── ISprite.cs │ ├── ImageSprite.cs │ ├── ShapeSprite.cs │ ├── Sprite.cs │ └── TextSprite.cs └── tools └── packages.config /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set the merge driver for project and solution files 8 | # 9 | # Merging from the command prompt will add diff markers to the files if there 10 | # are conflicts (Merging from VS is not affected by the settings below, in VS 11 | # the diff markers are never inserted). Diff markers may cause the following 12 | # file extensions to fail to load in VS. An alternative would be to treat 13 | # these files as binary and thus will always conflict and require user 14 | # intervention with every merge. To do so, just comment the entries below and 15 | # uncomment the group further below 16 | ############################################################################### 17 | 18 | *.sln text eol=crlf 19 | *.csproj text eol=crlf 20 | *.vbproj text eol=crlf 21 | *.vcxproj text eol=crlf 22 | *.vcproj text eol=crlf 23 | *.dbproj text eol=crlf 24 | *.fsproj text eol=crlf 25 | *.lsproj text eol=crlf 26 | *.wixproj text eol=crlf 27 | *.modelproj text eol=crlf 28 | *.sqlproj text eol=crlf 29 | *.wmaproj text eol=crlf 30 | 31 | *.xproj text eol=crlf 32 | *.props text eol=crlf 33 | *.filters text eol=crlf 34 | *.vcxitems text eol=crlf 35 | 36 | *.sql text eol=crlf 37 | 38 | *.ai merge=binary 39 | *.psd merge=binary 40 | *.sketch merge=binary 41 | 42 | #*.sln merge=binary 43 | #*.csproj merge=binary 44 | #*.vbproj merge=binary 45 | #*.vcxproj merge=binary 46 | #*.vcproj merge=binary 47 | #*.dbproj merge=binary 48 | #*.fsproj merge=binary 49 | #*.lsproj merge=binary 50 | #*.wixproj merge=binary 51 | #*.modelproj merge=binary 52 | #*.sqlproj merge=binary 53 | #*.wwaproj merge=binary 54 | 55 | #*.xproj merge=binary 56 | #*.props merge=binary 57 | #*.filters merge=binary 58 | #*.vcxitems merge=binary 59 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [2.9.2] - [2020-05-25] 8 | ### Added 9 | - .NET 4.0 Build 10 | - .NET Core Build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![logo](src/.editoricon.png) 2 | 3 | # ObjectListView 4 | 5 | .NET ListView on caffeine, guarana and steroids. 6 | 7 | ObjectListView is a C# wrapper around a .NET ListView. It makes the ListView much easier to use and teaches it some neat new tricks. 8 | 9 | Larry Wall, the author of Perl, once wrote that the three essential character flaws of any good programmer were sloth, impatience and hubris. Good programmers want to do the minimum amount of work (sloth). They want their programs to run quickly (impatience). They take inordinate pride in what they have written (hubris). 10 | 11 | ObjectListView encourages the vices of sloth and hubris, by allowing programmers to do far less work but still produce great looking results. 12 | 13 | --------------------------------------- 14 | 15 | [![Build status](https://ci.appveyor.com/api/projects/status/yr6ewes5he8jhadl?svg=true)](https://ci.appveyor.com/project/ennerperez/objectlistview) 16 | [![NuGet](http://img.shields.io/nuget/v/objectlistview.updated.svg)](https://www.nuget.org/packages/objectlistview.updated/) 17 | 18 | --------------------------------------- 19 | 20 | See the [changelog](CHANGELOG.md) for changes. 21 | 22 | ## Contents 23 | 24 | * [Usage](#usage) 25 | * [Implementing](#implementing) 26 | * [Contributing](#contributing) 27 | * [Documentation](#documentation) 28 | * [License](#license) 29 | 30 | ### Build 31 | 32 | Execute on PowerShell terminal the Cake Build command line. 33 | 34 | ```powershell 35 | .\build 36 | ``` 37 | 38 | ### Implementing 39 | 40 | No more implementation instructions for now. 41 | 42 | ### Usage 43 | 44 | No more implementation instructions for now. 45 | 46 | ### Contributing 47 | 48 | No more contributing information for now. 49 | 50 | ### Documentation 51 | 52 | No more documentation required for now. 53 | 54 | ### License 55 | 56 | Code released under [GNU GENERAL PUBLIC LICENSE](LICENSE) 57 | -------------------------------------------------------------------------------- /build.cake: -------------------------------------------------------------------------------- 1 | #tool nuget:?package=NUnit.ConsoleRunner&version=3.4.0 2 | ////////////////////////////////////////////////////////////////////// 3 | // ARGUMENTS 4 | ////////////////////////////////////////////////////////////////////// 5 | 6 | var target = Argument("target", "Default"); 7 | var configuration = Argument("configuration", "Release"); 8 | 9 | ////////////////////////////////////////////////////////////////////// 10 | // PREPARATION 11 | ////////////////////////////////////////////////////////////////////// 12 | 13 | // Define solutions. 14 | var solutions = new Dictionary { 15 | { "./src/ObjectListView.sln", "Any" }, 16 | }; 17 | 18 | // Define directories. 19 | var buildDir = Directory("./build") + Directory(configuration); 20 | 21 | // Define AssemblyInfo source. 22 | var assemblyInfoVersion = ParseAssemblyInfo("./src/.files/AssemblyInfo.Version.cs"); 23 | 24 | // Define version. 25 | var ticks = DateTime.Now.ToString("ddHHmmss"); 26 | var assemblyVersion = assemblyInfoVersion.AssemblyVersion.Replace(".*", "." + ticks.Substring(ticks.Length-8,8)); 27 | var version = EnvironmentVariable("APPVEYOR_BUILD_VERSION") ?? Argument("version", assemblyVersion); 28 | 29 | ////////////////////////////////////////////////////////////////////// 30 | // TASKS 31 | ////////////////////////////////////////////////////////////////////// 32 | 33 | Task("Clean") 34 | .Does(() => 35 | { 36 | CleanDirectory(buildDir); 37 | CleanDirectories("./**/bin"); 38 | CleanDirectories("./**/obj"); 39 | }); 40 | 41 | Task("Restore-NuGet-Packages") 42 | .IsDependentOn("Clean") 43 | .Does(() => 44 | { 45 | foreach (var solution in solutions) 46 | { 47 | NuGetRestore(solution.Key); 48 | } 49 | }); 50 | 51 | Task("Build") 52 | .IsDependentOn("Restore-NuGet-Packages") 53 | .Does(() => 54 | { 55 | foreach (var solution in solutions) 56 | { 57 | var settings = new MSBuildSettings(); 58 | settings.SetConfiguration(configuration); 59 | MSBuild(solution.Key, settings); 60 | } 61 | }); 62 | 63 | Task("Build-NuGet-Packages") 64 | .Does(() => 65 | { 66 | foreach (var folder in new System.IO.FileInfo(solutions.ElementAt(0).Key).Directory.GetDirectories()) 67 | { 68 | foreach (var file in folder.GetFiles("*.nuspec")) 69 | { 70 | var path = file.Directory; 71 | var assemblyInfo = ParseAssemblyInfo(path + "/Properties/AssemblyInfo.cs"); 72 | var nuGetPackSettings = new NuGetPackSettings() 73 | { 74 | OutputDirectory = buildDir, 75 | IncludeReferencedProjects = false, 76 | //Id = assemblyInfo.Title.Replace(" ", "."), 77 | //Title = assemblyInfo.Title, 78 | Version = version, 79 | //Authors = new[] { assemblyInfoCommon.Company }, 80 | //Summary = assemblyInfo.Description, 81 | //Copyright = assemblyInfoCommon.Copyright, 82 | Properties = new Dictionary() 83 | {{ "Configuration", configuration }} 84 | }; 85 | NuGetPack(file.FullName, nuGetPackSettings); 86 | } 87 | } 88 | }); 89 | 90 | Task("Run-Unit-Tests") 91 | .IsDependentOn("Build") 92 | .Does(() => 93 | { 94 | NUnit3("./src/**/bin/" + configuration + "/*.Tests.dll", new NUnit3Settings { 95 | NoResults = true 96 | }); 97 | }); 98 | 99 | ////////////////////////////////////////////////////////////////////// 100 | // TASK TARGETS 101 | ////////////////////////////////////////////////////////////////////// 102 | 103 | Task("Default") 104 | .IsDependentOn("Run-Unit-Tests") 105 | .IsDependentOn("Build-NuGet-Packages"); 106 | 107 | ////////////////////////////////////////////////////////////////////// 108 | // EXECUTION 109 | ////////////////////////////////////////////////////////////////////// 110 | 111 | RunTarget(target); 112 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ########################################################################## 4 | # This is the Cake bootstrapper script for Linux and OS X. 5 | # This file was downloaded from https://github.com/cake-build/resources 6 | # Feel free to change this file to fit your needs. 7 | ########################################################################## 8 | 9 | # Define directories. 10 | SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 11 | TOOLS_DIR=$SCRIPT_DIR/tools 12 | NUGET_EXE=$TOOLS_DIR/nuget.exe 13 | CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe 14 | PACKAGES_CONFIG=$TOOLS_DIR/packages.config 15 | PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum 16 | 17 | # Define md5sum or md5 depending on Linux/OSX 18 | MD5_EXE= 19 | if [[ "$(uname -s)" == "Darwin" ]]; then 20 | MD5_EXE="md5 -r" 21 | else 22 | MD5_EXE="md5sum" 23 | fi 24 | 25 | # Define default arguments. 26 | SCRIPT="build.cake" 27 | TARGET="Default" 28 | CONFIGURATION="Release" 29 | VERBOSITY="verbose" 30 | DRYRUN= 31 | SHOW_VERSION=false 32 | SCRIPT_ARGUMENTS=() 33 | 34 | # Parse arguments. 35 | for i in "$@"; do 36 | case $1 in 37 | -s|--script) SCRIPT="$2"; shift ;; 38 | -t|--target) TARGET="$2"; shift ;; 39 | -c|--configuration) CONFIGURATION="$2"; shift ;; 40 | -v|--verbosity) VERBOSITY="$2"; shift ;; 41 | -d|--dryrun) DRYRUN="-dryrun" ;; 42 | --version) SHOW_VERSION=true ;; 43 | --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; 44 | *) SCRIPT_ARGUMENTS+=("$1") ;; 45 | esac 46 | shift 47 | done 48 | 49 | # Make sure the tools folder exist. 50 | if [ ! -d "$TOOLS_DIR" ]; then 51 | mkdir "$TOOLS_DIR" 52 | fi 53 | 54 | # Make sure that packages.config exist. 55 | if [ ! -f "$TOOLS_DIR/packages.config" ]; then 56 | echo "Downloading packages.config..." 57 | curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages 58 | if [ $? -ne 0 ]; then 59 | echo "An error occurred while downloading packages.config." 60 | exit 1 61 | fi 62 | fi 63 | 64 | # Download NuGet if it does not exist. 65 | if [ ! -f "$NUGET_EXE" ]; then 66 | echo "Downloading NuGet..." 67 | curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe 68 | if [ $? -ne 0 ]; then 69 | echo "An error occurred while downloading nuget.exe." 70 | exit 1 71 | fi 72 | fi 73 | 74 | # Restore tools from NuGet. 75 | pushd "$TOOLS_DIR" >/dev/null 76 | if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then 77 | find . -type d ! -name . | xargs rm -rf 78 | fi 79 | 80 | mono "$NUGET_EXE" install -ExcludeVersion 81 | if [ $? -ne 0 ]; then 82 | echo "Could not restore NuGet packages." 83 | exit 1 84 | fi 85 | 86 | $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 87 | 88 | popd >/dev/null 89 | 90 | # Make sure that Cake has been installed. 91 | if [ ! -f "$CAKE_EXE" ]; then 92 | echo "Could not find Cake.exe at '$CAKE_EXE'." 93 | exit 1 94 | fi 95 | 96 | # Start Cake 97 | if $SHOW_VERSION; then 98 | exec mono "$CAKE_EXE" -version 99 | else 100 | exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" 101 | fi 102 | -------------------------------------------------------------------------------- /src/.editoricon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/.editoricon.png -------------------------------------------------------------------------------- /src/.files/AssemblyInfo.Version.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | // Version information for an assembly consists of the following four values: 4 | // 5 | // Major Version 6 | // Minor Version 7 | // Build Number 8 | // Revision 9 | // 10 | // You can specify all the values or you can default the Revision and Build Numbers 11 | // by using the '*' as shown below: 12 | [assembly: AssemblyVersion("2.9.3.*")] 13 | [assembly: AssemblyFileVersion("2.9.3")] 14 | [assembly: AssemblyInformationalVersion("2.9.3")] 15 | [assembly: System.CLSCompliant(true)] -------------------------------------------------------------------------------- /src/ListViewPrinter.NetCore/ListViewPrinter.NetCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.1 5 | false 6 | false 7 | BrightIdeasSoftware 8 | ListViewPrinter 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/ListViewPrinter/BrushForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Drawing; 5 | using System.Drawing.Drawing2D; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | 9 | //TODO: Allow alpha 10 | 11 | namespace BrightIdeasSoftware 12 | { 13 | internal partial class BrushForm : Form 14 | { 15 | public BrushForm() 16 | { 17 | InitializeComponent(); 18 | this.TopLevel = false; 19 | } 20 | 21 | public IBrushData GetBrushData() 22 | { 23 | return this.propertyGrid1.SelectedObject as IBrushData; 24 | } 25 | 26 | public Brush GetBrush() 27 | { 28 | IBrushData bd = this.GetBrushData(); 29 | if (bd == null) 30 | return null; 31 | else 32 | return bd.GetBrush(); 33 | } 34 | 35 | public void SetBrush(IBrushData value) 36 | { 37 | this.rbSolid.Tag = (value is SolidBrushData) ? value : new SolidBrushData(); 38 | this.rbHatch.Tag = (value is HatchBrushData) ? value : new HatchBrushData(); 39 | this.rbGradient.Tag = (value is LinearGradientBrushData) ? value : new LinearGradientBrushData(); 40 | this.TurnOnRadioButton(value); 41 | } 42 | 43 | protected void TurnOnRadioButton(IBrushData value) 44 | { 45 | RadioButton turnedOn = this.rbNone; 46 | if (value != null) { 47 | if (value.GetType() == typeof(SolidBrushData)) 48 | turnedOn = this.rbSolid; 49 | else if (value.GetType() == typeof(LinearGradientBrushData)) 50 | turnedOn = this.rbGradient; 51 | else if (value.GetType() == typeof(HatchBrushData)) 52 | turnedOn = this.rbHatch; 53 | } 54 | 55 | turnedOn.Checked = true; 56 | } 57 | 58 | protected void examplePanel_Paint(object sender, PaintEventArgs e) 59 | { 60 | using (BufferedGraphics buffered = BufferedGraphicsManager.Current.Allocate(e.Graphics, e.ClipRectangle)) { 61 | Graphics g = buffered.Graphics; 62 | g.Clear(((Panel)sender).BackColor); 63 | this.HandlePaintEvent(g, e.ClipRectangle); 64 | buffered.Render(); 65 | } 66 | } 67 | 68 | virtual protected void HandlePaintEvent(Graphics g, Rectangle r) 69 | { 70 | using (Brush b = this.GetBrush()) { 71 | StringFormat fmt = new StringFormat(); 72 | fmt.Alignment = StringAlignment.Center; 73 | fmt.LineAlignment = StringAlignment.Center; 74 | if (b == null) { 75 | g.DrawString("No brush", new Font("Tahoma", 14), Brushes.DarkGray, r, fmt); 76 | } else { 77 | g.DrawString("Through a mirror darkly", new Font("Tahoma", 14), Brushes.Black, r, fmt); 78 | g.FillRectangle(BlockFormat.PrepareBrushForDrawing(b, r), r); 79 | } 80 | } 81 | } 82 | 83 | private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) 84 | { 85 | this.examplePanel.Invalidate(); 86 | } 87 | 88 | private void propertyGrid1_SelectedObjectsChanged(object sender, EventArgs e) 89 | { 90 | this.examplePanel.Invalidate(); 91 | } 92 | 93 | private void rbCheckedChanged(object sender, EventArgs e) 94 | { 95 | this.propertyGrid1.SelectedObject = ((RadioButton)sender).Tag; 96 | } 97 | } 98 | 99 | internal class PenForm : BrushForm 100 | { 101 | public PenData GetPenData() 102 | { 103 | return this.propertyGrid1.SelectedObject as PenData; 104 | } 105 | 106 | public Pen GetPen() 107 | { 108 | PenData data = this.GetPenData(); 109 | if (data == null) 110 | return null; 111 | else 112 | return data.GetPen(); 113 | } 114 | 115 | public void SetPenData(PenData value) 116 | { 117 | IBrushData bd = (value == null) ? null : value.Brush; 118 | this.rbSolid.Tag = (bd is SolidBrushData) ? value : new PenData(new SolidBrushData()); 119 | this.rbGradient.Tag = (bd is LinearGradientBrushData) ? value : new PenData(new LinearGradientBrushData()); 120 | this.rbHatch.Tag = (bd is HatchBrushData) ? value : new PenData(new HatchBrushData()); 121 | this.TurnOnRadioButton(bd); 122 | } 123 | 124 | protected override void HandlePaintEvent(Graphics g, Rectangle r) 125 | { 126 | using (Pen p = this.GetPen()) { 127 | g.SmoothingMode = ObjectListView.SmoothingMode; 128 | StringFormat fmt = new StringFormat(); 129 | fmt.Alignment = StringAlignment.Center; 130 | fmt.LineAlignment = StringAlignment.Center; 131 | if (p == null) { 132 | g.DrawString("No pen", new Font("Tahoma", 14), Brushes.DarkGray, r, fmt); 133 | } else { 134 | g.DrawString("Through a mirror darkly", new Font("Tahoma", 14), Brushes.Black, r, fmt); 135 | int inset = (int)Math.Max(1.0, p.Width); 136 | r.Inflate(-inset, -inset); 137 | Point[] pts = new Point[4]; 138 | pts[0] = r.Location; 139 | pts[1] = new Point(r.X + r.Width / 2, r.Bottom); 140 | pts[2] = new Point(r.X + r.Width / 2, r.Top); 141 | pts[3] = new Point(r.Right, r.Bottom); 142 | g.DrawLines(BlockFormat.PreparePenForDrawing(p, r), pts); 143 | } 144 | } 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /src/ListViewPrinter/BrushForm.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 | -------------------------------------------------------------------------------- /src/ListViewPrinter/BrushPenData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.ComponentModel; 5 | using System.Drawing; 6 | using System.Drawing.Drawing2D; 7 | using System.Drawing.Design; 8 | 9 | namespace BrightIdeasSoftware 10 | { 11 | /// 12 | /// PenData represents the data required to create a pen. 13 | /// 14 | /// Pens cannot be edited directly within the IDE (is this VCS EE only?) 15 | /// These objects allow pen characters to be edited within the IDE and then real 16 | /// Pen objects created. 17 | [Editor(typeof(PenDataEditor), typeof(UITypeEditor)), 18 | TypeConverter(typeof(PenDataConverter))] 19 | public class PenData 20 | { 21 | public PenData() : this(new SolidBrushData()) 22 | { 23 | } 24 | 25 | public PenData(IBrushData brush) 26 | { 27 | this.Brush = brush; 28 | } 29 | 30 | public Pen GetPen() 31 | { 32 | Pen p = new Pen(this.Brush.GetBrush(), this.Width); 33 | p.SetLineCap(this.StartCap, this.EndCap, this.DashCap); 34 | p.DashStyle = this.DashStyle; 35 | p.LineJoin = this.LineJoin; 36 | return p; 37 | } 38 | 39 | [TypeConverter(typeof(ExpandableObjectConverter))] 40 | public IBrushData Brush 41 | { 42 | get { return brushData; } 43 | set { brushData = value; } 44 | } 45 | private IBrushData brushData; 46 | 47 | [DefaultValue(typeof(DashCap), "Round")] 48 | public DashCap DashCap 49 | { 50 | get { return dashCap; } 51 | set { dashCap = value; } 52 | } 53 | private DashCap dashCap = DashCap.Round; 54 | 55 | [DefaultValue(typeof(DashStyle), "Solid")] 56 | public DashStyle DashStyle 57 | { 58 | get { return dashStyle; } 59 | set { dashStyle = value; } 60 | } 61 | private DashStyle dashStyle = DashStyle.Solid; 62 | 63 | [DefaultValue(typeof(LineCap), "NoAnchor")] 64 | public LineCap EndCap 65 | { 66 | get { return endCap; } 67 | set { endCap = value; } 68 | } 69 | private LineCap endCap = LineCap.NoAnchor; 70 | 71 | [DefaultValue(typeof(LineJoin), "Round")] 72 | public LineJoin LineJoin 73 | { 74 | get { return lineJoin; } 75 | set { lineJoin = value; } 76 | } 77 | private LineJoin lineJoin = LineJoin.Round; 78 | 79 | [DefaultValue(typeof(LineCap), "NoAnchor")] 80 | public LineCap StartCap 81 | { 82 | get { return startCap; } 83 | set { startCap = value; } 84 | } 85 | private LineCap startCap = LineCap.NoAnchor; 86 | 87 | [DefaultValue(1.0f)] 88 | public float Width 89 | { 90 | get { return width; } 91 | set { width = value; } 92 | } 93 | private float width = 1.0f; 94 | } 95 | 96 | [Editor(typeof(BrushDataEditor), typeof(UITypeEditor)), 97 | TypeConverter(typeof(BrushDataConverter))] 98 | public interface IBrushData 99 | { 100 | Brush GetBrush(); 101 | } 102 | 103 | public class SolidBrushData : IBrushData 104 | { 105 | public Brush GetBrush() 106 | { 107 | if (this.Alpha < 255) 108 | return new SolidBrush(Color.FromArgb(this.Alpha, this.Color)); 109 | else 110 | return new SolidBrush(this.Color); 111 | } 112 | 113 | [DefaultValue(typeof(Color), "")] 114 | public Color Color 115 | { 116 | get { return color; } 117 | set { color = value; } 118 | } 119 | private Color color = Color.Empty; 120 | 121 | [DefaultValue(255)] 122 | public int Alpha 123 | { 124 | get { return alpha; } 125 | set { alpha = value; } 126 | } 127 | private int alpha = 255; 128 | } 129 | 130 | public class LinearGradientBrushData : IBrushData 131 | { 132 | public Brush GetBrush() 133 | { 134 | return new LinearGradientBrush(new Rectangle(0, 0, 100, 100), this.FromColor, this.ToColor, this.GradientMode); 135 | } 136 | 137 | public Color FromColor 138 | { 139 | get { return fromColor; } 140 | set { fromColor = value; } 141 | } 142 | private Color fromColor = Color.Aqua; 143 | 144 | public Color ToColor 145 | { 146 | get { return toColor; } 147 | set { toColor = value; } 148 | } 149 | private Color toColor = Color.Pink; 150 | 151 | public LinearGradientMode GradientMode 152 | { 153 | get { return gradientMode; } 154 | set { gradientMode = value; } 155 | } 156 | private LinearGradientMode gradientMode = LinearGradientMode.Horizontal; 157 | } 158 | 159 | public class HatchBrushData : IBrushData 160 | { 161 | public Brush GetBrush() 162 | { 163 | return new HatchBrush(this.HatchStyle, this.ForegroundColor, this.BackgroundColor); 164 | } 165 | 166 | public Color BackgroundColor 167 | { 168 | get { return backgroundColor; } 169 | set { backgroundColor = value; } 170 | } 171 | private Color backgroundColor = Color.AliceBlue; 172 | 173 | public Color ForegroundColor 174 | { 175 | get { return foregroundColor; } 176 | set { foregroundColor = value; } 177 | } 178 | private Color foregroundColor = Color.Aqua; 179 | 180 | public HatchStyle HatchStyle 181 | { 182 | get { return hatchStyle; } 183 | set { hatchStyle = value; } 184 | } 185 | private HatchStyle hatchStyle = HatchStyle.Cross; 186 | } 187 | 188 | public class TextureBrushData : IBrushData 189 | { 190 | public Brush GetBrush() 191 | { 192 | if (this.Image == null) 193 | return null; 194 | else 195 | return new TextureBrush(this.Image, this.WrapMode); 196 | } 197 | 198 | public Image Image 199 | { 200 | get { return image; } 201 | set { image = value; } 202 | } 203 | private Image image; 204 | 205 | public WrapMode WrapMode 206 | { 207 | get { return wrapMode; } 208 | set { wrapMode = value; } 209 | } 210 | private WrapMode wrapMode = WrapMode.Tile; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /src/ListViewPrinter/ListViewPrinter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6D9AD07B-0286-4082-BC30-7706FB6E601F} 8 | Library 9 | Properties 10 | BrightIdeasSoftware 11 | ListViewPrinter 12 | v4.0 13 | 512 14 | false 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Properties\AssemblyInfo.Version.cs 50 | 51 | 52 | Form 53 | 54 | 55 | BrushForm.cs 56 | 57 | 58 | 59 | 60 | Component 61 | 62 | 63 | 64 | 65 | 66 | BrushForm.cs 67 | 68 | 69 | 70 | 71 | {609d2cf5-049c-4708-809d-1c0b7bf57a5c} 72 | ObjectListView 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/ListViewPrinter/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("ListViewPrinter")] 9 | [assembly: AssemblyDescription("A class to take a ListView or ObjectListView and make it into a beatiful report")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Bright Ideas Software")] 12 | [assembly: AssemblyProduct("ListViewPrinter")] 13 | [assembly: AssemblyCopyright("Copyright © 2008-2020")] 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("213c7c43-b654-47cb-b817-fc602282c9df")] -------------------------------------------------------------------------------- /src/ObjectListView.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.30114.105 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F2848700-C8F6-419E-9D2A-FF3590CA7AFB}" 6 | ProjectSection(SolutionItems) = preProject 7 | ..\.gitattributes = ..\.gitattributes 8 | ..\.gitignore = ..\.gitignore 9 | ..\build.cake = ..\build.cake 10 | ..\build.ps1 = ..\build.ps1 11 | ..\build.sh = ..\build.sh 12 | ..\CHANGELOG.md = ..\CHANGELOG.md 13 | ..\LICENSE = ..\LICENSE 14 | ..\README.md = ..\README.md 15 | EndProjectSection 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectListView", "ObjectListView\ObjectListView.csproj", "{609D2CF5-049C-4708-809D-1C0B7BF57A5C}" 18 | EndProject 19 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectListView.NetCore", "ObjectListView.NetCore\ObjectListView.NetCore.csproj", "{4CD0B8CE-161D-4F19-9B62-8C77FA601986}" 20 | EndProject 21 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ObjectListViewDemo", "ObjectListViewDemo\ObjectListViewDemo.csproj", "{6C098288-075B-4083-9B53-6E94FFCD50C4}" 22 | EndProject 23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ObjectListViewDemo.NetCore", "ObjectListViewDemo.NetCore\ObjectListViewDemo.NetCore.csproj", "{B1A8F19D-D299-4C57-90BF-B001525C3152}" 24 | EndProject 25 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{DD4EAE51-6E46-4B5E-924A-E2C75037C4E5}" 26 | EndProject 27 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ListViewPrinter", "ListViewPrinter\ListViewPrinter.csproj", "{6D9AD07B-0286-4082-BC30-7706FB6E601F}" 28 | EndProject 29 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ListViewPrinter.NetCore", "ListViewPrinter.NetCore\ListViewPrinter.NetCore.csproj", "{564C996E-4AE7-4270-A04D-203273986A1B}" 30 | EndProject 31 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "References", "References", "{E3F00174-C029-4C5C-9554-5F57326B22FC}" 32 | EndProject 33 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleLibrary", "SparkleLibrary\SparkleLibrary.csproj", "{D304B8BF-0D7A-4CDD-A50B-7FCD9A437496}" 34 | EndProject 35 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SparkleLibrary.NetCore", "SparkleLibrary.NetCore\SparkleLibrary.NetCore.csproj", "{1486AF93-F02C-4B71-BBC9-C76654EBAE02}" 36 | EndProject 37 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".files", ".files", "{7EA29E9E-A450-41EF-8AE7-88058A3FD27E}" 38 | ProjectSection(SolutionItems) = preProject 39 | .files\AssemblyInfo.Version.cs = .files\AssemblyInfo.Version.cs 40 | EndProjectSection 41 | EndProject 42 | Global 43 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 44 | Debug|Any CPU = Debug|Any CPU 45 | Release|Any CPU = Release|Any CPU 46 | EndGlobalSection 47 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 48 | {609D2CF5-049C-4708-809D-1C0B7BF57A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {609D2CF5-049C-4708-809D-1C0B7BF57A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {609D2CF5-049C-4708-809D-1C0B7BF57A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {609D2CF5-049C-4708-809D-1C0B7BF57A5C}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {4CD0B8CE-161D-4F19-9B62-8C77FA601986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {4CD0B8CE-161D-4F19-9B62-8C77FA601986}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {4CD0B8CE-161D-4F19-9B62-8C77FA601986}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {4CD0B8CE-161D-4F19-9B62-8C77FA601986}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {6C098288-075B-4083-9B53-6E94FFCD50C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {6C098288-075B-4083-9B53-6E94FFCD50C4}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {6C098288-075B-4083-9B53-6E94FFCD50C4}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {B1A8F19D-D299-4C57-90BF-B001525C3152}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {B1A8F19D-D299-4C57-90BF-B001525C3152}.Debug|Any CPU.Build.0 = Debug|Any CPU 61 | {B1A8F19D-D299-4C57-90BF-B001525C3152}.Release|Any CPU.ActiveCfg = Release|Any CPU 62 | {6D9AD07B-0286-4082-BC30-7706FB6E601F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {6D9AD07B-0286-4082-BC30-7706FB6E601F}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {6D9AD07B-0286-4082-BC30-7706FB6E601F}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {564C996E-4AE7-4270-A04D-203273986A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 66 | {564C996E-4AE7-4270-A04D-203273986A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU 67 | {564C996E-4AE7-4270-A04D-203273986A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU 68 | {D304B8BF-0D7A-4CDD-A50B-7FCD9A437496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {D304B8BF-0D7A-4CDD-A50B-7FCD9A437496}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {D304B8BF-0D7A-4CDD-A50B-7FCD9A437496}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {1486AF93-F02C-4B71-BBC9-C76654EBAE02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 72 | {1486AF93-F02C-4B71-BBC9-C76654EBAE02}.Debug|Any CPU.Build.0 = Debug|Any CPU 73 | {1486AF93-F02C-4B71-BBC9-C76654EBAE02}.Release|Any CPU.ActiveCfg = Release|Any CPU 74 | EndGlobalSection 75 | GlobalSection(SolutionProperties) = preSolution 76 | HideSolutionNode = FALSE 77 | EndGlobalSection 78 | GlobalSection(NestedProjects) = preSolution 79 | {6C098288-075B-4083-9B53-6E94FFCD50C4} = {DD4EAE51-6E46-4B5E-924A-E2C75037C4E5} 80 | {B1A8F19D-D299-4C57-90BF-B001525C3152} = {DD4EAE51-6E46-4B5E-924A-E2C75037C4E5} 81 | {6D9AD07B-0286-4082-BC30-7706FB6E601F} = {DD4EAE51-6E46-4B5E-924A-E2C75037C4E5} 82 | {564C996E-4AE7-4270-A04D-203273986A1B} = {DD4EAE51-6E46-4B5E-924A-E2C75037C4E5} 83 | {D304B8BF-0D7A-4CDD-A50B-7FCD9A437496} = {E3F00174-C029-4C5C-9554-5F57326B22FC} 84 | {1486AF93-F02C-4B71-BBC9-C76654EBAE02} = {E3F00174-C029-4C5C-9554-5F57326B22FC} 85 | {7EA29E9E-A450-41EF-8AE7-88058A3FD27E} = {F2848700-C8F6-419E-9D2A-FF3590CA7AFB} 86 | EndGlobalSection 87 | GlobalSection(ExtensibilityGlobals) = postSolution 88 | SolutionGuid = {5562d2e8-7406-4238-98ae-140e65c62f1a} 89 | EndGlobalSection 90 | EndGlobal 91 | -------------------------------------------------------------------------------- /src/ObjectListView/CustomDictionary.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | br 6 | Canceled 7 | Center 8 | Color 9 | Colors 10 | f 11 | fmt 12 | g 13 | gdi 14 | hti 15 | i 16 | lightbox 17 | lv 18 | lvi 19 | lvsi 20 | m 21 | multi 22 | Munger 23 | n 24 | olv 25 | olvi 26 | p 27 | parms 28 | r 29 | Renderer 30 | s 31 | SubItem 32 | Unapply 33 | Unpause 34 | x 35 | y 36 | 37 | 38 | ComPlus 39 | 40 | 41 | 42 | 43 | OLV 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/ObjectListView/Filtering/Cluster.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Cluster - Implements a simple cluster 3 | * 4 | * Author: Phillip Piper 5 | * Date: 3-March-2011 10:53 pm 6 | * 7 | * Change log: 8 | * 2011-03-03 JPP - First version 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Text; 31 | 32 | namespace BrightIdeasSoftware { 33 | 34 | /// 35 | /// Concrete implementation of the ICluster interface. 36 | /// 37 | public class Cluster : ICluster { 38 | 39 | #region Life and death 40 | 41 | /// 42 | /// Create a cluster 43 | /// 44 | /// The key for the cluster 45 | public Cluster(object key) { 46 | this.Count = 1; 47 | this.ClusterKey = key; 48 | } 49 | 50 | #endregion 51 | 52 | #region Public overrides 53 | 54 | /// 55 | /// Return a string representation of this cluster 56 | /// 57 | /// 58 | public override string ToString() { 59 | return this.DisplayLabel ?? "[empty]"; 60 | } 61 | 62 | #endregion 63 | 64 | #region Implementation of ICluster 65 | 66 | /// 67 | /// Gets or sets how many items belong to this cluster 68 | /// 69 | public int Count { 70 | get { return count; } 71 | set { count = value; } 72 | } 73 | private int count; 74 | 75 | /// 76 | /// Gets or sets the label that will be shown to the user to represent 77 | /// this cluster 78 | /// 79 | public string DisplayLabel { 80 | get { return displayLabel; } 81 | set { displayLabel = value; } 82 | } 83 | private string displayLabel; 84 | 85 | /// 86 | /// Gets or sets the actual data object that all members of this cluster 87 | /// have commonly returned. 88 | /// 89 | public object ClusterKey { 90 | get { return clusterKey; } 91 | set { clusterKey = value; } 92 | } 93 | private object clusterKey; 94 | 95 | #endregion 96 | 97 | #region Implementation of IComparable 98 | 99 | /// 100 | /// Return an indication of the ordering between this object and the given one 101 | /// 102 | /// 103 | /// 104 | public int CompareTo(object other) { 105 | if (other == null || other == System.DBNull.Value) 106 | return 1; 107 | 108 | ICluster otherCluster = other as ICluster; 109 | if (otherCluster == null) 110 | return 1; 111 | 112 | string keyAsString = this.ClusterKey as string; 113 | if (keyAsString != null) 114 | return String.Compare(keyAsString, otherCluster.ClusterKey as string, StringComparison.CurrentCultureIgnoreCase); 115 | 116 | IComparable keyAsComparable = this.ClusterKey as IComparable; 117 | if (keyAsComparable != null) 118 | return keyAsComparable.CompareTo(otherCluster.ClusterKey); 119 | 120 | return -1; 121 | } 122 | 123 | #endregion 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/ObjectListView/Filtering/ClustersFromGroupsStrategy.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ClusteringStrategy - Implements a simple clustering strategy 3 | * 4 | * Author: Phillip Piper 5 | * Date: 1-April-2011 8:12am 6 | * 7 | * Change log: 8 | * 2011-04-01 JPP - First version 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Text; 31 | 32 | namespace BrightIdeasSoftware { 33 | 34 | /// 35 | /// This class calculates clusters from the groups that the column uses. 36 | /// 37 | /// 38 | /// 39 | /// This is the default strategy for all non-date, filterable columns. 40 | /// 41 | /// 42 | /// This class does not strictly mimic the groups created by the given column. 43 | /// In particular, if the programmer changes the default grouping technique 44 | /// by listening for grouping events, this class will not mimic that behaviour. 45 | /// 46 | /// 47 | public class ClustersFromGroupsStrategy : ClusteringStrategy { 48 | 49 | /// 50 | /// Get the cluster key by which the given model will be partitioned by this strategy 51 | /// 52 | /// 53 | /// 54 | public override object GetClusterKey(object model) { 55 | return this.Column.GetGroupKey(model); 56 | } 57 | 58 | /// 59 | /// Gets the display label that the given cluster should use 60 | /// 61 | /// 62 | /// 63 | public override string GetClusterDisplayLabel(ICluster cluster) { 64 | string s = this.Column.ConvertGroupKeyToTitle(cluster.ClusterKey); 65 | if (String.IsNullOrEmpty(s)) 66 | s = EMPTY_LABEL; 67 | return this.ApplyDisplayFormat(cluster, s); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/ObjectListView/Filtering/FlagClusteringStrategy.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * FlagClusteringStrategy - Implements a clustering strategy for a field which is a single integer 3 | * containing an XOR'ed collection of bit flags 4 | * 5 | * Author: Phillip Piper 6 | * Date: 23-March-2012 8:33 am 7 | * 8 | * Change log: 9 | * 2012-03-23 JPP - First version 10 | * 11 | * Copyright (C) 2012 Phillip Piper 12 | * 13 | * This program is free software: you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation, either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program. If not, see . 25 | * 26 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 27 | */ 28 | 29 | using System; 30 | using System.Collections; 31 | using System.Collections.Generic; 32 | using System.Globalization; 33 | 34 | namespace BrightIdeasSoftware { 35 | 36 | /// 37 | /// Instances of this class cluster model objects on the basis of a 38 | /// property that holds an xor-ed collection of bit flags. 39 | /// 40 | public class FlagClusteringStrategy : ClusteringStrategy 41 | { 42 | #region Life and death 43 | 44 | /// 45 | /// Create a clustering strategy that operates on the flags of the given enum 46 | /// 47 | /// 48 | public FlagClusteringStrategy(Type enumType) { 49 | if (enumType == null) throw new ArgumentNullException("enumType"); 50 | if (!enumType.IsEnum) throw new ArgumentException("Type must be enum", "enumType"); 51 | if (enumType.GetCustomAttributes(typeof(FlagsAttribute), false) == null) throw new ArgumentException("Type must have [Flags] attribute", "enumType"); 52 | 53 | List flags = new List(); 54 | foreach (object x in Enum.GetValues(enumType)) 55 | flags.Add(Convert.ToInt64(x)); 56 | 57 | List flagLabels = new List(); 58 | foreach (string x in Enum.GetNames(enumType)) 59 | flagLabels.Add(x); 60 | 61 | this.SetValues(flags.ToArray(), flagLabels.ToArray()); 62 | } 63 | 64 | /// 65 | /// Create a clustering strategy around the given collections of flags and their display labels. 66 | /// There must be the same number of elements in both collections. 67 | /// 68 | /// The list of flags. 69 | /// 70 | public FlagClusteringStrategy(long[] values, string[] labels) { 71 | this.SetValues(values, labels); 72 | } 73 | 74 | #endregion 75 | 76 | #region Implementation 77 | 78 | /// 79 | /// Gets the value that will be xor-ed to test for the presence of a particular value. 80 | /// 81 | public long[] Values { 82 | get { return this.values; } 83 | private set { this.values = value; } 84 | } 85 | private long[] values; 86 | 87 | /// 88 | /// Gets the labels that will be used when the corresponding Value is XOR present in the data. 89 | /// 90 | public string[] Labels { 91 | get { return this.labels; } 92 | private set { this.labels = value; } 93 | } 94 | private string[] labels; 95 | 96 | private void SetValues(long[] flags, string[] flagLabels) { 97 | if (flags == null || flags.Length == 0) throw new ArgumentNullException("flags"); 98 | if (flagLabels == null || flagLabels.Length == 0) throw new ArgumentNullException("flagLabels"); 99 | if (flags.Length != flagLabels.Length) throw new ArgumentException("values and labels must have the same number of entries", "flags"); 100 | 101 | this.Values = flags; 102 | this.Labels = flagLabels; 103 | } 104 | 105 | #endregion 106 | 107 | #region Implementation of IClusteringStrategy 108 | 109 | /// 110 | /// Get the cluster key by which the given model will be partitioned by this strategy 111 | /// 112 | /// 113 | /// 114 | public override object GetClusterKey(object model) { 115 | List flags = new List(); 116 | try { 117 | long modelValue = Convert.ToInt64(this.Column.GetValue(model)); 118 | foreach (long x in this.Values) { 119 | if ((x & modelValue) == x) 120 | flags.Add(x); 121 | } 122 | return flags; 123 | } 124 | catch (InvalidCastException ex) { 125 | System.Diagnostics.Debug.Write(ex); 126 | return flags; 127 | } 128 | catch (FormatException ex) { 129 | System.Diagnostics.Debug.Write(ex); 130 | return flags; 131 | } 132 | } 133 | 134 | /// 135 | /// Gets the display label that the given cluster should use 136 | /// 137 | /// 138 | /// 139 | public override string GetClusterDisplayLabel(ICluster cluster) { 140 | long clusterKeyAsUlong = Convert.ToInt64(cluster.ClusterKey); 141 | for (int i = 0; i < this.Values.Length; i++ ) { 142 | if (clusterKeyAsUlong == this.Values[i]) 143 | return this.ApplyDisplayFormat(cluster, this.Labels[i]); 144 | } 145 | return this.ApplyDisplayFormat(cluster, clusterKeyAsUlong.ToString(CultureInfo.CurrentUICulture)); 146 | } 147 | 148 | /// 149 | /// Create a filter that will include only model objects that 150 | /// match one or more of the given values. 151 | /// 152 | /// 153 | /// 154 | public override IModelFilter CreateFilter(IList valuesChosenForFiltering) { 155 | return new FlagBitSetFilter(this.GetClusterKey, valuesChosenForFiltering); 156 | } 157 | 158 | #endregion 159 | } 160 | } -------------------------------------------------------------------------------- /src/ObjectListView/Filtering/ICluster.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ICluster - A cluster is a group of objects that can be included or excluded as a whole 3 | * 4 | * Author: Phillip Piper 5 | * Date: 4-March-2011 11:59 pm 6 | * 7 | * Change log: 8 | * 2011-03-04 JPP - First version 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Text; 31 | 32 | namespace BrightIdeasSoftware { 33 | 34 | /// 35 | /// A cluster is a like collection of objects that can be usefully filtered 36 | /// as whole using the filtering UI provided by the ObjectListView. 37 | /// 38 | public interface ICluster : IComparable { 39 | /// 40 | /// Gets or sets how many items belong to this cluster 41 | /// 42 | int Count { get; set; } 43 | 44 | /// 45 | /// Gets or sets the label that will be shown to the user to represent 46 | /// this cluster 47 | /// 48 | string DisplayLabel { get; set; } 49 | 50 | /// 51 | /// Gets or sets the actual data object that all members of this cluster 52 | /// have commonly returned. 53 | /// 54 | object ClusterKey { get; set; } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ObjectListView/Filtering/IClusteringStrategy.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * IClusterStrategy - Encapsulates the ability to create a list of clusters from an ObjectListView 3 | * 4 | * Author: Phillip Piper 5 | * Date: 4-March-2011 11:59 pm 6 | * 7 | * Change log: 8 | * 2012-05-23 JPP - Added CreateFilter() method to interface to allow the strategy 9 | * to control the actual model filter that is created. 10 | * v2.5 11 | * 2011-03-04 JPP - First version 12 | * 13 | * Copyright (C) 2011-2014 Phillip Piper 14 | * 15 | * This program is free software: you can redistribute it and/or modify 16 | * it under the terms of the GNU General Public License as published by 17 | * the Free Software Foundation, either version 3 of the License, or 18 | * (at your option) any later version. 19 | * 20 | * This program is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | * GNU General Public License for more details. 24 | * 25 | * You should have received a copy of the GNU General Public License 26 | * along with this program. If not, see . 27 | * 28 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 29 | */ 30 | 31 | using System; 32 | using System.Collections; 33 | using System.Collections.Generic; 34 | using System.Text; 35 | 36 | namespace BrightIdeasSoftware{ 37 | 38 | /// 39 | /// Implementation of this interface control the selecting of cluster keys 40 | /// and how those clusters will be presented to the user 41 | /// 42 | public interface IClusteringStrategy { 43 | 44 | /// 45 | /// Gets or sets the column upon which this strategy will operate 46 | /// 47 | OLVColumn Column { get; set; } 48 | 49 | /// 50 | /// Get the cluster key by which the given model will be partitioned by this strategy 51 | /// 52 | /// If the returned value is an IEnumerable, the given model is considered 53 | /// to belong to multiple clusters 54 | /// 55 | /// 56 | object GetClusterKey(object model); 57 | 58 | /// 59 | /// Create a cluster to hold the given cluster key 60 | /// 61 | /// 62 | /// 63 | ICluster CreateCluster(object clusterKey); 64 | 65 | /// 66 | /// Gets the display label that the given cluster should use 67 | /// 68 | /// 69 | /// 70 | string GetClusterDisplayLabel(ICluster cluster); 71 | 72 | /// 73 | /// Create a filter that will include only model objects that 74 | /// match one or more of the given values. 75 | /// 76 | /// 77 | /// 78 | IModelFilter CreateFilter(IList valuesChosenForFiltering); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/ObjectListView/Implementation/Enums.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Enums - All enum definitions used in ObjectListView 3 | * 4 | * Author: Phillip Piper 5 | * Date: 31-March-2011 5:53 pm 6 | * 7 | * Change log: 8 | * 2011-03-31 JPP - Split into its own file 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Text; 31 | 32 | namespace BrightIdeasSoftware { 33 | 34 | public partial class ObjectListView { 35 | /// 36 | /// How does a user indicate that they want to edit cells? 37 | /// 38 | public enum CellEditActivateMode { 39 | /// 40 | /// This list cannot be edited. F2 does nothing. 41 | /// 42 | None = 0, 43 | 44 | /// 45 | /// A single click on a subitem will edit the value. Single clicking the primary column, 46 | /// selects the row just like normal. The user must press F2 to edit the primary column. 47 | /// 48 | SingleClick = 1, 49 | 50 | /// 51 | /// Double clicking a subitem or the primary column will edit that cell. 52 | /// F2 will edit the primary column. 53 | /// 54 | DoubleClick = 2, 55 | 56 | /// 57 | /// Pressing F2 is the only way to edit the cells. Once the primary column is being edited, 58 | /// the other cells in the row can be edited by pressing Tab. 59 | /// 60 | F2Only = 3, 61 | 62 | /// 63 | /// A single click on a any cell will edit the value, even the primary column. 64 | /// 65 | SingleClickAlways = 4, 66 | } 67 | 68 | /// 69 | /// These values specify how column selection will be presented to the user 70 | /// 71 | public enum ColumnSelectBehaviour { 72 | /// 73 | /// No column selection will be presented 74 | /// 75 | None, 76 | 77 | /// 78 | /// The columns will be show in the main menu 79 | /// 80 | InlineMenu, 81 | 82 | /// 83 | /// The columns will be shown in a submenu 84 | /// 85 | Submenu, 86 | 87 | /// 88 | /// A model dialog will be presented to allow the user to choose columns 89 | /// 90 | ModelDialog, 91 | 92 | /* 93 | * NonModelDialog is just a little bit tricky since the OLV can change views while the dialog is showing 94 | * So, just comment this out for the time being. 95 | 96 | /// 97 | /// A non-model dialog will be presented to allow the user to choose columns 98 | /// 99 | NonModelDialog 100 | * 101 | */ 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /src/ObjectListView/Implementation/NullableDictionary.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * NullableDictionary - A simple Dictionary that can handle null as a key 3 | * 4 | * Author: Phillip Piper 5 | * Date: 31-March-2011 5:53 pm 6 | * 7 | * Change log: 8 | * 2011-03-31 JPP - Split into its own file 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Text; 31 | using System.Collections; 32 | 33 | namespace BrightIdeasSoftware { 34 | 35 | /// 36 | /// A simple-minded implementation of a Dictionary that can handle null as a key. 37 | /// 38 | /// The type of the dictionary key 39 | /// The type of the values to be stored 40 | /// This is not a full implementation and is only meant to handle 41 | /// collecting groups by their keys, since groups can have null as a key value. 42 | internal class NullableDictionary : Dictionary { 43 | private bool hasNullKey; 44 | private TValue nullValue; 45 | 46 | new public TValue this[TKey key] { 47 | get { 48 | if (key != null) 49 | return base[key]; 50 | 51 | if (this.hasNullKey) 52 | return this.nullValue; 53 | 54 | throw new KeyNotFoundException(); 55 | } 56 | set { 57 | if (key == null) { 58 | this.hasNullKey = true; 59 | this.nullValue = value; 60 | } else 61 | base[key] = value; 62 | } 63 | } 64 | 65 | new public bool ContainsKey(TKey key) { 66 | return key == null ? this.hasNullKey : base.ContainsKey(key); 67 | } 68 | 69 | new public IList Keys { 70 | get { 71 | ArrayList list = new ArrayList(base.Keys); 72 | if (this.hasNullKey) 73 | list.Add(null); 74 | return list; 75 | } 76 | } 77 | 78 | new public IList Values { 79 | get { 80 | List list = new List(base.Values); 81 | if (this.hasNullKey) 82 | list.Add(this.nullValue); 83 | return list; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/ObjectListView/Implementation/OLVListSubItem.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * OLVListSubItem - A single cell in an ObjectListView 3 | * 4 | * Author: Phillip Piper 5 | * Date: 31-March-2011 5:53 pm 6 | * 7 | * Change log: 8 | * 2011-03-31 JPP - Split into its own file 9 | * 10 | * Copyright (C) 2011-2014 Phillip Piper 11 | * 12 | * This program is free software: you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation, either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program. If not, see . 24 | * 25 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 26 | */ 27 | 28 | using System; 29 | using System.Collections.Generic; 30 | using System.Drawing; 31 | using System.Text; 32 | using System.Windows.Forms; 33 | using System.ComponentModel; 34 | 35 | namespace BrightIdeasSoftware { 36 | 37 | /// 38 | /// A ListViewSubItem that knows which image should be drawn against it. 39 | /// 40 | [Browsable(false)] 41 | public class OLVListSubItem : ListViewItem.ListViewSubItem { 42 | #region Constructors 43 | 44 | /// 45 | /// Create a OLVListSubItem 46 | /// 47 | public OLVListSubItem() { 48 | } 49 | 50 | /// 51 | /// Create a OLVListSubItem that shows the given string and image 52 | /// 53 | public OLVListSubItem(object modelValue, string text, Object image) { 54 | this.ModelValue = modelValue; 55 | this.Text = text; 56 | this.ImageSelector = image; 57 | } 58 | 59 | #endregion 60 | 61 | #region Properties 62 | 63 | /// 64 | /// Gets or sets how many pixels will be left blank around this cell 65 | /// 66 | /// This setting only takes effect when the control is owner drawn. 67 | public Rectangle? CellPadding { 68 | get { return this.cellPadding; } 69 | set { this.cellPadding = value; } 70 | } 71 | private Rectangle? cellPadding; 72 | 73 | /// 74 | /// Gets or sets how this cell will be vertically aligned 75 | /// 76 | /// This setting only takes effect when the control is owner drawn. 77 | public StringAlignment? CellVerticalAlignment { 78 | get { return this.cellVerticalAlignment; } 79 | set { this.cellVerticalAlignment = value; } 80 | } 81 | private StringAlignment? cellVerticalAlignment; 82 | 83 | /// 84 | /// Gets or sets the model value is being displayed by this subitem. 85 | /// 86 | public object ModelValue 87 | { 88 | get { return modelValue; } 89 | private set { modelValue = value; } 90 | } 91 | private object modelValue; 92 | 93 | /// 94 | /// Gets if this subitem has any decorations set for it. 95 | /// 96 | public bool HasDecoration { 97 | get { 98 | return this.decorations != null && this.decorations.Count > 0; 99 | } 100 | } 101 | 102 | /// 103 | /// Gets or sets the decoration that will be drawn over this item 104 | /// 105 | /// Setting this replaces all other decorations 106 | public IDecoration Decoration { 107 | get { 108 | return this.HasDecoration ? this.Decorations[0] : null; 109 | } 110 | set { 111 | this.Decorations.Clear(); 112 | if (value != null) 113 | this.Decorations.Add(value); 114 | } 115 | } 116 | 117 | /// 118 | /// Gets the collection of decorations that will be drawn over this item 119 | /// 120 | public IList Decorations { 121 | get { 122 | if (this.decorations == null) 123 | this.decorations = new List(); 124 | return this.decorations; 125 | } 126 | } 127 | private IList decorations; 128 | 129 | /// 130 | /// Get or set the image that should be shown against this item 131 | /// 132 | /// This can be an Image, a string or an int. A string or an int will 133 | /// be used as an index into the small image list. 134 | public Object ImageSelector { 135 | get { return imageSelector; } 136 | set { imageSelector = value; } 137 | } 138 | private Object imageSelector; 139 | 140 | /// 141 | /// Gets or sets the url that should be invoked when this subitem is clicked 142 | /// 143 | public string Url 144 | { 145 | get { return this.url; } 146 | set { this.url = value; } 147 | } 148 | private string url; 149 | 150 | /// 151 | /// Gets or sets whether this cell is selected 152 | /// 153 | public bool Selected 154 | { 155 | get { return this.selected; } 156 | set { this.selected = value; } 157 | } 158 | private bool selected; 159 | 160 | #endregion 161 | 162 | #region Implementation Properties 163 | 164 | /// 165 | /// Return the state of the animatation of the image on this subitem. 166 | /// Null means there is either no image, or it is not an animation 167 | /// 168 | internal ImageRenderer.AnimationState AnimationState; 169 | 170 | #endregion 171 | } 172 | 173 | } 174 | -------------------------------------------------------------------------------- /src/ObjectListView/Package.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ObjectListView.Updated 5 | ObjectListView (Updated) 6 | $version$ 7 | Phillip Piper 8 | $author$ 9 | LICENSE 10 | .editoricon.png 11 | https://github.com/ennerperez/ObjectListView 12 | 13 | ObjectListView is a .NET ListView wired on caffeine, guarana and steroids. 14 | More calmly, it is a C# wrapper around a .NET ListView, which makes the ListView much easier to use and teaches it lots of neat new tricks. 15 | 16 | $description$ 17 | $copyright$ 18 | .Net WinForms ListView Controls 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/ObjectListView/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("ObjectListView")] 8 | [assembly: AssemblyDescription("A much easier to use ListView and friends")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Bright Ideas Software")] 11 | [assembly: AssemblyProduct("ObjectListView")] 12 | [assembly: AssemblyCopyright("Copyright © 2006-2020")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("ef28c7a8-77ae-442d-abc3-bb023fa31e57")] -------------------------------------------------------------------------------- /src/ObjectListView/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 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 BrightIdeasSoftware.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("BrightIdeasSoftware.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 resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap ClearFiltering { 67 | get { 68 | object obj = ResourceManager.GetObject("ClearFiltering", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap ColumnFilterIndicator { 77 | get { 78 | object obj = ResourceManager.GetObject("ColumnFilterIndicator", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap Filtering { 87 | get { 88 | object obj = ResourceManager.GetObject("Filtering", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap SortAscending { 97 | get { 98 | object obj = ResourceManager.GetObject("SortAscending", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap SortDescending { 107 | get { 108 | object obj = ResourceManager.GetObject("SortDescending", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/ObjectListView/Resources/clear-filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/clear-filter.png -------------------------------------------------------------------------------- /src/ObjectListView/Resources/coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/coffee.jpg -------------------------------------------------------------------------------- /src/ObjectListView/Resources/filter-icons3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/filter-icons3.png -------------------------------------------------------------------------------- /src/ObjectListView/Resources/filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/filter.png -------------------------------------------------------------------------------- /src/ObjectListView/Resources/sort-ascending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/sort-ascending.png -------------------------------------------------------------------------------- /src/ObjectListView/Resources/sort-descending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListView/Resources/sort-descending.png -------------------------------------------------------------------------------- /src/ObjectListView/Utilities/ColumnSelectionForm.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 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedDecoration.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * OlvDecorationAdapter - Put an animation as a decoration on an ObjectListView 3 | * 4 | * Author: Phillip Piper 5 | * Date: 24/02/2010 8:18 PM 6 | * 7 | * Change log: 8 | * 2010-02-24 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2009 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Drawing; 32 | using System.Windows.Forms; 33 | 34 | namespace BrightIdeasSoftware 35 | { 36 | /// 37 | /// Support running an animation as a decoration on an ObjectListView 38 | /// 39 | class AnimatedDecoration : AbstractDecoration 40 | { 41 | #region Life and death 42 | 43 | /// 44 | /// Create a decoration that will draw an animation onto the given ObjectListView 45 | /// 46 | /// 47 | public AnimatedDecoration(ObjectListView olv) { 48 | this.ListView = olv; 49 | this.Animation = new Animation(); 50 | this.SubscribeEvents(); 51 | } 52 | 53 | /// 54 | /// Create a decoration that will draw an animation around the row of the given model 55 | /// 56 | /// The model that identifies the row on which the 57 | /// animation will draw. If this is null, the decoration will drawn around the 58 | /// whole ListView. 59 | public AnimatedDecoration(ObjectListView olv, object modelObject) 60 | : this(olv) { 61 | this.ModelObject = modelObject; 62 | } 63 | 64 | /// 65 | /// Create a decoration that will draw an animation around a cell of the given model 66 | /// 67 | /// 68 | public AnimatedDecoration(ObjectListView olv, object modelObject, OLVColumn column) 69 | : this(olv) { 70 | this.ModelObject = modelObject; 71 | this.Column = column; 72 | } 73 | 74 | /// 75 | /// Create a decoration that will draw an animation around a cell of the given model 76 | /// 77 | /// 78 | public AnimatedDecoration(ObjectListView olv, OLVListItem item, OLVListSubItem subItem) 79 | : this(olv) { 80 | this.ModelObject = item.RowObject; 81 | this.Column = olv.GetColumn(item.SubItems.IndexOf(subItem)); 82 | } 83 | 84 | #endregion 85 | 86 | #region Public properties 87 | 88 | public ObjectListView ListView { get; protected set; } 89 | public Animation Animation { get; protected set; } 90 | public object ModelObject { get; protected set; } 91 | public OLVColumn Column { get; protected set; } 92 | 93 | #endregion 94 | 95 | #region Subscriptions 96 | 97 | protected void SubscribeEvents() { 98 | this.ListView.Disposed += new EventHandler(ListView_Disposed); 99 | this.Animation.Started += new EventHandler(Animation_Started); 100 | this.Animation.Stopped += new EventHandler(Animation_Stopped); 101 | this.Animation.Redraw += new EventHandler(Animation_Redraw); 102 | this.Animation.Ticked += new EventHandler(Animation_Ticked); 103 | } 104 | 105 | protected void UnsubscribeEvents() { 106 | this.ListView.Disposed -= new EventHandler(ListView_Disposed); 107 | this.Animation.Started -= new EventHandler(Animation_Started); 108 | this.Animation.Stopped -= new EventHandler(Animation_Stopped); 109 | this.Animation.Redraw -= new EventHandler(Animation_Redraw); 110 | this.Animation.Ticked -= new EventHandler(Animation_Ticked); 111 | } 112 | 113 | #endregion 114 | 115 | #region IOverlay implementation 116 | 117 | public override void Draw(ObjectListView olv, Graphics g, Rectangle r) { 118 | if (!this.Animation.Running) 119 | return; 120 | 121 | if (this.ModelObject != null) { 122 | this.ListItem = this.ListView.ModelToItem(this.ModelObject); 123 | if (this.ListItem == null) 124 | return; 125 | if (this.Column != null) { 126 | this.Animation.Bounds = this.ListItem.GetSubItemBounds(this.Column.Index); 127 | } else 128 | this.Animation.Bounds = this.RowBounds; 129 | } else { 130 | this.Animation.Bounds = r; 131 | } 132 | 133 | this.Animation.Draw(g); 134 | } 135 | 136 | #endregion 137 | 138 | #region Event handlers 139 | 140 | protected virtual void ListView_Disposed(object sender, EventArgs e) { 141 | this.Animation.Stop(); 142 | } 143 | 144 | protected virtual void Animation_Started(object sender, StartAnimationEventArgs e) { 145 | this.Animation.Bounds = this.ListView.ContentRectangle; 146 | this.ListView.AddDecoration(this); 147 | } 148 | 149 | protected virtual void Animation_Stopped(object sender, StopAnimationEventArgs e) { 150 | if (!this.ListView.IsDisposed && this.ListView.IsHandleCreated) { 151 | this.ListView.Invoke((MethodInvoker)delegate { 152 | this.UnsubscribeEvents(); 153 | this.ListView.RemoveDecoration(this); 154 | }); 155 | } 156 | } 157 | 158 | protected virtual void Animation_Redraw(object sender, RedrawEventArgs e) { 159 | if (!this.ListView.IsDisposed && this.ListView.IsHandleCreated) { 160 | this.ListView.Invoke((MethodInvoker)delegate { 161 | this.ListView.Invalidate(); 162 | }); 163 | } 164 | } 165 | 166 | protected virtual void Animation_Ticked(object sender, TickEventArgs e) { 167 | } 168 | 169 | #endregion 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/3dlink1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/3dlink1.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/cd1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/cd1.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/circum.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/circum.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/cool3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/cool3.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/enter3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/enter3.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/envelope.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/envelope.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/exclame.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/exclame.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/eye2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/eye2.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/net2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/net2.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/AnimatedGifs/new5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/AnimatedGifs/new5.gif -------------------------------------------------------------------------------- /src/ObjectListViewDemo/BusinessCardOverlay.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Windows.Forms; 3 | using BrightIdeasSoftware; 4 | 5 | namespace ObjectListViewDemo { 6 | /// 7 | /// This simple class just shows how an overlay can be drawn when the hot item changes. 8 | /// 9 | internal class BusinessCardOverlay : AbstractOverlay 10 | { 11 | public BusinessCardOverlay() 12 | { 13 | this.businessCardRenderer.HeaderBackBrush = Brushes.DarkBlue; 14 | this.businessCardRenderer.BorderPen = new Pen(Color.DarkBlue, 2); 15 | this.Transparency = 255; 16 | } 17 | #region IOverlay Members 18 | 19 | public override void Draw(ObjectListView olv, Graphics g, Rectangle r) 20 | { 21 | if (olv.HotRowIndex < 0) 22 | return; 23 | 24 | if (olv.View == View.Tile) 25 | return; 26 | 27 | OLVListItem item = olv.GetItem(olv.HotRowIndex); 28 | if (item == null) 29 | return; 30 | 31 | Size cardSize = new Size(250, 120); 32 | Rectangle cardBounds = new Rectangle( 33 | r.Right - cardSize.Width - 8, r.Bottom - cardSize.Height - 8, cardSize.Width, cardSize.Height); 34 | this.businessCardRenderer.DrawBusinessCard(g, cardBounds, item.RowObject, olv, item); 35 | } 36 | 37 | #endregion 38 | 39 | private readonly BusinessCardRenderer businessCardRenderer = new BusinessCardRenderer(); 40 | } 41 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/BusinessCardRenderer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Drawing.Drawing2D; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | using BrightIdeasSoftware; 7 | using ObjectListViewDemo.Models; 8 | 9 | namespace ObjectListViewDemo { 10 | /// 11 | /// Hackish renderer that draw a fancy version of a person for a Tile view. 12 | /// 13 | /// This is not the way to write a professional level renderer. 14 | /// It is hideously inefficient (we should at least cache the images), 15 | /// but it is obvious 16 | public class BusinessCardRenderer : AbstractRenderer 17 | { 18 | public override bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object rowObject) 19 | { 20 | // If we're in any other view than Tile, return false to say that we haven't done 21 | // the renderering and the default process should do it's stuff 22 | ObjectListView olv = e.Item.ListView as ObjectListView; 23 | if (olv == null || olv.View != View.Tile) 24 | return false; 25 | 26 | // Use buffered graphics to kill flickers 27 | BufferedGraphics buffered = BufferedGraphicsManager.Current.Allocate(g, itemBounds); 28 | g = buffered.Graphics; 29 | g.Clear(olv.BackColor); 30 | g.SmoothingMode = ObjectListView.SmoothingMode; 31 | g.TextRenderingHint = ObjectListView.TextRenderingHint; 32 | 33 | if (e.Item.Selected) 34 | { 35 | this.BorderPen = Pens.Blue; 36 | this.HeaderBackBrush = new SolidBrush(olv.SelectedBackColorOrDefault); 37 | } 38 | else 39 | { 40 | this.BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33)); 41 | this.HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33)); 42 | } 43 | DrawBusinessCard(g, itemBounds, rowObject, olv, (OLVListItem)e.Item); 44 | 45 | // Finally render the buffered graphics 46 | buffered.Render(); 47 | buffered.Dispose(); 48 | 49 | // Return true to say that we've handled the drawing 50 | return true; 51 | } 52 | 53 | internal Pen BorderPen = new Pen(Color.FromArgb(0x33, 0x33, 0x33)); 54 | internal Brush TextBrush = new SolidBrush(Color.FromArgb(0x22, 0x22, 0x22)); 55 | internal Brush HeaderTextBrush = Brushes.AliceBlue; 56 | internal Brush HeaderBackBrush = new SolidBrush(Color.FromArgb(0x33, 0x33, 0x33)); 57 | internal Brush BackBrush = Brushes.LemonChiffon; 58 | 59 | public void DrawBusinessCard(Graphics g, Rectangle itemBounds, object rowObject, ObjectListView olv, OLVListItem item) 60 | { 61 | const int spacing = 8; 62 | 63 | // Allow a border around the card 64 | itemBounds.Inflate(-2, -2); 65 | 66 | // Draw card background 67 | const int rounding = 20; 68 | GraphicsPath path = this.GetRoundedRect(itemBounds, rounding); 69 | g.FillPath(this.BackBrush, path); 70 | g.DrawPath(this.BorderPen, path); 71 | 72 | g.Clip = new Region(itemBounds); 73 | 74 | // Draw the photo 75 | Rectangle photoRect = itemBounds; 76 | photoRect.Inflate(-spacing, -spacing); 77 | Person person = rowObject as Person; 78 | if (person != null) 79 | { 80 | photoRect.Width = 80; 81 | string photoFile = String.Format(@".\Photos\{0}.png", person.Photo); 82 | if (File.Exists(photoFile)) 83 | { 84 | Image photo = Image.FromFile(photoFile); 85 | if (photo.Width > photoRect.Width) 86 | photoRect.Height = (int)(photo.Height * ((float)photoRect.Width / photo.Width)); 87 | else 88 | photoRect.Height = photo.Height; 89 | g.DrawImage(photo, photoRect); 90 | } 91 | else 92 | { 93 | g.DrawRectangle(Pens.DarkGray, photoRect); 94 | } 95 | } 96 | 97 | // Now draw the text portion 98 | RectangleF textBoxRect = photoRect; 99 | textBoxRect.X += (photoRect.Width + spacing); 100 | textBoxRect.Width = itemBounds.Right - textBoxRect.X - spacing; 101 | 102 | StringFormat fmt = new StringFormat(StringFormatFlags.NoWrap); 103 | fmt.Trimming = StringTrimming.EllipsisCharacter; 104 | fmt.Alignment = StringAlignment.Center; 105 | fmt.LineAlignment = StringAlignment.Near; 106 | String txt = item.Text; 107 | 108 | using (Font font = new Font("Tahoma", 11)) 109 | { 110 | // Measure the height of the title 111 | SizeF size = g.MeasureString(txt, font, (int)textBoxRect.Width, fmt); 112 | // Draw the title 113 | RectangleF r3 = textBoxRect; 114 | r3.Height = size.Height; 115 | path = this.GetRoundedRect(r3, 15); 116 | g.FillPath(this.HeaderBackBrush, path); 117 | g.DrawString(txt, font, this.HeaderTextBrush, textBoxRect, fmt); 118 | textBoxRect.Y += size.Height + spacing; 119 | } 120 | 121 | // Draw the other bits of information 122 | using (Font font = new Font("Tahoma", 8)) 123 | { 124 | SizeF size = g.MeasureString("Wj", font, itemBounds.Width, fmt); 125 | textBoxRect.Height = size.Height; 126 | fmt.Alignment = StringAlignment.Near; 127 | for (int i = 0; i < olv.Columns.Count; i++) 128 | { 129 | OLVColumn column = olv.GetColumn(i); 130 | if (column.IsTileViewColumn) 131 | { 132 | txt = column.GetStringValue(rowObject); 133 | g.DrawString(txt, font, this.TextBrush, textBoxRect, fmt); 134 | textBoxRect.Y += size.Height; 135 | } 136 | } 137 | } 138 | } 139 | 140 | private GraphicsPath GetRoundedRect(RectangleF rect, float diameter) 141 | { 142 | GraphicsPath path = new GraphicsPath(); 143 | 144 | RectangleF arc = new RectangleF(rect.X, rect.Y, diameter, diameter); 145 | path.AddArc(arc, 180, 90); 146 | arc.X = rect.Right - diameter; 147 | path.AddArc(arc, 270, 90); 148 | arc.Y = rect.Bottom - diameter; 149 | path.AddArc(arc, 0, 90); 150 | arc.X = rect.Left; 151 | path.AddArc(arc, 90, 90); 152 | path.CloseFigure(); 153 | 154 | return path; 155 | } 156 | } 157 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/ColumnSelectionForm.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 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/MainForm.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ObjectListViewDemo - A simple demo to show the ObjectListView control 3 | * 4 | * User: Phillip Piper 5 | * Date: 15/10/2006 11:15 AM 6 | * 7 | * Change log: 8 | * 2015-06-12 JPP COMPLETE REWRITE. Goal of rewrite is to make the code much easier to follow 9 | * 10 | * 2009-07-04 JPP Added ExampleVirtualDataSource for virtual list demo 11 | * [lots of stuff] 12 | * 2006-10-20 JPP Added DataSet tab page 13 | * 2006-10-15 JPP Initial version 14 | */ 15 | 16 | using System; 17 | using System.Drawing; 18 | using System.Windows.Forms; 19 | using BrightIdeasSoftware; 20 | 21 | namespace ObjectListViewDemo { 22 | 23 | public partial class MainForm { 24 | 25 | [STAThread] 26 | public static void Main(string[] args) { 27 | Application.EnableVisualStyles(); 28 | Application.SetCompatibleTextRenderingDefault(false); 29 | Application.Run(new MainForm()); 30 | } 31 | 32 | /// 33 | /// 34 | /// 35 | public MainForm() { 36 | // 37 | // The InitializeComponent() call is required for Windows Forms designer support. 38 | // 39 | InitializeComponent(); 40 | InitializeExamples(); 41 | } 42 | 43 | void InitializeExamples() { 44 | // Use different font under Vista 45 | if (ObjectListView.IsVistaOrLater) 46 | this.Font = new Font("Segoe UI", 9); 47 | 48 | OLVDemoCoordinator coordinator = new OLVDemoCoordinator(this); 49 | 50 | this.tabSimple.Coordinator = coordinator; 51 | this.tabComplex.Coordinator = coordinator; 52 | this.tabDataSet.Coordinator = coordinator; 53 | this.tabFileExplorer1.Coordinator = coordinator; 54 | this.tabFastList1.Coordinator = coordinator; 55 | this.tabTreeListView1.Coordinator = coordinator; 56 | this.tabDataTreeListView1.Coordinator = coordinator; 57 | this.tabDragAndDrop1.Coordinator = coordinator; 58 | this.tabDescribedTask1.Coordinator = coordinator; 59 | 60 | // Printing tab is slightly different, since it needs to know about the ObjectListViews from the other tabs 61 | this.tabPrinting1.SimpleView = this.tabSimple.ListView; 62 | this.tabPrinting1.ComplexView = this.tabComplex.ListView; 63 | this.tabPrinting1.DataListView = this.tabDataSet.ListView; 64 | this.tabPrinting1.FileExplorerView = this.tabFileExplorer1.ListView; 65 | this.tabPrinting1.TreeListView = this.tabTreeListView1.ListView; 66 | this.tabPrinting1.Coordinator = coordinator; 67 | 68 | //this.tabControl1.SelectTab(this.tabDescribedTasks); 69 | } 70 | 71 | private void tabControl1_Selected(object sender, TabControlEventArgs e) 72 | { 73 | if (tabControl1.TabPages[e.TabPageIndex].Name == "tabPagePrinting") 74 | this.tabPrinting1.UpdatePrintPreview(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 243, 17 122 | 123 | 124 | 35 125 | 126 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Models/MaritalStatus.cs: -------------------------------------------------------------------------------- 1 | namespace ObjectListViewDemo.Models { 2 | public enum MaritalStatus 3 | { 4 | Single, 5 | Married, 6 | Divorced, 7 | Partnered 8 | } 9 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Models/MyFileSystemInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.IO; 4 | 5 | namespace ObjectListViewDemo.Models { 6 | /// 7 | /// Standard .NET FileSystemInfos are always not equal to each other. 8 | /// When we try to refresh a directory, our controls can't match up new 9 | /// files with existing files. They are also sealed so we can't just subclass them. 10 | /// This class is a wrapper around a FileSystemInfo that simply provides 11 | /// equality. 12 | /// 13 | public class MyFileSystemInfo : IEquatable 14 | { 15 | public MyFileSystemInfo(FileSystemInfo fileSystemInfo) { 16 | if (fileSystemInfo == null) throw new ArgumentNullException("fileSystemInfo"); 17 | this.info = fileSystemInfo; 18 | } 19 | 20 | public bool IsDirectory { get { return this.AsDirectory != null; } } 21 | 22 | public DirectoryInfo AsDirectory { get { return this.info as DirectoryInfo; } } 23 | public FileInfo AsFile{ get { return this.info as FileInfo; } } 24 | 25 | public FileSystemInfo Info { 26 | get { return this.info; } 27 | } 28 | private readonly FileSystemInfo info; 29 | 30 | public string Name { 31 | get { return this.info.Name; } 32 | } 33 | 34 | public string Extension { 35 | get { return this.info.Extension; } 36 | } 37 | 38 | public DateTime CreationTime { 39 | get { return this.info.CreationTime; } 40 | } 41 | 42 | public DateTime LastWriteTime { 43 | get { return this.info.LastWriteTime; } 44 | } 45 | 46 | public string FullName { 47 | get { return this.info.FullName; } 48 | } 49 | 50 | public FileAttributes Attributes { 51 | get { return this.info.Attributes; } 52 | } 53 | 54 | public long Length { 55 | get { return this.AsFile.Length; } 56 | } 57 | 58 | public IEnumerable GetFileSystemInfos() { 59 | ArrayList children = new ArrayList(); 60 | if (this.IsDirectory) { 61 | foreach (FileSystemInfo x in this.AsDirectory.GetFileSystemInfos()) 62 | children.Add(new MyFileSystemInfo(x)); 63 | } 64 | return children; 65 | } 66 | 67 | // Two file system objects are equal if they point to the same file system path 68 | 69 | public bool Equals(MyFileSystemInfo other) { 70 | if (ReferenceEquals(null, other)) return false; 71 | if (ReferenceEquals(this, other)) return true; 72 | return Equals(other.info.FullName, this.info.FullName); 73 | } 74 | public override bool Equals(object obj) { 75 | if (ReferenceEquals(null, obj)) return false; 76 | if (ReferenceEquals(this, obj)) return true; 77 | if (obj.GetType() != typeof(MyFileSystemInfo)) return false; 78 | return Equals((MyFileSystemInfo)obj); 79 | } 80 | public override int GetHashCode() { 81 | return (this.info != null ? this.info.FullName.GetHashCode() : 0); 82 | } 83 | public static bool operator ==(MyFileSystemInfo left, MyFileSystemInfo right) { 84 | return Equals(left, right); 85 | } 86 | public static bool operator !=(MyFileSystemInfo left, MyFileSystemInfo right) { 87 | return !Equals(left, right); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Models/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Drawing; 4 | using BrightIdeasSoftware; 5 | using BrightIdeasSoftware.Properties; 6 | 7 | namespace ObjectListViewDemo.Models 8 | { 9 | public class Person : INotifyPropertyChanged 10 | { 11 | public bool IsActive = true; 12 | 13 | public Person(string name) 14 | { 15 | this.name = name; 16 | } 17 | 18 | public Person(string name, string occupation, int culinaryRating, DateTime birthDate, double hourlyRate, bool canTellJokes, string photo, string comments) 19 | { 20 | this.name = name; 21 | this.Occupation = occupation; 22 | this.culinaryRating = culinaryRating; 23 | this.birthDate = birthDate; 24 | this.hourlyRate = hourlyRate; 25 | this.CanTellJokes = canTellJokes; 26 | this.Comments = comments; 27 | this.Photo = photo; 28 | } 29 | 30 | public Person(Person other) 31 | { 32 | this.name = other.Name; 33 | this.Occupation = other.Occupation; 34 | this.culinaryRating = other.CulinaryRating; 35 | this.birthDate = other.BirthDate; 36 | this.hourlyRate = other.GetRate(); 37 | this.CanTellJokes = other.CanTellJokes; 38 | this.Photo = other.Photo; 39 | this.Comments = other.Comments; 40 | this.MaritalStatus = other.MaritalStatus; 41 | } 42 | 43 | [OLVIgnore] 44 | public Image ImageAspect 45 | { 46 | get 47 | { 48 | return Resource1.folder16; 49 | } 50 | } 51 | 52 | [OLVIgnore] 53 | public string ImageName 54 | { 55 | get 56 | { 57 | return "user"; 58 | } 59 | } 60 | 61 | // Allows tests for properties. 62 | [OLVColumn(ImageAspectName = "ImageName")] 63 | public string Name 64 | { 65 | get { return this.name; } 66 | set 67 | { 68 | if (this.name == value) return; 69 | this.name = value; 70 | this.OnPropertyChanged("Name"); 71 | } 72 | } 73 | 74 | private string name; 75 | 76 | [OLVColumn(ImageAspectName = "ImageName")] 77 | public string Occupation 78 | { 79 | get { return this.occupation; } 80 | set 81 | { 82 | if (this.occupation == value) return; 83 | this.occupation = value; 84 | this.OnPropertyChanged("Occupation"); 85 | } 86 | } 87 | 88 | private string occupation; 89 | 90 | public int CulinaryRating 91 | { 92 | get { return this.culinaryRating; } 93 | set { this.culinaryRating = value; } 94 | } 95 | 96 | private int culinaryRating; 97 | 98 | public DateTime BirthDate 99 | { 100 | get { return this.birthDate; } 101 | set { this.birthDate = value; } 102 | } 103 | 104 | private DateTime birthDate; 105 | 106 | public int YearOfBirth 107 | { 108 | get { return this.BirthDate.Year; } 109 | set { this.BirthDate = new DateTime(value, this.birthDate.Month, this.birthDate.Day); } 110 | } 111 | 112 | // Allow tests for methods 113 | public double GetRate() 114 | { 115 | return this.hourlyRate; 116 | } 117 | 118 | private double hourlyRate; 119 | 120 | public void SetRate(double value) 121 | { 122 | this.hourlyRate = value; 123 | } 124 | 125 | // Allows tests for fields. 126 | public string Photo; 127 | 128 | public string Comments; 129 | public int serialNumber; 130 | public bool? CanTellJokes; 131 | 132 | // Allow tests for enums 133 | public MaritalStatus MaritalStatus = MaritalStatus.Single; 134 | 135 | #region Implementation of INotifyPropertyChanged 136 | 137 | public event PropertyChangedEventHandler PropertyChanged; 138 | 139 | private void OnPropertyChanged(string propertyName) 140 | { 141 | if (this.PropertyChanged != null) 142 | this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 143 | } 144 | 145 | #endregion Implementation of INotifyPropertyChanged 146 | } 147 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/MyFileSystemInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.IO; 4 | 5 | namespace ObjectListViewDemo { 6 | /// 7 | /// Standard .NET FileSystemInfos are always not equal to each other. 8 | /// When we try to refresh a directory, our controls can't match up new 9 | /// files with existing files. They are also sealed so we can't just subclass them. 10 | /// This class is a wrapper around a FileSystemInfo that simply provides 11 | /// equality. 12 | /// 13 | public class MyFileSystemInfo : IEquatable 14 | { 15 | public MyFileSystemInfo(FileSystemInfo fileSystemInfo) { 16 | if (fileSystemInfo == null) throw new ArgumentNullException("fileSystemInfo"); 17 | this.info = fileSystemInfo; 18 | } 19 | 20 | public bool IsDirectory { get { return this.AsDirectory != null; } } 21 | 22 | public DirectoryInfo AsDirectory { get { return info as DirectoryInfo; } } 23 | public FileInfo AsFile{ get { return info as FileInfo; } } 24 | 25 | public FileSystemInfo Info { 26 | get { return this.info; } 27 | } 28 | private readonly FileSystemInfo info; 29 | 30 | public string Name { 31 | get { return info.Name; } 32 | } 33 | 34 | public string Extension { 35 | get { return info.Extension; } 36 | } 37 | 38 | public DateTime CreationTime { 39 | get { return info.CreationTime; } 40 | } 41 | 42 | public DateTime LastWriteTime { 43 | get { return info.LastWriteTime; } 44 | } 45 | 46 | public string FullName { 47 | get { return info.FullName; } 48 | } 49 | 50 | public FileAttributes Attributes { 51 | get { return info.Attributes; } 52 | } 53 | 54 | public long Length { 55 | get { return this.AsFile.Length; } 56 | } 57 | 58 | public IEnumerable GetFileSystemInfos() { 59 | ArrayList children = new ArrayList(); 60 | if (this.IsDirectory) { 61 | foreach (FileSystemInfo x in this.AsDirectory.GetFileSystemInfos()) 62 | children.Add(new MyFileSystemInfo(x)); 63 | } 64 | return children; 65 | } 66 | 67 | // Two file system objects are equal if they point to the same file system path 68 | 69 | public bool Equals(MyFileSystemInfo other) { 70 | if (ReferenceEquals(null, other)) return false; 71 | if (ReferenceEquals(this, other)) return true; 72 | return Equals(other.info.FullName, this.info.FullName); 73 | } 74 | public override bool Equals(object obj) { 75 | if (ReferenceEquals(null, obj)) return false; 76 | if (ReferenceEquals(this, obj)) return true; 77 | if (obj.GetType() != typeof(MyFileSystemInfo)) return false; 78 | return Equals((MyFileSystemInfo)obj); 79 | } 80 | public override int GetHashCode() { 81 | return (this.info != null ? this.info.FullName.GetHashCode() : 0); 82 | } 83 | public static bool operator ==(MyFileSystemInfo left, MyFileSystemInfo right) { 84 | return Equals(left, right); 85 | } 86 | public static bool operator !=(MyFileSystemInfo left, MyFileSystemInfo right) { 87 | return !Equals(left, right); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/OlvDemoTab.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | using BrightIdeasSoftware; 5 | 6 | namespace ObjectListViewDemo { 7 | public class OlvDemoTab : UserControl { 8 | 9 | [Browsable(false), 10 | DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 11 | public OLVDemoCoordinator Coordinator 12 | { 13 | get { return coordinator; } 14 | set 15 | { 16 | coordinator = value; 17 | if (value != null) { 18 | this.InitializeTab(); 19 | this.SetupGeneralListViewEvents(); 20 | } 21 | } 22 | } 23 | private OLVDemoCoordinator coordinator; 24 | private ObjectListView listView; 25 | 26 | protected virtual void InitializeTab() { } 27 | 28 | public ObjectListView ListView { 29 | get { return this.listView; } 30 | protected set { this.listView = value; } 31 | } 32 | 33 | private void SetupGeneralListViewEvents() { 34 | if (this.ListView == null || this.Coordinator == null) 35 | return; 36 | 37 | this.ListView.SelectionChanged += delegate(object sender, EventArgs args) { 38 | this.Coordinator.HandleSelectionChanged(this.ListView); 39 | }; 40 | 41 | this.ListView.HotItemChanged += delegate(object sender, HotItemChangedEventArgs args) { 42 | this.Coordinator.HandleHotItemChanged(sender, args); 43 | }; 44 | 45 | this.ListView.GroupTaskClicked += delegate(object sender, GroupTaskClickedEventArgs args) { 46 | Coordinator.ShowMessage("Clicked on group task: " + args.Group.Name); 47 | }; 48 | 49 | this.ListView.GroupStateChanged += delegate(object sender, GroupStateChangedEventArgs e) { 50 | System.Diagnostics.Debug.WriteLine(String.Format("Group '{0}' was {1}{2}{3}{4}{5}{6}", 51 | e.Group.Header, 52 | e.Selected ? "Selected" : "", 53 | e.Focused ? "Focused" : "", 54 | e.Collapsed ? "Collapsed" : "", 55 | e.Unselected ? "Unselected" : "", 56 | e.Unfocused ? "Unfocused" : "", 57 | e.Uncollapsed ? "Uncollapsed" : "")); 58 | }; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Drawing; 4 | using BrightIdeasSoftware; 5 | 6 | namespace ObjectListViewDemo { 7 | 8 | public enum MaritalStatus 9 | { 10 | Single, 11 | Married, 12 | Divorced, 13 | Partnered 14 | } 15 | 16 | public class Person : INotifyPropertyChanged 17 | { 18 | public bool IsActive = true; 19 | 20 | public Person(string name) { 21 | this.name = name; 22 | } 23 | 24 | public Person(string name, string occupation, int culinaryRating, DateTime birthDate, double hourlyRate, bool canTellJokes, string photo, string comments) { 25 | this.name = name; 26 | this.Occupation = occupation; 27 | this.culinaryRating = culinaryRating; 28 | this.birthDate = birthDate; 29 | this.hourlyRate = hourlyRate; 30 | this.CanTellJokes = canTellJokes; 31 | this.Comments = comments; 32 | this.Photo = photo; 33 | } 34 | 35 | public Person(Person other) { 36 | this.name = other.Name; 37 | this.Occupation = other.Occupation; 38 | this.culinaryRating = other.CulinaryRating; 39 | this.birthDate = other.BirthDate; 40 | this.hourlyRate = other.GetRate(); 41 | this.CanTellJokes = other.CanTellJokes; 42 | this.Photo = other.Photo; 43 | this.Comments = other.Comments; 44 | this.MaritalStatus = other.MaritalStatus; 45 | } 46 | 47 | [OLVIgnore] 48 | public Image ImageAspect { 49 | get { 50 | return Resource1.folder16; 51 | } 52 | } 53 | 54 | [OLVIgnore] 55 | public string ImageName { 56 | get { 57 | return "user"; 58 | } 59 | } 60 | 61 | // Allows tests for properties. 62 | [OLVColumn(ImageAspectName = "ImageName")] 63 | public string Name { 64 | get { return name; } 65 | set { 66 | if (name == value) return; 67 | name = value; 68 | this.OnPropertyChanged("Name"); 69 | } 70 | } 71 | private string name; 72 | 73 | [OLVColumn(ImageAspectName = "ImageName")] 74 | public string Occupation { 75 | get { return occupation; } 76 | set { 77 | if (occupation == value) return; 78 | occupation = value; 79 | this.OnPropertyChanged("Occupation"); 80 | } 81 | } 82 | private string occupation; 83 | 84 | public int CulinaryRating { 85 | get { return culinaryRating; } 86 | set { culinaryRating = value; } 87 | } 88 | private int culinaryRating; 89 | 90 | public DateTime BirthDate { 91 | get { return birthDate; } 92 | set { birthDate = value; } 93 | } 94 | private DateTime birthDate; 95 | 96 | public int YearOfBirth { 97 | get { return this.BirthDate.Year; } 98 | set { this.BirthDate = new DateTime(value, birthDate.Month, birthDate.Day); } 99 | } 100 | 101 | // Allow tests for methods 102 | public double GetRate() { 103 | return hourlyRate; 104 | } 105 | private double hourlyRate; 106 | 107 | public void SetRate(double value) { 108 | hourlyRate = value; 109 | } 110 | 111 | // Allows tests for fields. 112 | public string Photo; 113 | public string Comments; 114 | public int serialNumber; 115 | public bool? CanTellJokes; 116 | 117 | // Allow tests for enums 118 | public MaritalStatus MaritalStatus = MaritalStatus.Single; 119 | 120 | #region Implementation of INotifyPropertyChanged 121 | 122 | public event PropertyChangedEventHandler PropertyChanged; 123 | 124 | private void OnPropertyChanged(string propertyName) { 125 | if (this.PropertyChanged != null) 126 | this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 127 | } 128 | 129 | #endregion 130 | } 131 | } -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/ak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/ak.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/cp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/cp.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/cr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/cr.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/es.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/es.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/gab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/gab.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/gp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/gp.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/jp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/jp.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/jr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/jr.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/mb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/mb.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/np.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/np.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/ns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/ns.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/sj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/sj.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Photos/sp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Photos/sp.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Information about this assembly is defined by the following 6 | // attributes. 7 | // 8 | // change them to the information which is associated with the assembly 9 | // you compile. 10 | 11 | [assembly: AssemblyTitle("ObjectListViewDemo")] 12 | [assembly: AssemblyDescription("A demonstration of how easy an ObjectListView is to use (and how powerful).")] 13 | [assembly: AssemblyConfiguration("")] 14 | [assembly: AssemblyCompany("Bright Ideas Software")] 15 | [assembly: AssemblyProduct("ObjectListViewDemo")] 16 | [assembly: AssemblyCopyright("Copyright 2006-2020 All Rights Reserved")] 17 | [assembly: AssemblyTrademark("")] 18 | [assembly: AssemblyCulture("")] 19 | 20 | // This sets the default COM visibility of types in the assembly to invisible. 21 | // If you need to expose a type to COM, use [ComVisible(true)] on that type. 22 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resource1.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.1 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 ObjectListViewDemo { 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 Resource1 { 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 Resource1() { 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("ObjectListViewDemo.Resource1", typeof(Resource1).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 | internal static System.Drawing.Bitmap down16 { 64 | get { 65 | object obj = ResourceManager.GetObject("down16", resourceCulture); 66 | return ((System.Drawing.Bitmap)(obj)); 67 | } 68 | } 69 | 70 | internal static System.Drawing.Bitmap folder16 { 71 | get { 72 | object obj = ResourceManager.GetObject("folder16", resourceCulture); 73 | return ((System.Drawing.Bitmap)(obj)); 74 | } 75 | } 76 | 77 | internal static System.Drawing.Bitmap largestar { 78 | get { 79 | object obj = ResourceManager.GetObject("largestar", resourceCulture); 80 | return ((System.Drawing.Bitmap)(obj)); 81 | } 82 | } 83 | 84 | internal static System.Drawing.Bitmap limeleaf { 85 | get { 86 | object obj = ResourceManager.GetObject("limeleaf", resourceCulture); 87 | return ((System.Drawing.Bitmap)(obj)); 88 | } 89 | } 90 | 91 | internal static System.Drawing.Bitmap loveheart { 92 | get { 93 | object obj = ResourceManager.GetObject("loveheart", resourceCulture); 94 | return ((System.Drawing.Bitmap)(obj)); 95 | } 96 | } 97 | 98 | internal static System.Drawing.Bitmap movie16 { 99 | get { 100 | object obj = ResourceManager.GetObject("movie16", resourceCulture); 101 | return ((System.Drawing.Bitmap)(obj)); 102 | } 103 | } 104 | 105 | internal static System.Drawing.Bitmap music16 { 106 | get { 107 | object obj = ResourceManager.GetObject("music16", resourceCulture); 108 | return ((System.Drawing.Bitmap)(obj)); 109 | } 110 | } 111 | 112 | internal static System.Drawing.Bitmap redback1 { 113 | get { 114 | object obj = ResourceManager.GetObject("redback1", resourceCulture); 115 | return ((System.Drawing.Bitmap)(obj)); 116 | } 117 | } 118 | 119 | internal static System.Drawing.Bitmap redbull { 120 | get { 121 | object obj = ResourceManager.GetObject("redbull", resourceCulture); 122 | return ((System.Drawing.Bitmap)(obj)); 123 | } 124 | } 125 | 126 | internal static System.Drawing.Bitmap star16 { 127 | get { 128 | object obj = ResourceManager.GetObject("star16", resourceCulture); 129 | return ((System.Drawing.Bitmap)(obj)); 130 | } 131 | } 132 | 133 | internal static System.Drawing.Bitmap star32 { 134 | get { 135 | object obj = ResourceManager.GetObject("star32", resourceCulture); 136 | return ((System.Drawing.Bitmap)(obj)); 137 | } 138 | } 139 | 140 | internal static System.Drawing.Bitmap tick16 { 141 | get { 142 | object obj = ResourceManager.GetObject("tick16", resourceCulture); 143 | return ((System.Drawing.Bitmap)(obj)); 144 | } 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/Espresso Maker.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/Espresso Maker.ico -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/coffee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/coffee.jpg -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/down16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/down16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/fav32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/fav32.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/folder16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/folder16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/goldstar3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/goldstar3.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/goldstart-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/goldstart-32.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/limeleaf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/limeleaf.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/movie16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/movie16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/music16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/music16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/redback1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/redback1.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/redbull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/redbull.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/star16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/star16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/Resources/tick16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ennerperez/ObjectListView/214eef0a38d041a55a0031dce154398ebcc0a9d2/src/ObjectListViewDemo/Resources/tick16.png -------------------------------------------------------------------------------- /src/ObjectListViewDemo/TabDataTreeListView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using System.Windows.Forms; 4 | using BrightIdeasSoftware; 5 | 6 | namespace ObjectListViewDemo 7 | { 8 | public partial class TabDataTreeListView : OlvDemoTab { 9 | 10 | public TabDataTreeListView() 11 | { 12 | InitializeComponent(); 13 | this.ListView = this.olvDataTree; 14 | } 15 | 16 | protected override void InitializeTab() { 17 | 18 | // The whole point of a DataTreeListView is to write no code. So there is very little code here. 19 | 20 | // Put some images against each row 21 | this.olvColumn41.ImageGetter = delegate(object row) { return "user"; }; 22 | 23 | // The DataTreeListView needs to know the key that identifies root level objects. 24 | // DataTreeListView can handle that key being any data type, but the Designer only deals in strings. 25 | // Since we want a non-string value to identify keys, we have to set it explicitly here. 26 | this.olvDataTree.RootKeyValue = 0u; 27 | 28 | // Finally load the data into the UI 29 | LoadXmlIntoTreeDataListView(); 30 | 31 | // This does a better job of auto sizing the columns 32 | this.olvDataTree.AutoResizeColumns(); 33 | } 34 | 35 | private void LoadXmlIntoTreeDataListView() { 36 | DataSet ds = Coordinator.LoadDatasetFromXml(@"Data\FamilyTree.xml"); 37 | 38 | if (ds.Tables.Count <= 0) { 39 | Coordinator.ShowMessage(@"Failed to load data set from Data\FamilyTree.xml"); 40 | return; 41 | } 42 | 43 | this.dataGridView2.DataSource = ds; 44 | this.dataGridView2.DataMember = "Person"; 45 | 46 | // Like DataListView, the DataTreeListView can handle binding to a variety of sources 47 | // And again, you could create a BindingSource in the designer, and assign that BindingSource 48 | // to DataSource, removing the need to even write these few lines of code. 49 | 50 | //this.olvDataTree.DataSource = new BindingSource(ds, "Person"); 51 | //this.olvDataTree.DataSource = ds.Tables["Person"]; 52 | //this.olvDataTree.DataSource = new DataView(ds.Tables["Person"]); 53 | //this.olvDataTree.DataMember = "Person"; this.olvDataTree.DataSource = ds; 54 | this.olvDataTree.DataMember = "Person"; 55 | this.olvDataTree.DataSource = new DataViewManager(ds); 56 | } 57 | 58 | #region UI event handlers 59 | 60 | private void filterTextBox_TextChanged(object sender, EventArgs e) 61 | { 62 | Coordinator.TimedFilter(this.ListView, ((TextBox)sender).Text); 63 | } 64 | 65 | private void buttonResetData_Click(object sender, EventArgs e) 66 | { 67 | LoadXmlIntoTreeDataListView(); 68 | } 69 | 70 | #endregion 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/TabDataTreeListView.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | The TreeDataListView is a data bound TreeListView. The hierarchy is constructed from information in the data source. Each row needs a unique key (in this case, "Id" column), plus a column that identifies the parent in the hierarchy (in this case, "ParentId" column). Because of its general nature, this control cannot be fast. Don't try to use it on large datasets. 122 | 123 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/TabDragAndDrop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using BrightIdeasSoftware; 4 | using ObjectListViewDemo.Properties; 5 | 6 | namespace ObjectListViewDemo 7 | { 8 | public partial class TabDragAndDrop : OlvDemoTab 9 | { 10 | public TabDragAndDrop() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | protected override void InitializeTab() { 16 | 17 | SetupColumns(); 18 | SetupDragAndDrop(); 19 | 20 | this.comboBoxGeeksAndTweebsView.SelectedIndex = 4; 21 | this.comboBoxCoolFroodsView.SelectedIndex = 4; 22 | 23 | this.olvGeeks.SetObjects(Coordinator.PersonList); 24 | } 25 | 26 | private void SetupColumns() { 27 | this.olvGeeks.GetColumn(0).ImageGetter = delegate(object x) { return "user"; }; 28 | this.olvFroods.GetColumn(0).ImageGetter = delegate(object x) { return "user"; }; 29 | 30 | this.olvGeeks.GetColumn(2).Renderer = new MultiImageRenderer(Resource1.star16, 5, 0, 40); 31 | this.olvFroods.GetColumn(2).Renderer = new MultiImageRenderer(Resource1.star16, 5, 0, 40); 32 | } 33 | 34 | private void SetupDragAndDrop() { 35 | 36 | // Make each listview capable of dragging rows out 37 | this.olvGeeks.DragSource = new SimpleDragSource(); 38 | this.olvFroods.DragSource = new SimpleDragSource(); 39 | 40 | // Make each listview capable of accepting drops. 41 | // More than that, make it so it's items can be rearranged 42 | this.olvGeeks.DropSink = new RearrangingDropSink(true); 43 | this.olvFroods.DropSink = new RearrangingDropSink(true); 44 | 45 | // For a normal drag and drop situation, you will need to create a SimpleDropSink 46 | // and then listen for ModelCanDrop and ModelDropped events 47 | } 48 | 49 | #region UI event handlers 50 | 51 | private void comboBoxGeeksAndTweebsView_SelectedIndexChanged(object sender, EventArgs e) 52 | { 53 | Coordinator.ChangeView(this.olvGeeks, (ComboBox)sender); 54 | } 55 | 56 | private void comboBoxCoolFroodsView_SelectedIndexChanged(object sender, EventArgs e) 57 | { 58 | Coordinator.ChangeView(this.olvFroods, (ComboBox)sender); 59 | } 60 | 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/TabPrinting.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | The ListViewPrinter class makes printing a ListView ridiciously easy. The format of the report can be easily customised: the styles Minimal, Modern and Too Much! are just some examples. N.B The preview below is not a full print previewer -- it only shows the first two pages of the report. 122 | 123 | 124 | 17, 17 125 | 126 | -------------------------------------------------------------------------------- /src/ObjectListViewDemo/TabSimpleExample.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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | This list view shows what is possible using only the IDE. Each column has been told which aspect to display, plus: Birthday and Hourly Rate columns have format strings; Person and Occupation columns have minimum and maximum widths; Year of birth column is fixed width; Comments is a space filler. The Comments header shows a tool tip. All of this configuration, even the overlay image, was done within the IDE. 122 | 123 | -------------------------------------------------------------------------------- /src/SparkleLibrary.NetCore/SparkleLibrary.NetCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | false 6 | BrightIdeasSoftware 7 | SparkleLibrary 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/SparkleLibrary/Animation/Animateable.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Animateable - A item that can be placed in an animation 3 | * 4 | * Author: Phillip Piper 5 | * Date: 23/10/2009 10:39 PM 6 | * 7 | * Change log: 8 | * 2009-10-23 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2009 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Collections.Generic; 32 | 33 | namespace BrightIdeasSoftware 34 | { 35 | public interface IAnimateable 36 | { 37 | /// 38 | /// Gets or sets the animation that this component belongs to 39 | /// 40 | Animation Animation { get; set; } 41 | 42 | /// 43 | /// This component is being started. It should acquire any resources that it needs 44 | /// 45 | void Start(); 46 | 47 | /// 48 | /// A unit of time has passed and the animation component should advance its state 49 | /// if sufficient time has passed. 50 | /// 51 | /// The number of milliseconds since Start() was called. 52 | /// True if Tick() should be called again 53 | bool Tick(long elapsed); 54 | 55 | /// 56 | /// Revert this component to its initial state. 57 | /// 58 | void Reset(); 59 | 60 | /// 61 | /// This component has been stopped. It should release any resources acquired in Start(). 62 | /// 63 | void Stop(); 64 | } 65 | 66 | /// 67 | /// A Animateable is the base class for any item that can be 68 | /// placed within an Animation. 69 | /// 70 | public class Animateable : IAnimateable 71 | { 72 | /// 73 | /// Gets or sets the animation that this component belongs to 74 | /// 75 | public Animation Animation { 76 | get { return animation; } 77 | set { animation = value; } 78 | } 79 | private Animation animation; 80 | 81 | /// 82 | /// This component is being started. It should acquire any resources that it needs 83 | /// 84 | public virtual void Start() { 85 | } 86 | 87 | /// 88 | /// A unit of time has passed and the animation component should advance its state 89 | /// if sufficient time has passed. 90 | /// 91 | /// The number of milliseconds since Start() was called. 92 | /// True if Tick() should be called again 93 | public virtual bool Tick(long elapsed) { 94 | return false; 95 | } 96 | 97 | /// 98 | /// Revert this component to its initial state. 99 | /// 100 | public virtual void Reset() { 101 | } 102 | 103 | /// 104 | /// This component has been stopped. It should release any resources acquired in Start(). 105 | /// 106 | public virtual void Stop() { 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/SparkleLibrary/Animation/Events.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Events - All events triggerable by an animation 3 | * 4 | * Author: Phillip Piper 5 | * Date: 8/02/2010 17:35 6 | * 7 | * Change log: 8 | * 2010-02-08 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2010 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Collections.Generic; 32 | using System.Drawing; 33 | using System.ComponentModel; 34 | using System.Windows.Forms; 35 | 36 | namespace BrightIdeasSoftware 37 | { 38 | public class StartAnimationEventArgs : EventArgs 39 | { 40 | } 41 | 42 | public class TickEventArgs : EventArgs 43 | { 44 | /// 45 | /// Gets or sets if the tick event was completely handled 46 | /// 47 | public bool Handled; 48 | } 49 | 50 | public class RedrawEventArgs : EventArgs 51 | { 52 | public RedrawEventArgs() { 53 | this.Damage = new Rectangle(-100000, -100000, 200000, 200000); 54 | } 55 | 56 | public RedrawEventArgs(Rectangle r) { 57 | this.Damage = r; 58 | } 59 | 60 | /// 61 | /// Gets the area of the animation that was damaged 62 | /// 63 | public Rectangle Damage; 64 | } 65 | 66 | public class StopAnimationEventArgs : EventArgs 67 | { 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/SparkleLibrary/Locators/RectangleLocator.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * RectangleLocator - Generalized mechanism to calculate rectangles 3 | * 4 | * Author: Phillip Piper 5 | * Date: 18/01/2010 5:48 PM 6 | * 7 | * Change log: 8 | * 2010-01-18 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2009 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System.Drawing; 31 | 32 | namespace BrightIdeasSoftware 33 | { 34 | /// 35 | /// A IRectangleLocator calculates a rectangle 36 | /// 37 | public interface IRectangleLocator 38 | { 39 | ISprite Sprite { get; set; } 40 | Rectangle GetRectangle(); 41 | } 42 | 43 | /// 44 | /// A safe do-nothing implementation of IRectangleLocator plus some useful utilities 45 | /// 46 | public class AbstractRectangleLocator : IRectangleLocator 47 | { 48 | #region Properties 49 | 50 | public Point Expansion ; 51 | 52 | public ISprite Sprite { 53 | get { return this.sprite; } 54 | set { 55 | this.sprite = value; 56 | this.InitializeSublocators(); 57 | } 58 | } 59 | private ISprite sprite; 60 | 61 | #endregion 62 | 63 | #region Public interface 64 | 65 | public virtual Rectangle GetRectangle() { 66 | return Rectangle.Empty; 67 | } 68 | 69 | #endregion 70 | 71 | #region Utilities 72 | 73 | protected Rectangle Expand(Rectangle r) { 74 | if (this.Expansion == Point.Empty) 75 | return r; 76 | 77 | Rectangle r2 = r; 78 | r2.Inflate(this.Expansion.X, this.Expansion.Y); 79 | return r2; 80 | } 81 | 82 | /// 83 | /// The sprite associate with this locator has changed. 84 | /// Make sure any dependent locators are updated 85 | /// 86 | protected virtual void InitializeSublocators() { 87 | } 88 | 89 | protected void InitializeLocator(IPointLocator locator) { 90 | if (locator != null && locator.Sprite == null) 91 | locator.Sprite = this.Sprite; 92 | } 93 | 94 | protected void InitializeLocator(IRectangleLocator locator) { 95 | if (locator != null && locator.Sprite == null) 96 | locator.Sprite = this.Sprite; 97 | } 98 | 99 | #endregion 100 | } 101 | 102 | /// 103 | /// A SpritePointLocator calculates a point relative to 104 | /// the reference bound of sprite. 105 | /// 106 | public class SpriteBoundsLocator : AbstractRectangleLocator 107 | { 108 | public SpriteBoundsLocator() { 109 | } 110 | 111 | public SpriteBoundsLocator(ISprite sprite) { 112 | this.Sprite = sprite; 113 | } 114 | 115 | public SpriteBoundsLocator(int expandX, int expandY) { 116 | this.Expansion = new Point(expandX, expandY); 117 | } 118 | 119 | public override Rectangle GetRectangle() { 120 | return this.Expand(this.Sprite.Bounds); 121 | } 122 | } 123 | 124 | /// 125 | /// A AnimationBoundsLocator calculates a point 126 | /// on the bounds of whole animation. 127 | /// 128 | public class AnimationBoundsLocator : AbstractRectangleLocator 129 | { 130 | public AnimationBoundsLocator() { 131 | } 132 | 133 | public AnimationBoundsLocator(int expandX, int expandY) { 134 | this.Expansion = new Point(expandX, expandY); 135 | } 136 | 137 | public override Rectangle GetRectangle() { 138 | return this.Expand(this.Sprite.OuterBounds); 139 | } 140 | } 141 | 142 | /// 143 | /// A RectangleFromCornersLocator calculates its rectangle through two point locators, 144 | /// one for the top left, the other for the bottom right. The rectangle 145 | /// can also be expanded by a fixed amount. 146 | /// 147 | public class RectangleFromCornersLocator : AbstractRectangleLocator 148 | { 149 | #region Life and death 150 | 151 | public RectangleFromCornersLocator(IPointLocator topLeftLocator, IPointLocator bottomRightLocator) : 152 | this(topLeftLocator, bottomRightLocator, Point.Empty) { 153 | } 154 | 155 | public RectangleFromCornersLocator(IPointLocator topLeftLocator, IPointLocator bottomRightLocator, Point expand) { 156 | this.TopLeftLocator = topLeftLocator; 157 | this.BottomRightLocator = bottomRightLocator; 158 | this.Expansion = expand; 159 | } 160 | 161 | #endregion 162 | 163 | #region Configuration properties 164 | 165 | protected IPointLocator TopLeftLocator ; 166 | protected IPointLocator BottomRightLocator ; 167 | 168 | #endregion 169 | 170 | #region Public methods 171 | 172 | public override Rectangle GetRectangle() { 173 | Point topLeft = this.TopLeftLocator.GetPoint(); 174 | Point bottomRight = this.BottomRightLocator.GetPoint(); 175 | return this.Expand(Rectangle.FromLTRB(topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y)); 176 | } 177 | 178 | #endregion 179 | 180 | protected override void InitializeSublocators() { 181 | this.InitializeLocator(this.TopLeftLocator); 182 | this.InitializeLocator(this.BottomRightLocator); 183 | } 184 | } 185 | 186 | /// 187 | /// A FixedRectangleLocator simply returns the rectangle with which it was initialized 188 | /// 189 | public class FixedRectangleLocator : AbstractRectangleLocator 190 | { 191 | public FixedRectangleLocator(Rectangle r) { 192 | this.Rectangle = r; 193 | } 194 | 195 | public FixedRectangleLocator(int x, int y, int width, int height) { 196 | this.Rectangle = new Rectangle(x, y, width, height); 197 | } 198 | 199 | protected Rectangle Rectangle ; 200 | 201 | public override Rectangle GetRectangle() { 202 | return this.Expand(this.Rectangle); 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/SparkleLibrary/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("Sparkle Library")] 9 | [assembly: AssemblyDescription("An animation library to add some sparkly eye candy to an application")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Bright Ideas Software")] 12 | [assembly: AssemblyProduct("SparkleLibrary")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 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("6bc11313-3880-41ce-94af-39b60ab4ef33")] -------------------------------------------------------------------------------- /src/SparkleLibrary/SparkleLibrary.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D304B8BF-0D7A-4CDD-A50B-7FCD9A437496} 8 | Library 9 | Properties 10 | BrightIdeasSoftware 11 | SparkleLibrary 12 | v4.0 13 | 512 14 | false 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Properties\AssemblyInfo.Version.cs 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/SparkleLibrary/Sprites/Audio.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Audio - Audio allows sound to be played during a animation. 3 | * 4 | * Author: Phillip Piper 5 | * Date: 18/01/2010 5:29 PM 6 | * 7 | * Change log: 8 | * 2010-01-18 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2010 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Collections.Generic; 32 | using System.Media; 33 | using System.IO; 34 | using System.Reflection; 35 | using System.Threading; 36 | 37 | namespace BrightIdeasSoftware 38 | { 39 | /// 40 | /// Instances of this class allow sound to be played at specified 41 | /// points within a animation. 42 | /// 43 | /// 44 | /// 45 | /// This class uses the SoundPlayer class internally, and thus can 46 | /// only handle system sounds and WAV sound files. 47 | /// 48 | /// A sound that is already playing cannot be paused. 49 | /// 50 | public class Audio : Animateable 51 | { 52 | #region Life and death 53 | 54 | /// 55 | /// Load a sound from a named resource. 56 | /// 57 | /// The name of the resource including the trailing ".wav" 58 | /// To embed a wav file, simple add it to the project, and change "Build Action" 59 | /// to "Embedded Resource". 60 | /// 61 | public static Audio FromResource(string resourceName) { 62 | Audio sound = new Audio(); 63 | sound.ResourceName = resourceName; 64 | return sound; 65 | } 66 | 67 | /// 68 | /// Create an empty Audio object 69 | /// 70 | public Audio() { 71 | } 72 | 73 | /// 74 | /// Creates an Audio object that will play the given "wav" file 75 | /// 76 | /// 77 | public Audio(string fileName) { 78 | this.FileName = fileName; 79 | } 80 | 81 | /// 82 | /// Creates an Audio object that will play the given system sound 83 | /// 84 | /// 85 | public Audio(SystemSound sound) { 86 | this.SystemSound = sound; 87 | } 88 | 89 | #endregion 90 | 91 | #region Implementation properties 92 | 93 | /// 94 | /// Gets or sets the name of the audio file that will be played. 95 | /// 96 | protected string FileName ; 97 | protected SoundPlayer Player ; 98 | protected string ResourceName ; 99 | protected SystemSound SystemSound ; 100 | 101 | #endregion 102 | 103 | #region Animation methods 104 | 105 | /// 106 | /// Start the sound playing 107 | /// 108 | public override void Start() { 109 | // If we are supposed to play an application resource, try to load it 110 | if (!String.IsNullOrEmpty(this.ResourceName)) { 111 | Assembly executingAssembly = Assembly.GetExecutingAssembly(); 112 | string assemblyName = executingAssembly.GetName().Name; 113 | Stream stream = executingAssembly.GetManifestResourceStream(assemblyName + "." + this.ResourceName); 114 | if (stream != null) 115 | this.Player = new SoundPlayer(stream); 116 | } 117 | 118 | if (!String.IsNullOrEmpty(this.FileName)) { 119 | this.Player = new SoundPlayer(this.FileName); 120 | } 121 | 122 | // We could just use Play() and let the player handle the threading for us, but: 123 | // - there is no builtin way to know when the sound has finished 124 | // - on XP (at least), using Play() on a Stream gives noise -- but PlaySync() works fine. 125 | 126 | this.done = false; 127 | Thread newThread = new Thread((ThreadStart)delegate { 128 | if (this.SystemSound != null) 129 | this.SystemSound.Play(); 130 | else { 131 | if (this.Player != null) 132 | this.Player.PlaySync(); 133 | } 134 | this.done = true; 135 | }); 136 | newThread.Start(); 137 | } 138 | bool done; 139 | 140 | /// 141 | /// Advance the audio and return if it is done. 142 | /// 143 | /// 144 | /// 145 | public override bool Tick(long elapsed) { 146 | return !this.done; 147 | } 148 | 149 | /// 150 | /// Stop the sound 151 | /// 152 | public override void Stop() { 153 | if (this.SystemSound != null) 154 | return; 155 | 156 | if (this.Player != null) { 157 | this.Player.Stop(); 158 | this.Player.Dispose(); 159 | this.Player = null; 160 | } 161 | } 162 | 163 | #endregion 164 | } 165 | } -------------------------------------------------------------------------------- /src/SparkleLibrary/Sprites/ISprite.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Sprite - A graphic item that can be animated on a animation 3 | * 4 | * Author: Phillip Piper 5 | * Date: 2/3/2010 9:36 AM 6 | * 7 | * Change log: 8 | * 2010-03-02 JPP - Initial version (Separated from Sprite.cs) 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2010 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Collections.Generic; 32 | using System.Drawing; 33 | using System.Drawing.Drawing2D; 34 | using System.Drawing.Imaging; 35 | using System.Windows.Forms; 36 | 37 | namespace BrightIdeasSoftware 38 | { 39 | public interface ISprite : IAnimateable 40 | { 41 | /// 42 | /// Gets or sets where the sprite is located 43 | /// 44 | Point Location { get; set; } 45 | 46 | /// 47 | /// Gets or sets how transparent the sprite is. 48 | /// 0.0 is completely transparent, 1.0 is completely opaque. 49 | /// 50 | float Opacity { get; set; } 51 | 52 | /// 53 | /// Gets or sets the scaling that is applied to the extent of the sprite. 54 | /// The location of the sprite is not scaled. 55 | /// 56 | float Scale { get; set; } 57 | 58 | /// 59 | /// Gets or sets the size of the sprite 60 | /// 61 | Size Size { get; set; } 62 | 63 | /// 64 | /// Gets or sets the angle in degrees of the sprite. 65 | /// 0 means no angle, 90 means right edge lifted vertical. 66 | /// 67 | float Spin { get; set; } 68 | 69 | /// 70 | /// Gets or sets the bounds of the sprite. This is boundary within which 71 | /// the sprite will be drawn. 72 | /// 73 | Rectangle Bounds { get; set; } 74 | 75 | /// 76 | /// Gets the outer bounds of this sprite, which is normally the 77 | /// bounds of the control that is hosting the story board. 78 | /// Nothing outside of this rectangle will be drawn. 79 | /// 80 | Rectangle OuterBounds { get; } 81 | 82 | /// 83 | /// Gets or sets the reference rectangle in relation to which 84 | /// the sprite will be drawn. This is normal the ClientArea of 85 | /// the control that is hosting the story board, though it 86 | /// could be a subarea of that control (e.g. a particular 87 | /// cell within a ListView). 88 | /// 89 | /// This value is controlled by ReferenceBoundsLocator property. 90 | Rectangle ReferenceBounds { get; set; } 91 | 92 | /// 93 | /// Gets or sets the locator that will calculate the reference rectangle 94 | /// for the sprite. 95 | /// 96 | IRectangleLocator ReferenceBoundsLocator { get; set; } 97 | 98 | /// 99 | /// Gets or sets the point at which this sprite will always be placed. 100 | /// 101 | /// 102 | /// Most sprites play with their location as part of their animation. 103 | /// But other just want to stay in the same place. 104 | /// Do not set this if you use Move or Goto effects on the sprite. 105 | /// 106 | IPointLocator FixedLocation { get; set; } 107 | 108 | /// 109 | /// Gets or sets the bounds at which this sprite will always be placed. 110 | /// 111 | /// See remarks on FixedLocation 112 | IRectangleLocator FixedBounds { get; set; } 113 | 114 | /// 115 | /// Draw the sprite in its current state 116 | /// 117 | /// 118 | void Draw(Graphics g); 119 | 120 | /// 121 | /// Add an Effect to this sprite. This effect will run at the beginning of 122 | /// the sprite and will have 0 duration. 123 | /// 124 | /// The effect to be applied to the sprite 125 | void Add(IEffect effect); 126 | 127 | /// 128 | /// Add an Effect to this sprite. This effect will commences startTick's 129 | /// after the sprite begins and will have 0 duration 130 | /// 131 | /// When will the effect begins? 132 | /// What effect will be applied? 133 | void Add(long startTick, IEffect effect); 134 | 135 | /// 136 | /// The main entry point for adding effects to Sprites. 137 | /// 138 | /// When will the effect begin? 139 | /// For how long will it last? 140 | /// What effect will be applied? 141 | void Add(long startTick, long duration, IEffect effect); 142 | } 143 | } -------------------------------------------------------------------------------- /src/SparkleLibrary/Sprites/ImageSprite.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * ImageSprite - A sprite that draws an Image 3 | * 4 | * Author: Phillip Piper 5 | * Date: 08/02/2010 6:18 PM 6 | * 7 | * Change log: 8 | * 2010-02-08 JPP - Initial version 9 | * 10 | * To do: 11 | * 12 | * Copyright (C) 2010 Phillip Piper 13 | * 14 | * This program is free software: you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation, either version 3 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program. If not, see . 26 | * 27 | * If you wish to use this code in a closed source application, please contact phillip.piper@gmail.com. 28 | */ 29 | 30 | using System; 31 | using System.Collections.Generic; 32 | using System.Drawing; 33 | using System.Drawing.Drawing2D; 34 | using System.Drawing.Imaging; 35 | using System.Windows.Forms; 36 | 37 | namespace BrightIdeasSoftware 38 | { 39 | /// 40 | /// An ImageSprite draws an image onto the animation, to which animations can be applied 41 | /// 42 | /// The image can even be an animated GIF! 43 | public class ImageSprite : Sprite 44 | { 45 | #region Life and death 46 | 47 | public ImageSprite(Image image) { 48 | this.Image = image; 49 | } 50 | 51 | #endregion 52 | 53 | #region Implementation properties 54 | 55 | protected Image Image ; 56 | 57 | #endregion 58 | 59 | #region Sprite properties 60 | 61 | /// 62 | /// Gets or sets how big the image is 63 | /// 64 | /// The image size cannot be set, since it is natural size multiplied by 65 | /// the Scale property. 66 | public override Size Size { 67 | get { 68 | if (this.Image == null) 69 | return Size.Empty; 70 | 71 | // Internal the Image class cannot handle being accessed by multiple threads 72 | // at the same time. So make sure the access is serialized. 73 | lock (this.locker) { 74 | if (this.Scale == 1.0f) 75 | return this.Image.Size; 76 | else 77 | return new Size((int)(this.Image.Size.Width * this.Scale), 78 | (int)(this.Image.Size.Height * this.Scale)); 79 | } 80 | } 81 | set { 82 | } 83 | } 84 | 85 | #endregion 86 | 87 | #region Sprite methods 88 | 89 | public override void Start() { 90 | if (this.Image != null && ImageAnimator.CanAnimate(this.Image)) { 91 | isAnimatedImage = true; 92 | ImageAnimator.Animate(this.Image, this.OnFrameChanged); 93 | } 94 | } 95 | bool isAnimatedImage; 96 | 97 | public override void Stop() { 98 | if (this.isAnimatedImage) 99 | ImageAnimator.StopAnimate(this.Image, this.OnFrameChanged); 100 | } 101 | 102 | public override void Draw(Graphics g) { 103 | this.ApplyState(g); 104 | lock (this.locker) { 105 | if (this.Image != null) { 106 | if (this.isAnimatedImage) 107 | ImageAnimator.UpdateFrames(this.Image); 108 | 109 | this.DrawTransparentBitmap(g, this.Bounds, this.Image, this.Opacity); 110 | } 111 | this.UnapplyState(g); 112 | } 113 | } 114 | 115 | private Object locker = new object(); 116 | 117 | #endregion 118 | 119 | #region Implementation methods 120 | 121 | /// 122 | /// The frame on an animated GIF has changed. Normally we would redraw, but 123 | /// we leave that to the animation controller. 124 | /// 125 | /// 126 | /// 127 | private void OnFrameChanged(object o, EventArgs e) { 128 | } 129 | 130 | /// 131 | /// Draw an image in a (possibilty) transluscent fashion 132 | /// 133 | /// 134 | /// 135 | /// 136 | /// 137 | protected void DrawTransparentBitmap(Graphics g, Rectangle r, Image image, float transparency) { 138 | if (transparency <= 0.0f) 139 | return; 140 | 141 | ImageAttributes imageAttributes = null; 142 | if (transparency < 1.0f) { 143 | imageAttributes = new ImageAttributes(); 144 | float[][] colorMatrixElements = { 145 | new float[] {1, 0, 0, 0, 0}, 146 | new float[] {0, 1, 0, 0, 0}, 147 | new float[] {0, 0, 1, 0, 0}, 148 | new float[] {0, 0, 0, transparency, 0}, 149 | new float[] {0, 0, 0, 0, 1}}; 150 | 151 | imageAttributes.SetColorMatrix(new ColorMatrix(colorMatrixElements)); 152 | } 153 | 154 | Rectangle dest = new Rectangle(Point.Empty, this.Size); 155 | g.DrawImage(image, 156 | dest, // destination rectangle 157 | 0, 0, image.Size.Width, image.Size.Height, // source rectangle 158 | GraphicsUnit.Pixel, 159 | imageAttributes); 160 | } 161 | 162 | #endregion 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /tools/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------