Best way to change specific property of set of controlsin VB.net - vb.net

I have a set of controls on my form and i want to enable/disable some of them. what is the best way?
Hint: I don't want to change all controls available in my form.

If your meaning from "enable/disable" is "preventing user from changing them", then you can do this:
THE_NAME_OF_CONTROL.Enabled = False 'Disable a control with THE_NAME_OF_CONTROL Name
And
THE_NAME_OF_CONTROL.Enabled = True 'Enable a control with THE_NAME_OF_CONTROL Name
Or you can put all of your controls in a "Group Box" and disable/enable whole group box.

If you want change controls outside of form, then create a public property or method which do it, instead of making controls public
Public Class MyForm
Inherits Form
Private _MyCheckBoxControl As CheckBox
Private _MyTextBoxControl As TextBox
Private _IsGroupOfControlsEnabled As Boolean
Public Property IsGroupOfControlsEnabled As Boolean
Get
Return _IsGroupOfControlsEnabled As Boolean
End Get
Set (value As Boolean)
_IsGroupOfControlsEnabled = value
'Update controls
_MyCheckBoxControl.Enabled = _IsGroupOfControlsEnabled
_MyTextBoxControl.Enabled = _IsGroupOfControlsEnabled
End Set
End Class

Related

Creating form setting in VB Programmatically

My question is how to create a new form setting in vb.net language to save data Programmatically.
For example when i click button it will create the setting which it,s name is the text of the textbox1.
is this possible and how.
And is there any functions which can save data when program is closed?
You can do that through the form designer.
Go to the ApplicationSettings / PropertyBinding and click the ... button.
Then assign a New setting to the Text property by clicking here:
.Net takes care of making the settings save automatically when the program exits. If you want to force it to save, just call My.Settings.Save()
You can create your own settings-class which inherits ApplicationSettingsBase:
Imports System.Configuration
Public Class MyUserSettings
Inherits ApplicationSettingsBase
<UserScopedSetting()> _
<DefaultSettingValue("white")> _
Public Property BackgroundColor() As Color
Get
BackgroundColor = Me("BackgroundColor")
End Get
Set(ByVal value As Color)
Me("BackgroundColor") = value
End Set
End Property
End Class
Save the settings:
Dim Mus As New MyUserSettings
Mus.BackgroundColor = Color.AliceBlue
Mus.Save()
Load the settings:
Dim Mus As New MyUserSettings
MessageBox.Show(Mus.BackgroundColor.ToString)
Source: MSDN
One of the way in VBA is a standard functions to save setting to Registry:
Call SaveSetting(appName, Section, Key, Value)
Value = GetSetting(appName, Section, Key)
Just put them in form constructor and form destructor:
Private Sub UserForm_Initialize()
...
end sub
Private Sub UserForm_Terminate()
...
end sub

Block focus/select in a ReadOnly textbox

Someone knows how to block the focus/select in a read-only textbox (ReadOnly = true), without using enabled = false?
Thanks!
Controls have a GotFocus Event. You can add an event handler for this event and give another control focus, for example by calling Select() on another control or by using SelectNextControl:
Private Sub MyTextBox_GotFocus(sender as Object, e as EventArgs) _
Handles MyTextBox.GotFocus
MyTextBox.Parent.SelectNextControl(MyTextBox, True, True, True, True)
End Sub
Alternately, you can create a custom control that inherits TextBox and set ControlStyles.Selectable to False.
Public Class NonSelectableTextBox Inherits TextBox
Public Sub New()
SetStyle(ControlStyles.Selectable, false)
End Sub
End Class
Setting ControlStyles.Selectable to false will make the TextBox mimic the behavior of other controls which have this bit set to False:
Label
Panel
GroupBox
PictureBox
ProgressBar
Splitter
LinkLabel (when there is no link present in the control)
I'm not sure I understand fully why you would want that. A read only text box allows selection to allow users to copy the text in there for other purposes. What I assume from your question is that you don't want the TextBox to accept input focus when a user is tabbing through controls, which I've seen to be a more common requirement.
You can achieve this via code:
TextBox1.TabStop = False
to ensure that tab doesn't direct focus to the readonly textbox. You can also achieve this in the designer using the same property as the screenshot shows.

DatetimePicker and other Controls in MenuStrip

I know I can add a DateTimePicker to my MenuStrip with the following lines
Dim dp = New ToolStripControlHost(New DateTimePicker)
MenuStrip1.Items.Add(dp)
But I can't figure out how to add a DateTimePicker to the MenuStrip at designtime. What's the trick behind it? I have been trying and searching for like an hour and I am about to give up even though I know there has to be a way!
TL;DR
How do I add a DateTimePicker to my MenuStrip at design-time?
Alternatively we can add it to a ToolStrip instead.
You are close to a solution in using the ToolStripControlHost, but you will need to derive from that class as shown in the linked-to example. The frustrating thing with that example is that it does not decorate the derived class with the System.Windows.Forms.Design.ToolStripItemDesignerAvailabilityAttribute to make it available on the design surface.
The following is a minimalist implementation to get a working example. You may need to override the automatic sizing to suit your needs/wants for the control. The implementation overrides the Text property to prevent designer from assigning invalid text to the underlying DateTimerPicker control.
<System.Windows.Forms.Design.ToolStripItemDesignerAvailability(
System.Windows.Forms.Design.ToolStripItemDesignerAvailability.ToolStrip _
Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.StatusStrip _
Or System.Windows.Forms.Design.ToolStripItemDesignerAvailability.MenuStrip)> _
Public Class TSDatePicker : Inherits ToolStripControlHost
Public Sub New()
MyBase.New(New System.Windows.Forms.DateTimePicker())
End Sub
Public ReadOnly Property ExposedControl() As DateTimePicker
Get
Return CType(Control, DateTimePicker)
End Get
End Property
<Browsable(False), EditorBrowsable(EditorBrowsableState.Advanced), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
Get
Return ExposedControl.Text
End Get
Set(value As String)
' verify valid date
Dim dt As DateTime
If DateTime.TryParse(value, dt) Then
ExposedControl.Text = value
End If
End Set
End Property
End Class
Was going to add as a comment but I trust it justifies an answer.
The only way I have succeeded in this is to add one at design time (to the form) and set Visible to False and use the menu item to set Visible to True (may also need to set the position and/or bring it to the front).
You do need to manually handle setting Visible to False again.

How to pass a form as the parameter of a function vb.net

Currently in VB.NET I have two public subs like so:
Public Sub addmember1()
'Stuff
End Sub
Public Sub furtherinfo1()
'suff
End Sub
I haven't included the code where "'stuff" is as it is very long and is exactly the same in each sub, however the underlying the principle remains the same.
A certain sub is ran depending on a boolean value. like so...
If add_member = True Then
addmember1()
ElseIf add_member = False Then
furtherinfo1()
End If
How would I use one function to carry out the same procedure as above? (my current solution works but involves repeating the same section of code twice )
I tried the following however was unsuccessful
Public Function forms(ByVal frm As Windows.Forms.Form)
'stuff
End Function
and then run the function like so... (addmember and furtherinfo are the two forms I am working with)
If add_member = True Then
forms(addmember)
ElseIf add_member = False Then
forms(furtherinfo)
End If
here is the paste bin of all the code for context it's in modual and I want to use it for writing information to a word document. Lines 20-71, 76-128, 160-164 is what I am on about.
http://pastebin.com/xWD0RBuh
You can pass the form object to a Sub() in a module as below
Module Printing
Dim StrToAdd As String
Sub MySub(ByVal frm As Form)
'The first line is your code
StrToAdd = "Firstname: " & addmember.txtName.Text
'Change it to as below using frm.Controls("controlname").Text
StrToAdd = "Firstname: " & frm.Controls("txtName").Text
End Sub
End Module
After looking at your code at http://pastebin.com/xWD0RBuh it seems you have a global module with multiple sub routines. Each sub routine has references to controls (such as text boxes) on a form instance. This means each global module sub routine needs to have access to this form instance.
You have only copied in part of the application - the global module, but you have not copied in the form definition. I presume you have a form called addmember, but I don't see it in the example - aside from references in the global module.
Not sure how you use the sub routines - probably a click of a button. If it were me, I would create a class object with properties that hold the data to pass around - one property for each control on the form you want to print. On the click of the button, I would create an instance of the class and copy the values from the form controls into the class properties. I would then pass the instance of the class to the sub routines, and I would alter the sub routines to refer to an instance of the class instead of an instance of a form. That would provide a level abstraction between the form (UI) and the behavior (the sub routines that print). I may even go "crazy" and use an interface.
Does your code compile as-is?
The Problem is that your two Forms are two different classes. Even though you named your controls
the same, you can't just access them simply by frm.txtUsername.
What you could do is iterate through all controls of each form und find them by name:
Public Sub DoStuff(frm As Form)
Dim txtUsername As TextBox = GetControlByName(frm, "txtUsername")
txtUsername.Text = "Hello World"
End Sub
Private Function GetControlByName(container As Control, name As String) As Control
Dim retVal As Control = Nothing
If Not TryGetControlByName(container, name, retVal) Then Throw New ApplicationException("control not found")
Return retVal
End Function
Private Function TryGetControlByName(container As Control, name As String, ByRef ctl As Control) As Boolean
For Each item As Control In container.Controls
If item.Name = name Then
ctl = item
Return True
End If
'If item is a Container (like GroupBox, Panel) check its children
If TryGetControlByName(item, name, ctl) Then Return True
Next
Return False
End Function
If you want to get really fancy you could define a Class with the common Controls and fill them via a little
bit of reflection magic. Though this might be overkill:
Public Sub DoStuff2(frm As Form)
Dim wrapper As New CommonForm(frm)
wrapper.txtUsername.Text = "Hello Wolrd"
End Sub
Public Class CommonForm
Public Property txtUsername As TextBox
Public Property txtFoo As TextBox
Public Property txtBar As TextBox
'Add more Controls here...
Public Sub New(frm As Form)
For Each item In Me.GetType().GetProperties()
Dim value = GetControlByName(frm, item.Name)
item.SetValue(Me, value, Nothing)
Next
End Sub
Private Function GetControlByName(container As Control, name As String) As Control
Dim retVal As Control = Nothing
If Not TryGetControlByName(container, name, retVal) Then Throw New ApplicationException("control not found")
Return retVal
End Function
Private Function TryGetControlByName(container As Control, name As String, ByRef ctl As Control) As Boolean
For Each item As Control In container.Controls
If item.Name = name Then
ctl = item
Return True
End If
'If item is a Container (like GroupBox, Panel) check its children
If TryGetControlByName(item, name, ctl) Then Return True
Next
Return False
End Function
End Class

Unable To Get Public Property To Work In Custom Class

I have created a custom Class to which mimics a Textbox control but allows me to embed a button within this control. Everything works fine normally.
However my problem is that I am trying to setup a Public Property that allows me to turn this button visible or not (well create it actually), but I cannot seem to work out why my property never gets set to True - meaning that since I've implemented this piece of code, my button is no longer drawn anymore.
I have the following code:
Public Class CustomTextbox
Inherits TextBox
Private m_EnableSearch As Boolean
Private search_btn As Button
Public Sub New()
' This call is required by the designer.
Initialize()
End Sub
Private Sub Initialize()
search_btn = Nothing
'Draw the buttons
If EnableSearchButton = True Then CreateSearchButton() '<== This never equals True
End Sub
Private Sub CreateSearchButton()
search_btn = New Button()
...
...
End Sub
<Category("Appearance")> _
<Description("Enables the search button")> _
Public Property EnableSearchButton() As Boolean
Get
Return Me.m_EnableSearch
End Get
Set(value As Boolean)
Me.m_EnableSearch = value
Me.Invalidate()
End Set
End Property
End Class
If I take out the check for EnableSeachButton = True and just change it to CreateSearchButton, the button appears as expected. However, even though I can see and change the EnableSearchButton property in the design view, it never seems to equal true when I step through the code.
Any help appreciated, thanks!
Your question is a little confusing. Does EnableSearchButton actually ADD a button to the control or is it meant to toggle the Enabled state of said button? To get the button to respond to the Property and toggle the enabled state, you need to set the button's state:
Public Property EnableSearchButton() As Boolean
Get
Return Me.m_EnableSearch
End Get
Set(value As Boolean)
Me.m_EnableSearch = value
' to create the button when the prop is set:
If Value AndAlso search_btn IsNot Nothing Then
' create button
End If
If Value = False Then
' destroy button
End If
Me.Invalidate()
End Set
End Property
Since you appear to be creating the button at runtime, you will have to add a check for cases when it is nothing. Since the constructor only runs once and when created, there is no need to test the state of EnableSearchButton, just create it always.
If your Enabled property actually means something like AddButton to this TB, then just pass a Boolean in the ctor:
Public Sub New(boolAddButton As Boolean)
If boolAddButton Then CreateSearchButton()
End Sub
The way you have it, the backing field m_EnableSearch will always be true when the control is created. Any prop setting you do in the IDE happens after the control is created which is the only place you have it set up to create the button.