Bind data to a datagridview datasource removes the row header

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
pjbuckley
Posts: 26
Joined: Tue Nov 05, 2019 3:44 pm

Bind data to a datagridview datasource removes the row header

Post by pjbuckley » Wed Nov 20, 2019 10:47 am

I am dynamically creating row headers and column headers in a datagridview using data from multiple tables. The DGV gets fully populated with checkbox columns/rows that intersect the column header and row header. I am unable to figure out how to bind this data into the DGV without using the DGV datasource since every time i add the datasource my row headers disapear. There are always more columns than rows.

I could not find a way to create a row header in a datatable nor how to mosh the different datasources for the headers so that the checkbox data is bound to the DGV. I need to be able to check or uncheck the checkboxes in each column then export that data based on button click.

I hope this is clear. I have attached the full code (It's a bit messy still cuz im not done) but i am hoping it wont be needed.

Thanks for the look!
Attachments
Gdata-attendance.ps1
(12.87 KiB) Downloaded 7 times

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 12:45 pm

Please understand that no one is going to try to decode almost 400 lines of code that is extremely hard to follow. You have functions and other elements that are not used or not necessary.

The way to "dynamically" create a DGV is to put all of you fields in an object collection and convert it to a DataTable. Then just assign the table to th DGV.

$dgv.DataSource = $datatable

The DGV will autogenerate all columns and headers based on the table.

I highly recommend downloading the trail version of PowerShell Stdio and working with that until you understand how to work with forms. This will help you manage the process and allow you to experiment in a simple guided tool and you will find hundreds of examples that can be opened and inspected in PSS.

Note that, in your earlier post of that form, I spent a large amount of time trying to understand and modify it to work correctly but gave up because it was so convoluted that I couldn't see how to unwind your code.

When coding something so simple becomes this hard it is always a clue that something is missing or the design is wrong. Building forms is actually very easy once you have a deep understanding of PowerShell and forms.

Here is an example of how to use aa DGV using an object collection and generating all columns. It will run as-is on any system

Code: Select all

Add-Type System.Windows.Forms

# control creation
$form = New-Object System.Windows.Forms.Form
$buttonOK = New-Object System.Windows.Forms.Button
$form.Controls.Add($buttonOK)
$dgv = New-Object System.Windows.Forms.DataGridView
$form.Controls.Add($dgv)

# form settings
$form.Size = '500,400'
$form.StartPosition = 'CenterScreen'
$form.Text = 'Basic DGV Form Demo'
$form.add_Load({
    $files = Get-ChildItem -File | select Name,Mode,Length -First 30
    $dgv.DataSource = [System.Collections.ArrayList]$files
})

$dgv.Size = '480,300'
$dgv.Location = '5,40'


# buttonOK settings
$buttonOK.Text = 'Ok'
$buttonOK.DialogResult = 'Ok'

$form.ShowDialog()
This form took less than 5 minutes to code.

pjbuckley
Posts: 26
Joined: Tue Nov 05, 2019 3:44 pm

Re: Bind data to a datagridview datasource removes the row header

Post by pjbuckley » Wed Nov 20, 2019 2:21 pm

The point is that i have Column headers AND row headers. When i look at PS Studio it just confuses me since i have always written scripts using notepad. I can populate a DGV with just columns and one datasource all day long. I dont write 'scripts' all day and 90% of them dont need a GUI for me to complete my job.
However, this one customer has asked me for this. Meaning that i have had to delve deeper into powershell than i ever wanted to. I dont know what is relevant in this segment of my code because i have thousands of lines of other code in this project that do other things.

I am having trouble recording the checkbox data generated when i dynamically create row AND column headers from different datasources.

Is there a way to get data into the 'databounditem' property without using DGV.datasource? Or do i need to generate the row and/or column headers differently?

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 3:10 pm

The issue is that you are trying to use linear coding methods and a linear programming understanding with an object system. This leads to writing 10 times or more code than necessary. We call this "brute force" programming. This method is used by people who have not learned formal programming skills and can be made to work however, learning a coding system formally is more efficient and produces less errors and issues.

When applying this style to coding forms then all hell breaks out because forms do not work with linear programming. Forms are even based objects and use a "state machine" like approach to programming.

While it appears that you can build every primitive by hand this is not how any programmer would do this. First learn how the control and forms work technically then design a solution using the tools they provide.

To answer your question about the "databounditem" the answer is no. A data bound item is an external item attached as a source for the construction of the row. You can add an empty DataTable and add or alter rows in the table object and they will be reflected in the grid. My blog posts on data binding illustrate this in as simple a way as possible without getting too technical.

Manually adding cells to a DGV is just not done except under extreme circumstances. Every example I have seen of this in numerous languages has been unnecessary if the coder actually understood the DGV.

In order to prove this to you would require rewriting your code and, as I noted above, I tried to do a quick job of that but your code was such that I couldn't figure out your intent from the code. With your full environment I could figure it out if the code would actually run. I could possibly figure out the code you posted but I really don't feel like dedicating my day to trying to unwind hundreds of lines of clearly unnecessary code.

You would do yourself a favor by taking time to learn PSS and then using it to learn forms. This is what many trained programmers wanting to work with Windows and forms have finally realized they had to do including one programmer that I started out with. He went elsewhere and didn't learn Windows I worked in both arenas. When I brought him over to Windows he was just lost for more than a year and refused my direction. Later he went to a school for Windows developers and learned what he had fought against and eventually became a very expert Windows developer but not without more than a year of pain.

Coding is not a skill like a sport. It is aq discipline and it is an engineering discipline. Approaching it any other way never has a good outcome. You can ignore the base of accumulated knowledge and reinvent the discipline of programming and do things but it is unlikely that anyone with no formal engineering training will be able to invent the decades of work that very smart people have done to formalize software engineering.

If you were to learn to use PSS I know you would understand much of what I am trying to tell you.

I will give this tip. Rows are objects and can be added whole. Just get a new row and assign values. You do not need to create all of the parts. Row headers are not changeable except by the "Paint" event which can write into the Graphics context. Loading data into a row cannot change column headers and column headers should not be changed after the grid is created.

Think of a grid as a hierarchy of objects held in collections. The grid holds a header and a row collection. The row collection hold rows and a row object is a collection of cells.

The row collection has a method called NewRow() which creates a row and all cells based on the header. This can be loaded from an array.

A row header can only be changed globally which will effect every header.

Be careful of most C# examples as they will not work correctly or they will mislead you as to how the DGV works. The Microsoft C# "WalkThroughs" are useful but require using Visual Studio to understand them.

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 3:40 pm

As an example of some of the fundamental issues. The code you have copied as a starter is old code and code that was designed for an older version of PowerShell and dotNet.

Example - the following:

Code: Select all

[void][Reflection.Assembly]::Load('System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Reflection.Assembly]::Load('Microsoft.Office.Interop.Access.Dao, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
[void][Reflection.Assembly]::Load('System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
You only need the following line as all of the other assemblies are loaded in PS by default:

Add-Type -AssemblyName System.Windows.Forms

You do not need to add this in every function. Also utility functions should not be built as "Advanced Functions" as it serves no purpose. It would be useful if they were general purpose functions and were save in a module. Then for future designers they would be useful at design time.

This and numerous other bad habits you have learned are causing you to write 5 to 10 times as many lines as needed to accomplish your task.

Here is another link that can help you get control over code design. It can save you problems and help simplify your code.

https://poshcode.gitbooks.io/powershell ... and-style/

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 4:02 pm

I should also ask the missing piece. What ae you attempting to do with row headers? Why would you need to change them? A row header is just an annunciator that show which row is current and provides a spot where you can select the row or full row without suing a cell click event. It requires no event as the click is handled internally.

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 4:05 pm

Here is an old Sapien thread that explains how to maintain row headers after a row or grid is loaded.

viewtopic.php?t=11531

I looked for my demo example but it seems to be misplaced.

pjbuckley
Posts: 26
Joined: Tue Nov 05, 2019 3:44 pm

Re: Bind data to a datagridview datasource removes the row header

Post by pjbuckley » Wed Nov 20, 2019 4:10 pm

Yes. I know i am a brute force programmer. I am not fighting you on what tool i should use.

I agree. Its time that i started using an object based programming interface to build scripts moving forward. I am not formally trained. Formal training may make someone 'smart' but it doesnt make them intelligent.

The key word here is that i write 'scripts' not 'programs'. This project has taken me deeper into the 'program' area than ive ever wanted to be in. I am a Microsoft Platform migration and configuration expert with 20 years of migration and configuration experience as a consultant not a developer. I have never been formally trained in any discipline and made it this far on raw talent alone. I have worked as a Microsoft Premiere Field engineer for AD, Exchange,O365,Azure, and SCCM. If its a Microsoft Product i can migrate it or configure it.

I know my own limitations and have rarely asked for help on my journey to where i am today. Using powershell for anything other than simple scripting is a limit i recognize and am posting here because i found your article on tech-comments.com on binding data which eventually brought me here.

You have helped nudge me in the right direction for some of my questions and been rather vague or confusing on others. I get it.

I am only looking for that nudge and maybe an example or two that is relevant to my question so that i can apply it into the overall project i am working.

Right now, i am working under a deadline so formal training isnt available or in my radar to get this project done.

pjbuckley
Posts: 26
Joined: Tue Nov 05, 2019 3:44 pm

Re: Bind data to a datagridview datasource removes the row header

Post by pjbuckley » Wed Nov 20, 2019 4:15 pm

I have two csv's with completely different schemas and different datasets. One is a customer contact list and the other is a daily schedule. This particular interface will be utilized to take attendance.

The schedule time and Description fields are the only fields i want from the schedule csv. The customer name is the only column i want from the contact list.

The row header is generated from moshing the time and description fields together and the column headers are the customer name. The cells are all checkboxes to indicate attendance or not.

jvierra
Posts: 14000
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Bind data to a datagridview datasource removes the row header

Post by jvierra » Wed Nov 20, 2019 4:24 pm

  1. >>>Yes. I know i am a brute force programmer. I am not fighting you on what tool i should use.
  2.  
  3. Tools make the carpenter.
  4.  
  5. >>> I agree. Its time that i started using an object based programming interface to build scripts moving forward. I am not formally trained. Formal training may make someone 'smart' but it doesnt make them intelligent.
  6.  
  7. I think you are quite intelligent given what you have cobbled together with no formal training
  8.  
  9. >>>The key word here is that i write 'scripts' not 'programs'. This project has taken me deeper into the 'program' area than ive ever wanted to be in. I am a Microsoft Platform migration and configuration expert with 20 years of migration and configuration experience as a consultant not a developer. I have never been formally trained in any discipline and made it this far on raw talent alone. I have worked as a Microsoft Premiere Field engineer for AD, Exchange,O365,Azure, and SCCM. If its a Microsoft Product i can migrate it or configure it.
  10.  
  11.  
  12.  
  13. Ahhh! That is the glitch.  PowerShell can do configurations, but Forms are a different beast.  They are a hard nut to crack without some learning and basics.  I am not saying you need to become a software engineer but you do need to learn fundamental PowerShell and Forms.    You are overworking yourself by guessing.
  14.  
  15.  
  16.  
  17. >>>I know my own limitations and have rarely asked for help on my journey to where i am today. Using powershell for anything other than simple scripting is a limit i recognize and am posting here because i found your article on tech-comments.com on binding data which eventually brought me here.
  18.  
  19.  
  20.  
  21. But you are not using “data binding” anywhere in your code.  My tips and suggestions are to use a datatable and bind it to the grid.  That will solve many of your issues and the column will be autogenerated.
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. >>>Right now, i am working under a deadline so formal training isnt available or in my radar to get this project done.
  30.  
  31.  
  32.  
  33.     You could work with a book alongside of coding and do both.  As of now you are stuck.  You don’t understand my suggestions and you can’t move forward on your own.  Sounds like a good excuse to hit the book
  34.  
  35.  

Post Reply