├── .gitattributes ├── .gitignore ├── DataGridExtensions.Tests ├── DataGridExtensions.Tests.csproj ├── DataGridExtensionsTests.cs ├── Models │ └── ContactInfoModel.cs └── Properties │ └── AssemblyInfo.cs ├── DataGridViewExtensions.sln ├── DataGridViewExtensions ├── DataGridExtensions.cs ├── DataGridViewExtensions.csproj └── Properties │ └── AssemblyInfo.cs └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ 246 | /DataGridViewAssistant/ 247 | -------------------------------------------------------------------------------- /DataGridExtensions.Tests/DataGridExtensions.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02} 7 | Library 8 | Properties 9 | DataGridExtensions.Tests 10 | DataGridExtensions.Tests 11 | v4.5.2 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {7f506848-f713-4021-9768-b810b160d7d5} 63 | DataGridViewExtensions 64 | 65 | 66 | 67 | 68 | 69 | 70 | False 71 | 72 | 73 | False 74 | 75 | 76 | False 77 | 78 | 79 | False 80 | 81 | 82 | 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /DataGridExtensions.Tests/DataGridExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using System.Windows.Forms; 3 | using System.Data; 4 | using DataGridViewExtensions; 5 | using System.Linq; 6 | using System.Drawing; 7 | using DataGridExtensions.Tests.Models; 8 | using System.Collections.Generic; 9 | using System; 10 | 11 | namespace DataGridExtensions.Tests 12 | { 13 | [TestClass] 14 | public class DataGridExtensionsTests 15 | { 16 | private DataGridView _dataGridView; 17 | 18 | [TestInitialize] 19 | public void Setup() 20 | { 21 | _dataGridView = new DataGridView(); 22 | var dataTable = SetupDataTable(); 23 | AddDataTableToDataGrid(dataTable); 24 | } 25 | 26 | [TestMethod] 27 | public void FindRows_Successfully_Find_Data_Rows() 28 | { 29 | var dataRowsSearched = _dataGridView.FindRows(x => x.Value.ToString() == "Grant"); 30 | 31 | Assert.IsTrue(dataRowsSearched.Count() == 1); 32 | } 33 | 34 | [TestMethod] 35 | public void UpdateCells_Successfully_Update_Cells_In_Data_Grid() 36 | { 37 | _dataGridView.UpdateCells(x => x.Value.ToString() == "test@email.com", "ggtgivens24@gmail.com"); 38 | var dataRowsSearched = _dataGridView.FindRows(x => x.Value.ToString() == "ggtgivens24@gmail.com"); 39 | 40 | Assert.IsTrue(dataRowsSearched.Count() == 1); 41 | } 42 | 43 | [TestMethod] 44 | public void RemoveRows_Successfully_Remove_Rows_By_Cell_Value() 45 | { 46 | _dataGridView.RemoveRows(x => x.Value.ToString() == "test@email.com"); 47 | var dataRowsSearched = _dataGridView.FindRows(x => x.Value.ToString() == "ggtgivens24@gmail.com"); 48 | 49 | Assert.IsTrue(!dataRowsSearched.Any()); 50 | } 51 | 52 | [TestMethod] 53 | public void FormtCells_Successfully_Format_Cells_In_Data_Grid() 54 | { 55 | _dataGridView.FormatCells(x => x.Value.ToString() == "test@email.com", Color.White, Color.Red); 56 | var dataRowsSearched = _dataGridView.FindRows(x => x.Value.ToString() == "test@email.com"); 57 | 58 | var testEmailCellRow = dataRowsSearched.FirstOrDefault(); 59 | 60 | Assert.IsTrue(testEmailCellRow != null && 61 | testEmailCellRow.Cells != null && 62 | testEmailCellRow.Cells[3] != null && 63 | testEmailCellRow.Cells[3].Style.BackColor == Color.Red && 64 | testEmailCellRow.Cells[3].Style.ForeColor == Color.White); 65 | } 66 | 67 | [TestMethod] 68 | public void BindData_Successfully_Bind_Generic_Data_To_Data_Grid() 69 | { 70 | var contactInfo = SetupContactInfo(); 71 | var dataGrid = new DataGridView(); 72 | dataGrid.BindData(contactInfo); 73 | var dataRowsSearched = dataGrid.FindRows(x => x.Value.ToString() == "(952) 564-1170"); 74 | 75 | Assert.IsTrue(dataRowsSearched.Count() == 1); 76 | } 77 | 78 | private DataTable SetupDataTable() 79 | { 80 | var dataTable = new DataTable(); 81 | dataTable.Columns.Add("First Name"); 82 | dataTable.Columns.Add("Last Name"); 83 | dataTable.Columns.Add("Phone Number"); 84 | dataTable.Columns.Add("Email"); 85 | 86 | var firstDataRow = dataTable.NewRow(); 87 | firstDataRow[0] = "Grant"; 88 | firstDataRow[1] = "Taylor"; 89 | firstDataRow[2] = "(763) 413-6221"; 90 | firstDataRow[3] = "test@email.com"; 91 | 92 | var secondDataRow = dataTable.NewRow(); 93 | secondDataRow[0] = "John"; 94 | secondDataRow[1] = "Doe"; 95 | secondDataRow[2] = "(952) 890-0215"; 96 | secondDataRow[3] = "test24@email.com"; 97 | 98 | dataTable.Rows.Add(firstDataRow); 99 | dataTable.Rows.Add(secondDataRow); 100 | 101 | return dataTable; 102 | } 103 | 104 | private void AddDataTableToDataGrid(DataTable dataTable) 105 | { 106 | dataTable.Columns.Cast().ToList().ForEach(x => 107 | { 108 | _dataGridView.Columns.Add(x.ColumnName, x.ColumnName); 109 | }); 110 | 111 | _dataGridView.Rows.Add(dataTable.Rows.Count); 112 | var rowIndex = 0; 113 | dataTable.Rows.Cast().ToList().ForEach(x => 114 | { 115 | var columnIndex = 0; 116 | x.ItemArray.ToList().ForEach(cell => 117 | { 118 | _dataGridView.Rows[rowIndex].Cells[columnIndex].Value = x[columnIndex].ToString(); 119 | columnIndex++; 120 | }); 121 | 122 | rowIndex++; 123 | }); 124 | } 125 | 126 | private IEnumerable SetupContactInfo() 127 | { 128 | return new List 129 | { 130 | new ContactInfoModel 131 | { 132 | Id = Guid.NewGuid(), 133 | FirstName = "John", 134 | LastName = "Doe", 135 | Age = DateTime.Now.Year - new DateTime(1991, 9, 2).Year, 136 | DateOfBirth = new DateTime(1991, 9, 2), 137 | PhoneNumber = "(952) 564-1170", 138 | Email = "test@email.com" 139 | }, 140 | new ContactInfoModel 141 | { 142 | Id = Guid.NewGuid(), 143 | FirstName = "Jane", 144 | LastName = "Doe", 145 | Age = DateTime.Now.Year - new DateTime(1990, 8, 5).Year, 146 | DateOfBirth = new DateTime(1990, 8, 5), 147 | PhoneNumber = "(952) 564-2173", 148 | Email = "test24@email.com" 149 | } 150 | }; 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /DataGridExtensions.Tests/Models/ContactInfoModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace DataGridExtensions.Tests.Models 5 | { 6 | public class ContactInfoModel 7 | { 8 | public Guid Id { get; set; } 9 | [Description("First Name")] 10 | public string FirstName { get; set; } 11 | [Description("Last Name")] 12 | public string LastName { get; set; } 13 | [Description("Phone Number")] 14 | public string PhoneNumber { get; set; } 15 | [Description("Date of Birth")] 16 | public DateTime DateOfBirth { get; set; } 17 | public int Age { get; set; } 18 | public string Email { get; set; } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /DataGridExtensions.Tests/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("DataGridExtensions.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DataGridExtensions.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 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("b2dbbffd-b7c9-499f-bea0-e2c97ade8d02")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DataGridViewExtensions.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataGridViewExtensions", "DataGridViewExtensions\DataGridViewExtensions.csproj", "{7F506848-F713-4021-9768-B810B160D7D5}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{1E0305E6-D7DC-4181-9A24-FB1E65C492CA}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataGridExtensions.Tests", "DataGridExtensions.Tests\DataGridExtensions.Tests.csproj", "{B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {7F506848-F713-4021-9768-B810B160D7D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {7F506848-F713-4021-9768-B810B160D7D5}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {7F506848-F713-4021-9768-B810B160D7D5}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {7F506848-F713-4021-9768-B810B160D7D5}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02}.Release|Any CPU.Build.0 = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | GlobalSection(NestedProjects) = preSolution 31 | {B2DBBFFD-B7C9-499F-BEA0-E2C97ADE8D02} = {1E0305E6-D7DC-4181-9A24-FB1E65C492CA} 32 | EndGlobalSection 33 | EndGlobal 34 | -------------------------------------------------------------------------------- /DataGridViewExtensions/DataGridExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | 9 | namespace DataGridViewExtensions 10 | { 11 | public static class DataGridExtensions 12 | { 13 | /// 14 | /// Retunrs a collection of data rows from a data grid view based on the specific data grid cell where clause. 15 | /// 16 | /// The data grid view being searched 17 | /// Where clause used to search data rows by cell values 18 | /// A collection of data grid rows 19 | public static IEnumerable FindRows(this DataGridView dataGridView, Func whereExpression) 20 | { 21 | var dataRowsFound = new List(); 22 | dataGridView.Rows.Cast().ToList().ForEach(x => 23 | { 24 | if (x != null && x.Cells != null) 25 | { 26 | var cells = x.Cells.Cast().Where(cell => cell.Value != null) 27 | .Where(whereExpression); 28 | if (cells.Any()) 29 | { 30 | dataRowsFound.Add(x); 31 | } 32 | } 33 | }); 34 | 35 | return dataRowsFound; 36 | } 37 | 38 | /// 39 | /// Updates cells value in a grid based on a specific where clause and an update value. 40 | /// 41 | /// The data grid to update 42 | /// Where clause used to search data cells 43 | /// Update value for collection of cells 44 | public static void UpdateCells(this DataGridView dataGridView, Func whereExpression, object value) 45 | { 46 | dataGridView.Rows.Cast().ToList().ForEach(x => 47 | { 48 | if (x != null && x.Cells != null) 49 | { 50 | var cells = x.Cells.Cast().Where(cell => cell.Value != null) 51 | .Where(whereExpression); 52 | if (cells.Any()) 53 | { 54 | cells.ToList().ForEach(cell => 55 | { 56 | cell.Value = value; 57 | }); 58 | } 59 | } 60 | }); 61 | } 62 | 63 | /// 64 | /// Removes rows from a data grid based on a specific data grid cell where clause. 65 | /// 66 | /// The data grid to be updated 67 | /// Where clause used to search data cells 68 | public static void RemoveRows(this DataGridView dataGridView, Func whereExpression) 69 | { 70 | var rowsFound = dataGridView.FindRows(whereExpression); 71 | if (rowsFound.Any()) 72 | { 73 | rowsFound.ToList().ForEach(row => 74 | { 75 | dataGridView.Rows.RemoveAt(row.Index); 76 | }); 77 | } 78 | } 79 | 80 | /// 81 | /// Sets the font and background color for a data grid's cells based on a specific where clause. 82 | /// 83 | /// The data grid to format 84 | /// Where caluse used to locate the cells for formatting 85 | /// Font color for cells 86 | /// Background color for cells 87 | public static void FormatCells(this DataGridView dataGridView, Func whereExpression, System.Drawing.Color foreColor, System.Drawing.Color backColor) 88 | { 89 | dataGridView.Rows.Cast().ToList().ForEach(x => 90 | { 91 | if (x != null && x.Cells != null) 92 | { 93 | var cells = x.Cells.Cast().Where(cell => cell.Value != null) 94 | .Where(whereExpression); 95 | if (cells.Any()) 96 | { 97 | cells.ToList().ForEach(cell => 98 | { 99 | cell.Style.ForeColor = foreColor; 100 | cell.Style.BackColor = backColor; 101 | }); 102 | } 103 | } 104 | }); 105 | } 106 | 107 | /// 108 | /// Binds data of any class without nested collections to the data grid. If a class property has a description attribute, that will be used as the column header. 109 | /// 110 | /// The data grid to apply the data 111 | /// Type of the class to bind 112 | /// Collection of data to bind to the data grid 113 | public static void BindData(this DataGridView dataGridView, IEnumerable dataToBindToGrid) where T : class 114 | { 115 | var properties = typeof(T).GetProperties().ToList(); 116 | if (ClassHasNestedCollections(properties)) 117 | { 118 | throw new InvalidOperationException("Class cannot have nested collections."); 119 | } 120 | 121 | var columns = new Dictionary(); 122 | properties.ForEach(p => columns.Add(p, (GetColumnName(p)))); 123 | columns.ToList().ForEach(column => dataGridView.Columns.Add(column.Key.Name, column.Value)); 124 | dataGridView.Rows.Add(dataToBindToGrid.Count()); 125 | var rowIndex = 0; 126 | dataToBindToGrid.ToList().ForEach(data => 127 | { 128 | var columnIndex = 0; 129 | properties.ForEach(prop => 130 | { 131 | dataGridView.Rows[rowIndex].Cells[columnIndex].Value = SetCellValue(prop, data); 132 | columnIndex++; 133 | }); 134 | rowIndex++; 135 | }); 136 | } 137 | 138 | private static bool ClassHasNestedCollections(IEnumerable properties) 139 | { 140 | return properties.ToList().Any(x => x.PropertyType != typeof(string) && 141 | typeof(IEnumerable).IsAssignableFrom(x.PropertyType) || 142 | typeof(IEnumerable<>).IsAssignableFrom(x.PropertyType)); 143 | } 144 | 145 | private static object SetCellValue(PropertyInfo property, T data) where T : class 146 | { 147 | var value = property.GetValue(data, null); 148 | return value is Guid ? value.ToString() : value; 149 | } 150 | 151 | private static string GetColumnName(PropertyInfo propertyInfo) 152 | { 153 | var descriptionAttribute = propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute)).FirstOrDefault(); 154 | if (descriptionAttribute == null) 155 | { 156 | return propertyInfo.Name; 157 | } 158 | var description = descriptionAttribute as DescriptionAttribute; 159 | return description == null ? propertyInfo.Name : description.Description; 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /DataGridViewExtensions/DataGridViewExtensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7F506848-F713-4021-9768-B810B160D7D5} 8 | Library 9 | Properties 10 | DataGridViewExtensions 11 | DataGridViewExtensions 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 56 | -------------------------------------------------------------------------------- /DataGridViewExtensions/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("DataGridViewExtensions")] 9 | [assembly: AssemblyDescription("A library of extensions for Windows forms data grid views.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Grant Taylor")] 12 | [assembly: AssemblyProduct("DataGridViewExtensions")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 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("7f506848-f713-4021-9768-b810b160d7d5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataGridViewAssistant 2 | A library of extensions for Windows forms data grid views. 3 | 4 | This library is used for performing searches, updates, formatting and generic data binding for **Windows Forms** **DataGridViews**. 5 | 6 | The following functions are included in the library. **FindRows**, **UpdateCells**, **RemoveRows**, **FormatCells**, **BindData**. 7 | 8 | ## FindRows 9 | **FindRows** takes a ```Func``` parameter in order to find rows based on a specific data grid cells. 10 | Example: 11 | ```C# 12 | var dataRowsSearched = _dataGridView.FindRows(x => x.Value.ToString() == "Grant"); 13 | ``` 14 | 15 | ## UpdateCells 16 | **UpdateCells** takes a ```Func``` parameter for searching specific cells to update and a value for updating the searched cells. 17 | Example: 18 | ```C# 19 | _dataGridView.UpdateCells(x => x.Value.ToString() == "test@email.com", "ggtgivens24@gmail.com"); 20 | ``` 21 | 22 | ## RemoveRows 23 | **RemoveRows** takes a ```Func``` parameter for searching specific cells and removing the rows containing those cells. 24 | Example: 25 | ```C# 26 | _dataGridView.RemoveRows(x => x.Value.ToString() == "test@email.com"); 27 | ``` 28 | 29 | ## FormatCells 30 | **FormatCells** takes a ```Func``` parameter for searching specific cells and two additional parameters for formatting the cells font and background color. These parameters are **System.Drawing.Color** enums. 31 | Example: 32 | ```C# 33 | _dataGridView.FormatCells(x => x.Value.ToString() == "test@email.com", Color.White, Color.Red); 34 | ``` 35 | 36 | ## BindData 37 | **BindData** takes an ```IEnumerable``` with T being any .Net class without nested collections and builds the data grid from that collection. The property names of the class become the column names. If there are description attributes on the properties, those will be used as the column header's. 38 | Example: 39 | ```C# 40 | var contactInfo = new List 41 | { 42 | new ContactInfoModel 43 | { 44 | Id = Guid.NewGuid(), 45 | FirstName = "John", 46 | LastName = "Doe", 47 | Age = DateTime.Now.Year - new DateTime(1991, 9, 2).Year, 48 | DateOfBirth = new DateTime(1991, 9, 2), 49 | PhoneNumber = "(952) 564-1170", 50 | Email = "test@email.com" 51 | }, 52 | new ContactInfoModel 53 | { 54 | Id = Guid.NewGuid(), 55 | FirstName = "Jane", 56 | LastName = "Doe", 57 | Age = DateTime.Now.Year - new DateTime(1990, 8, 5).Year, 58 | DateOfBirth = new DateTime(1990, 8, 5), 59 | PhoneNumber = "(952) 564-2173", 60 | Email = "test24@email.com" 61 | } 62 | }; 63 | 64 | var dataGrid = new DataGridView(); 65 | dataGrid.BindData(contactInfo); 66 | ``` 67 | 68 | --------------------------------------------------------------------------------