Call sub on class property change? - vb.net

I have a custom class which is based off of a TreeNode and this has an Enum property on it called status, setup as shown below.
Public _staus As enumStatus
Public Enum enumStatus
None
Yes
No
End Enum
Basically when I change this property I want to call a sub routine which just changes the text colour of the item - this sub is contained in the class and is simply a select case statement updating the Me.ForeColor property.
This works correctly if I class myClass.ChangeColourBasedOnStatus but how can I make it automatically do this when a property is changed.
I've tried looking at event handlers but I just can't find an explanation that I understand and can get to work.
Any advice is greatly appreciated. :)

Make the field private and add a Property to access it. In the example below I assume that you are using text from a control, but you could modify it to use the enum or other types.
Private _staus As enumStatus
Public Enum enumStatus
None
Yes
No
End Enum
Public Property Status As enumStatus
Get
Return _staus
End Get
Set(value As enumStatus)
_staus = value
ChangeColor(TextBox1.Text)
End Set
End Property
Private Sub ChangeColor(SomeText As String)
Select Case SomeText
Case "" : Me.ForeColor = Color.Black
Case "Stop" : Me.ForeColor = Color.Red
Case "Go" : Me.ForeColor = Color.Green
End Select
End Sub

Related

Void user check RadioButton without disabling it

I have four RadioButtons inside a GroupBox and I need to forbid user to change it status but without disabling the control because I need that they look NOT disabled(grayed).
I'm controlling them from code.
I tried to change AutoClick to false but I get more than one RadioButton checked when I change them by code.
Of course I can change all the RadioButtons status every time but that looks a bit messy.
You can use an inherited class for this.
Mark IsReadOnly to true to disable the click.
Class ReadOnlyRadioButton
Inherits System.Windows.Forms.RadioButton
Private mRo as Boolean
Public Property IsReadOnly As Boolean
Get
Return mRo
End Get
Set(ByVal value as String)
mRo = value
End Set
End Property
Protected Overrides Sub OnClick(ByVal e As EventArgs)
If Not Me.IsReadOnly Then
MyBase.OnClick(e)
End If
End Sub
End Class

Change the defaultValue of A custom control property

I created a number of custom controls but still struggling mastering the interface.
For uniformity besides creating custom proerties I also want to change some base properties of the custom control I tried following code
Protected Overrides Sub OnControlAdded(e As ControlEventArgs)
Me.AutoCompleteMode = AutoCompleteMode.Suggest
Me.AutoCompleteSource = AutoCompleteSource.ListItems
MyBase.OnControlAdded(e)
End Sub
That however does not work when I drop the custom control on a form, I suppose the solution lies with adding the attribute and overriding the property.
I found an answer to this for C# but did not succeed to understand/translate it for vb.net
Since those properties are not overridable, try using the Shadows modifier instead:
Public Class MyComboBox
Inherits ComboBox
Public Sub New()
Me.AutoCompleteMode = AutoCompleteMode.Suggest
Me.AutoCompleteSource = AutoCompleteSource.ListItems
End Sub
<DefaultValue(AutoCompleteMode.Suggest)> _
Public Shadows Property AutoCompleteMode As AutoCompleteMode
Get
Return MyBase.AutoCompleteMode
End Get
Set(value As AutoCompleteMode)
MyBase.AutoCompleteMode = value
End Set
End Property
<DefaultValue(AutoCompleteSource.ListItems)> _
Public Shadows Property AutoCompleteSource As AutoCompleteSource
Get
Return MyBase.AutoCompleteSource
End Get
Set(value As AutoCompleteSource)
MyBase.AutoCompleteSource = value
End Set
End Property
End Class
Please note though, the DefaultValue attribute probably doesn't do what you think it does: it doesn't actually set a default value of that property. All it is used for is to tell the PropertyGrid what the default value for the property is, and if it matches it, it won't make it bold in the PropertyGrid view and it won't serialize the value in the designer file.

VB.Net - UserControl don't update Controls inside

I'm working on a VB.Net application. I need to create an UserControl I've named signalIO, with a TextBox and a Label, with some properties to change contents of TextBox and Label, change BackColor, etc.
When I add signalIO into the Form of my application, the signalIO control works fine. If I change the parameter StatusSignal from False to True, I can see the backcolor of textbox into control changed from Red to Green, if I change the name of the Signal, I can see text into Label changed correctly.
But if I run on debug the application, I cannot see the changes after the Set methods of the properties.
This is the code I've used:
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.ComponentModel.Design
Imports System.Windows.Forms
<Designer("System.Windows.Forms.Design.ParentControlDesigner,System.Design", GetType(IDesigner))> _
Public Class controlIO
Inherits UserControl
Private status As Boolean
Private ID As Integer = 0
Private label As String
Public Property labelSignal As String
Get
Return labelIO.Text
End Get
Set(value As String)
label = value
labelIO.Text = label
updateControl()
Invalidate()
End Set
End Property
Private Sub updateControl()
Me.Refresh()
boxIO.Refresh()
labelIO.Refresh()
End Sub
Public Property statusSignal As Boolean
Get
Return status
End Get
Set(value As Boolean)
status = value
If status Then boxIO.BackColor = Color.Green Else boxIO.BackColor = Color.Red
updateControl()
Invalidate()
End Set
End Property
Public Property signalIO As Integer
Get
Return ID
End Get
Set(value As Integer)
ID = value
boxIO.Text = CStr(ID)
updateControl()
Invalidate()
End Set
End Property
End Class
I cannot understand why if I change the property statusSignal, for example, I can see the change of the color of boxIO into FormDesigner of the application, but this not changed during execution of the application.
I wish you can understand my question.

How do you handle PropertyChange for a boolean value?

I'm creating a program in which I have a publicly defined boolean value
Public boolOverallStatus As Boolean = True
and I need to execute some code whenever the boolean value changes. In previous applications, an actual form item change handled this, but it can be changed by several different subs.
How would I handle this? I'm looking through msdn, but it's rather confusing.
In a nutshell: How to execute code when the event of a boolean value changing occurs.
Make it a property instead.
Private _boolOverallStatus As Boolean = True
Property boolOverallStatus As Boolean
Get
Return _boolOverallStatus
End Get
Set(ByVal value as Boolean)
If value <> _boolOverallStatus Then
_boolOverallStatus = value
'// handle more code changes here.'
End If
End Set
End Property
I use the following pattern which resembles what Microsoft do for most of their Changed events.
Class MyClass
Public Property OverallStatus As Boolean
Get
Return _OverallStatus
End Get
Set (value As Boolean)
If _OverallStatus = value Then Exit Property
_OverallStatus = value
OnOverallStatusChanged(EventArgs.Empty)
End Set
End Property
Private _OverallStatus As Boolean = False
Protected Overridable Sub OnOverallStatusChanged(e As EventArgs)
RaiseEvent OverallStatusChanged(Me, e)
End Sub
Public Event OverallStatusChanged As EventHandler
End Class
In VB, you can handle the event using the WithEvents and Handles keywords:
Class MyParent
Private WithEvents myObject As New MyClass()
Private Sub myobject_OverallStatusChanged(sender As Object, e As EventArgs) Handles myObject.OverallStatusChanged
' TODO: Write handler.
End Sub
End Class
The OnOverallStatusChanged function is useful for inheriting classes to get first shot at responding to the change.
Class MyOtherClass
Inherits MyClass
Protected Overrides Sub OnOverallStatusChanged(e As EventArgs)
' TODO: Do my stuff first.
MyBase.OnOverallStatusChanged(e)
End Sub
End Class
Use public properties instead of public variables. You can then put logic in the Set method of the property to execute whenever the property is.. well set.
http://msdn.microsoft.com/en-us/library/65zdfbdt%28v=VS.100%29.aspx
Private number As Integer = 0
Public Property MyNumber As Integer
' Retrieves number.
Get
Return number
End Get
' Assigns to number.
Set
CallLogicHere()
number = value
End Set
End Property
You could also define an event, which is fired each time the status changes. The advantage is, that changes can be handled by the parts of the application that depend on this status. Otherwise the logic would have to be implemented together with the status.
Other parts of the application can subscribe the event with AddHandler.
Public Class OverallStatusChangedEventArgs
Inherits EventArgs
Public Sub New(newStatus As Boolean)
Me.NewStatus = newStatus
End Sub
Private m_NewStatus As Boolean
Public Property NewStatus() As Boolean
Get
Return m_NewStatus
End Get
Private Set
m_NewStatus = Value
End Set
End Property
End Class
Module modGlobals
Public Event OverallStatusChanged As EventHandler(Of OverallStatusChangedEventArgs)
Private m_boolOverallStatus As Boolean = True
Public Property BoolOverallStatus() As Boolean
Get
Return m_boolOverallStatus
End Get
Set
If Value <> m_boolOverallStatus Then
m_boolOverallStatus = Value
OnOverallStatusChanged(Value)
End If
End Set
End Property
Private Sub OnOverallStatusChanged(newStatus As Boolean)
RaiseEvent OverallStatusChanged(GetType(modGlobals), New OverallStatusChangedEventArgs(newStatus))
End Sub
End Module

Create Custom Control with reusable properties

This is similar to my last post but with a different purpose.
I have built a custom control, but when I set the properties for it... ALL instances of that control on my page grab the exact same property. I need to be able to set the property to "abc" for one instance of the control on my page, and then set the exact same proprty to "xyz" for a different instance of the control on the same page.
Can anyone shed any light?
Namespace CustomControl
Public Class mycontrol : Inherits Literal
Protected Overrides Sub CreateChildControls()
Dim value As String = "test"
If _doubleit = True Then
value = value & " test"
End If
MyBase.Text = value
MyBase.CreateChildControls()
End Sub
Private Shared _doubleit As Boolean = True
Public Shared Property doubleit() As Boolean
Get
Return _doubleit
End Get
Set(ByVal value As Boolean)
_doubleit = value
End Set
End Property
End Class
End Namespace
Remove the Shared from your variable and from your property declaration. Shared means exactly that what you don't want: All instances share the same value.
So, your code should look like this:
Private _doubleit As Boolean = True
Public Property doubleit() As Boolean
Get
Return _doubleit
End Get
Set(ByVal value As Boolean)
_doubleit = value
End Set
End Property