Inherited controls not refreshing correctly - vb.net

I have 2 buttons that have similar functions so I created a base button class and derived button classes.
The problem I'm having is that if I put a child button on a form, make some changes on the base button and rebuild it, the child button on the form does not reflect the changes. The new child button put on the form after the rebuild, it has the changed properties. Basically, the control that was already put on the form does not refresh after the base control is rebuilt.
I can't refresh the controls on designer since there are too many of them. I'm guessing that if a control is put on a form, it's properties are set(?). Maybe I'm not good enough with inheritance and missing something here.
I would like to know how to refresh the child controls that were put on the form before base control was modified.
UPDATE with Minimal, Complete, and Verifiable example:
Here is the example in VB.NET.
Public Class ButtonA
Public Sub New()
Me.Size = New Size(200, 200)
End Sub
End Class
Public Class ButtonB
Inherits ButtonA
End Class
After instance of ButtonB called btnB is put on a form, ButtonA's default size changes to
Me.Size = New Size(300, 300)
After the project is rebuilt, when I look back on the designer view, btnB's size is still (200, 200), not (300, 300) as it's base default size.
Size is just used as an example, it applies to any properties.

The problem is that you are changing values of properties that he designer, by design, must not use, once you have placed a control on the form. The designer allows you to put a control of a certain class in you form and, when first inserted will take a clue as to what the size should be from that control. It will then assign that size to that control within this form. You are at liberty, at any time, to modify the form by changing the size or location of any form within that form. The designer will keep track of all of this.
If you now modify the source code to have a different 'default' value for the size, then, that will not be reflected on the form that was created prior to the size being changed - that's because the control already exists on your form and the designer therefore no longer has to make make any changes to the size.
If you do want to override this behaviour you will have to remove the assignment of the Size property in the designer code (Form.Desisgner.cs - in C# or its VB equivalent). But beware - next time you fire up the designer it will probably put the size back in there.

Related

Save Separate Settings for Copies of the same Form

I have a form, when I right click it, you can select properties, which opens a settings Form that interacts directly with the previous form, ie, it can change the color, size and other properties of the the original form. I want Several Copies of the original form running.
As it Stands, all the new forms take their settings from the same My.settings.
1st How Can I Save all the settings from each copy of the original form, Separately?
right now im using Form1.show(), and dim newform as form1 = new form1.
2nd, how can I make sure the settings form is interacting only with their respective original form?
right now, all the new settings Forms are only interacting with the same original form.
I have a jumble of data types saved, about 10 settings, and 2 of them are Specialized.string to save matrixes
Firstly, I recommend not using My.Settings in this case, since it only serves the purpose of storing global settings.
You'll need to store the settings in the Form1 class for each instance seperately, these could then be saved to a file or in the registry.
To your second question, in the settings form class, add a parameter to the Form.Show method, which is used to pass the instance of a main form object to the settings form.
This will tie a newly opened settings form to a particular main form. This could look like this:
Class SettingsForm
Shadows Sub Show(parentForm As Form1)
'The parentForm paramter will be the Form1 instance which will be controlled by this settings window
End Sub
End Class
You then just call the SettingsForm.Show method and pass the instance of the Form1 object you want to control to the method.

How can I add to a ListView on a child form if new data is received on the main form

I have a child form (let's call it ChildForm) that is instantiated by a parent form (MainForm). The ChildForm has a ListView control, which when initially opened populates data based on a public collection managed by the MainForm. The method within the ChildForm managing the population of the ListView is called PopulateLog and calls AddItemsToLog(logEntry). This works fine.
However, while the ChildForm is open and being displayed, the MainForm may receive additional elements, which are added to the collection. So to dynamically display the received data, I've tried the following from within the MainForm but it doesn't seem to work - nothing changes the display of the ListView in the ChildForm.
If Application.OpenForms().OfType(Of ChildForm).Any Then
ChildForm.AddItemsToLog(newLogEntry)
End If
I've tried ChildForm.Refresh() from within the MainForm, but also with no results.
I have searched this for a couple of hours and haven't been unable to find a clear example of how to do this - I suspect that using events/delegates is the direction to go - any help is appreciated. I suspect that this would be a useful and oft-used feature but am frustrated that it's not clearly documented.
EDIT: Also I should note that the ListViewLogReceived.Items.Count DOES increment when called - but the view doesn't appear to refresh. That would imply that the data is being added just not displayed. –
I can't seem to select Hans' answer, but he led me to the right place. I was (amateurishly) referring to the class name of the form, not the instantiated version of the form. This works:
If Application.OpenForms().OfType(Of ChildForm).Any Then
myChildForm.AddItemsToLog(newLogEntry)
End If

Winforms Form Inheritance - inherited forms not updating when base form is changed

I'm using form inheritance in my project. I design a base form, and then create forms that inherit it and go from there.
Here's the problem. If I change the width of the base form, the inherited forms don't get their widths updated.
Say my base form started at 820 width. I create an inherited form, it has 820 width. I update the base form to 800 width, inherited form stays 820. Yet, if I add a button to the base form, or make a number of other changes, those are reflected in the inherited form usually without issue.
It doesn't only apply to form width, I've run into this a few times.. but this is the current issue I'm having. Any anchored controls go haywire because their positions are updated from the base form, but the form itself doesn't change.
Any ideas how to resolve (or work around) this?
This will happen when you have the derived form opened in the designer. Which remembers the size it had. If you then modify the base form and rebuild then the designer will notice the derived form is no longer the same size as the base form and will record the size. You'll now have a permanent mismatch.
You avoid it by making sure the derived form isn't opened when you edit the base form. And that the base form is recompiled before you open the derived form. But, accidents are definitely going to happen, best to not rely on it. And in the greater scheme, the size should be left up to the user anyway.
You can fix it by right-clicking the derived form's Size property in the Properties window and clicking Reset.

Making multiple forms appear as one in VB.NET

I am writing a Windows Forms application in VB.NET. I have three forms: the main form, which shows a list of accounts, the account form which allows the user to view/edit the information for a specific account, and the policy form which allows the user to view/edit the information on a specific policy for that account. I want the forms to appear as if they are all the same window. Example: when the application starts, the user clicks an account name in the list box on the main form and clicks "edit". What I want to happen is that the window stays in the exact same place and stays the same exact size, only the content of the main form appears to be replaced with the content of the account form. Same thing if the user then chooses to edit a policy from the account form. When the user finishes and clicks "save", the main form comes back up. Through this entire use case, it would appear to the user as if they were viewing the same window the entire time, with the content of that window changing.
How can I do this? I have tried something like:
Dim newForm as New AcctForm
newForm.Location = Me.Location
newForm.Show()
Me.Close()
The problem is that if the user moves the original window, the new window appears where the parent form originally appeared, not where it ended up.
I see this is already in the comments, but what I have done in this case in the past is build each "form" in the application as a custom control. Then I have one actual form, and navigation works by changing which custom control is currently loaded on the parent form. To move from one screen/view to another, you remove the current custom control from the form's controls collection and add the new custom control.
I believe this is superior to manually setting the startup position and size, because you can use the form's .SuspendLayout()/.ResumeLayout() methods to hide the interim state, where there is no control loaded, from the user. This is harder to do when you want one form to be completely replaced by another.
This also makes it easy to set certain form properties in one place and have them be consistent for the application. You can even have an area on the form with controls that will now show in every view.
When using this pattern, I typically have each of my custom controls inherit from a common base. You may not have anything specific you will do with that base at the outset, but it almost always comes in handy later.
Finally, switching to use this scheme is easier than you think. Just go to the code for the each of your current forms, and you will find that each class currently inherits from System.Windows.Forms.Form. Most of the time, all you really need to do is change them to inherit from System.Windows.Forms.Panel and you're most of the way there.
As others have said, it may be better to redesign your application using custom controls or panels etc.
However, to answer your question regarding the seemingly random location of your forms, the first thing to check is that each form has it's StartPosition property set to Manual.
If your main form is resizable, then I would also add code to adjust newForm to the same size too.
I hope that helps with your immediate issues; so that you can move on to redesigning the application!
good morning there is another way . set property for second form to (top most) and use also
from2.show();
that make you switch between forms and keep form2 top other
Thanks
try using ShowDialog()
Dim newForm as New AcctForm
newForm.Location = Me.Location
newForm.ShowDialog()
Me.Close() <-- removed this

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!