How to Customize ListView Column Headers - vb.net

I am fairly new to programming and I have never attempted writing my own class before. I would like to try. What I am trying to achieve is to write my own (basic) listview control to start with. I am struggling with the first bit...
As a start I want to try and centre all of the Column Headers but keep the row text using their own formatting. I would like to implement a custom property if possible, but to start with I just want to override the DrawColumnHeader event.
Can someone point me in the right direction (maybe an example). I have setup a new class, inherited the listview control and added the following event:
Protected Overrides Sub OnDrawColumnHeader(ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
However, I am finding that any code I place in this event isn't getting fired when the listview gets drawn.

Reason was that I didn't have the OwnerDraw property set to True.

Related

Access cell color value of datagridview when it has been set via the cellpainting event args

My searches regarding this have only turned up how to set the color of a datagridview cell, whether that be in the formatting, cell painting, or databound events.
The code that I'm trying to work with is currently setting the cellstyle.backcolor through the datagridview event args in the cellpainting event:
Private Sub dgvAncientCode_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles dgvResults.CellPainting
If dgvAncientCode.Columns(e.ColumnIndex).Name = "Blah" Then
e.CellStyle.BackColor = Color.Red
End If
This works--the specified cells do show up as red--but how can I access this value elsewhere in code? When I check the cell.style it's set to the default, yet it displays on the screen as red.
I know there is a lot wrong with this code, but I'm still relatively new and I'm supporting a lot of legacy stuff that's comprised of every worst practice you can think of. I did come up with a workaround for this by setting the cell.style.backcolor instead of the e.CellStyle.BackColor, which lets me access the value later, but I'm also trying to understand what was happening with the original code. I hate making things work without understanding why, mainly because I know I might be missing something important.
I apologize if this isn't clear or if it's been asked before. I've searched for a couple hours here and elsewhere, so hopefully I didn't miss it.
Edit for additional information: There is a button click event that iterates through the datagridview using a for each loop. That is being used to set the cell color of a custom excel export class. This did not work because none of the cells in the datagridview had a value on the cell.style.backcolor property, even though they show as red in the form. If the cell displays as Red in the form, I should be able to access that somehow--at least, I think I should.
Try one of this. Maybe it can help you. "yourdatagrid.ControlStyle", "yourdatagrid.ItemStyle".

VB.NET - Hiding Form on Load

So theres a few questions on this but they all give the same answer Me.Hide() which "works" if you count that when it loads, It will SHOW but then will hide seconds after which makes a weird Shadow-y-Laggy Effect.
Example:
(The small Window that shows and almost instantly hides is the window im trying to NEVER show)
Is there a way to actually hide the WHOLE form upon load? I know of the whole VisibilityCore method but with that I cant find a way to show it again at a later point.
So is there a way to hide it so it NEVER shows unless I tell it to Show?
Currently im using "Hide() combined with Form.Show Method".
If you set the form's Opacity property to 0 (through the Property Window) you shouldn't have this problem.
When you want to show the form (if it's going to be shown at all) just set the opacity back to 1.0.
Opacity is still a hack. The correct way is to not show it at all, versus making it invisible. To do this, don't make it the "Startup Object" at all.
On the Application tab of the Project Properties screen, there is a Startup Object setting. Create a Module with a Sub Main() and make that the entry point of your app by selecting it as the Startup Object instead of that little form that apparently doesn't do anything visual.
Maybe you have some initialization code in that starting form...move that to Sub Main.
you can minimize the form upon application launch.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form fm = new Form1();
fm.WindowState = FormWindowState.Minimized;
Application.Run(fm);
}

How Can I Pass An Event Handler Outside Of A Custom Class

I have created a custom Textbox using a new class of which inherits. To this custom Textbox I have added two buttons (embedded) inside the control which are both declared inside the class. One button is for Search and the other for Clear.
The purpose behind these buttons is to populate a Listview control when using Search and Clear the results when using clear...pretty straight forward.
However, my issue that I need help with is...
Because I have declared these buttons inside of my custom class, I cannot work out how to pass a 'Click' event outside of the class and back to the form. For example, if I type into the Textbox and hit the search button, I somehow need to execute code on the click event (and same for clear).
I have read a little about not being able to pass event handlers outside of the class it was created, but I'm not really familiar with this.
Is there/and if so what is the best way to achieve my results? Is it possible to handle a click event outside of the class to pass information to other controls?
Any help appreciated. Thanks
Thanks to the comments from Hans Passant for putting me on the right track, I was able to refer to this site Raising Events and solve my issue.

How do I create a "wizard" style ui using vb.net?

The idea is that I would have a set of forms, users would click through a "forward" and "back" button, and the current form would change to a different one. My issue is that I can write code that just pops up a new form, but im not sure how to do a "replacement" of my current form. How is this usually done?
What I did recently was to create a form with buttons already in place and a large panel to contain each step. The dialog would accept an initial step in the form of a IWizStep instance, and the things would roll from there.
Each step was a class exposing a UserControl responsible for the visual aspect of the step, while the logic itself was handled by the class (it was a little more complicated that that, but that was the general idea).
The IWizStep interface, implemented by the step and accepted by the dialog, was on the lines of:
Interface IWizStep
Event StateChanged As EventHandler
ReadOnly Property Control As Control
ReadOnly Property Title As String
ReadOnly Property CanMovePrevious As Boolean
ReadOnly Property CanMoveNext As Boolean
Function MovePrevious As IWizStep
Function MoveNext As IWizStep
End Interface
To put everything together, a controller class would know how to compose the steps necessary for each given action. Therefore I had a controller for, say, "Emit Order", which needed some 10 steps, and a controller for "Emit Orders in Batch", which needed only a couple of steps.
Create a set of UserControls, and add and remove them from a Panel in a single form. (and set Dock to Fill)
You could define a user control which acts as a "wizard". It just needs the buttons you have and an array of content panels, just have it switch through the panels when the buttons are pressed assuming a certain condition is met within the controls on the panel. There's no real definitive "wizard" maker, since it's pretty easy to roll your own wizard.
You don't need to do a "replacement" of your current form really, you could just add a new one to the project. If you do need to for whatever reason, just grab the control collection with Me.Controls, copy that somewhere, and put the new controls up. When you don't need the wizard, swap them out again. It's generally best practice to make a new form however!

Deleting bound item from DataGridView

I have a List of an object, set to DataSource of a BindingSource, set to DataSource of a DataGridView. Then I added a DataGridViewButtonColumn which I want a click to remove that record from the collection. So I simply call collection.RemoveAt(e.rowIndex) from the DataGridView CellClick event. However this produces an IndexOutOfRange Exception; "1 does not have a value"..
So is happening here? I have maybe a vague idea, but would like to understand exactly which events are failing etc.. and what do i need to do to perform this action properly?
EDIT:
This seems not to happen if I use a BindingList.. But when using a List, I get this problem..
The reason you're seeing the error is because you're ultimately binding to a List. List doesn't include the notifications of changes that your DataGridView needs to receive to reflect the changes you make.
If you really want to work around this you could do the following: just before you make a changes to your List, set the BindingSource's DataSource property to Nothing. When you're done making changes reset your List to the DataSource.
This is a pretty ugly solution as you can imagine. What you'll want to do this bind to an object that implements IBindingList, either a custom collection you create or a BindingList.
Here's a reasonable starting point for investigating this further:
DataGridView Control Overview (Windows Forms)