VB.Net readonly property being automatically initialised without Get code execution - vb.net

I don't understand this, please help. Here is my code:
Class MyCookie
Private _CookieName As String
ReadOnly Property CookieName As String
Get
If String.IsNullOrWhiteSpace(_CookieName) Then _CookieName = "Test"
Return _CookieName
End Get
End Property
End Class
I put a breakpoint inside the property Get procedure. When I initialise MyCookie class, MyCookie.CookieName already has "Test" in it but the breakpoint is never hit!
What am I missing?

What other value would the debugger display for that property? The debugger has to execute the property to get a value to display in the IDE but your application hasn't executed the property so the breakpoint isn't activated. Breakpoints are only activated by YOU executing the code, not the IDE. If you were to use the debugger to watch the _CookieName field instead of the CookieName property then you'd see exactly what you would expect to see.

Related

Setting default property fails because it is read only?

This code was converted from VB6 to VB.Net:
Public prvMainForm = VB6Form
If prvMainForm IsNot Nothing Then
CObj(prvMainForm).StatusBar.Panels(1) = "Initializing Folders..."
End If
(My code is quite long so I've just added this if block which is where the actual error occurs.)
The error is seen on the single line inside the If statement:
Property 'Item' is 'ReadOnly'
StatusBar.Panels(1) returns a MSComctlLib.Panel.
StatusBar.Panels(1) = "Initializing Folders..." is valid in VB6 because of default properties.
Default properties in VB.NET must have parameters. A parameterless property cannot be default and therefore cannot be omitted. Thus, .Panels(1) = "..." is understood by VB.NET as an attempt to replace the entire Panel in the Panels property, which is not allowed.
You can look up the name of the default property in the VB6 object browser, which turns out to be Property _ObjectDefault As String, so you should be able to do:
CObj(prvMainForm).StatusBar.Panels(1).[_ObjectDefault] = "Initializing Folders..."
As you have observed, assigning Text should do the same:
CObj(prvMainForm).StatusBar.Panels(1).Text = "Initializing Folders..."

Call set of parent property when setting child properties

So in my class 'myInfo' I have an aliased property 'HeaderInfo' that is a property as a class, where it is actually the Header of a much deeper class.
Private _header As myHeader
Public Property HeaderInfo() AS myHeader
Get
Return _header
End Get
Set(ByVal value As myHeader)
_header = value
Someotherclass.Foo.Bar.AnotherThing.Header = _header
End Set
End Property
myHeader is a class with properties like 'Name', 'ID', etc. that are all strings. So when I reference this property in something like a Windows Form, I do
Dim info As New myInfo()
info.HeaderInfo.ID = "ID HERE"
info.HeaderInfo.Name = "Name here"
It works to the extent that the instance of the info.HeaderInfo is setting all its properties correctly, but
Someotherclass.Foo.Bar.AnotherThing.Header = _header
never gets set inside the myInfo.HeaderInfo 'Set', because I'm not directly setting the property, I'm setting its subproperties in assumption that it would propagate. Am I not understanding how properties with a custom type work? Is there a way to propagate this?
To make this happen automatically, you would need to alter the setter for the properties in your myHeader type, and for that to work your type instances have to know about the specific instance of your myInfo type.
Let's look at why this doesn't work they way you hoped. To do that, I'll break apart this statement:
info.HeaderInfo.ID = "ID HERE"
When that statement is executed, first the info variable must be de-referenced to get the object instance it refers to.1 When we have that object, we have to get (not set) the HeaderInfo property, so that we have a reference to the your myHeader object instance. Once we have the myHeader object, we call the setter on the ID property to complete the assignment.
Hopefully that clears up why this works the way it does. You do access the HeaderInfo property, but you only ever use the getter.
1Side note: if you ever see the "Object reference not set to instance of object" this is what it's talking about: a variable or property that you did not expect in an expression was Nothing/null.

Getting error when calling custom property

I am looking to do a depth first searching algo using vba so i have defined an object called "node" which should contains a "parentNode".
I have tried to define parentNode as collection and use the following
Public Property Let Parent(ByRef inputNode As Node)
Set parentNode = New Collection
hasParentNode = True
parentNode.Add inputNode
End Property
Public Property Get Parent() As Node
Parent = parentNode.Item(1)
End Property
But when i call node.Parent i got Object variable or With block variable not set
i know that is due to the line "Parent = parentNode.Item(1)" what should be the proper way of doing this? I want it to return the parnetNode assigned by Ref
Thanks
Since Node is an object (I assume, I have no idea what class Node actually is), your code is missing the Set keyword:
Public Property Get Parent() As Node
Set Parent = parentNode.Item(1)
End Property
Getting Object variable or With block variable not set usually sometimes means a missing Set keyword.

Intellisense for member override in VB.Net 2008 Express Edition

If I override a member (e.g AutoSize in the Button Class), then the intellisense no longer appears in the editor, forcing me to re-decorate the property.
Is there an option somewhere that I need to check?
ETA: Here's a code sample:
Public Class MyButton
Inherits Button
Public Overrides Property AutoSize() As Boolean
Get
Return MyBase.AutoSize
End Get
Set(ByVal value As Boolean)
MyBase.AutoSize = value
End Set
End Property
End Class
If I then type:
Dim b as New MyButton
b.AutoSize ...
The intellisense explaining the AutoSize property doesn't appear.
Whether a property is visible in IntelliSense is controlled by the [EditorBrowsable] attribute. VB.NET is a bit special because it hides EditorBrowsableState.Advanced by default.
None of this would apply to an override to Button.AutoSize, it is always visible. Maybe you can give a better example, a code snippet is always good.

Creating a custom control...Cannot create a 'text' property?

Solution
I did some googling and found this forum post, and here is what I needed to do:
Imports System.ComponentModel
<EditorBrowsable(EditorBrowsableState.Always), Browsable(True), Bindable(True), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
Overrides Property Text() As String
Get
Return ControlText.Text
End Get
Set(ByVal value As String)
ControlText.Text = value
End Set
End Property
I should state that I am really new to creating custom controls, so I do not know all of the ins-and-outs of the whole process.
I am creating a custom control that functions similarly to a checkbox, but uses two images as checked/unchecked. I am trying to add a Text property, but it gives me this warning:
Property Text() As String
Get
Return ControlText.Text
End Get
Set(ByVal value As String)
ControlText.Text = value
End Set
End Property
"property 'Text' shadows an overridable method in the base class 'UserControl'. To override the base method, this method must be declared 'Overrides'."
Ok, so that is no problem. I change my declaration to Overrides Property Text() As String, but when I go to test it out 'text' is not listed under properties. Is there additional steps I need take to get my result?
More details
My control consists of 2 (or 3, depending on how you look at it):
PictureBox - Displays a checked/unchecked image
Label - The Text that is being displayed on the control
PictureCheckBox - This is the actual control's name
The PictureBox is docked to the left of the PictureCheckBox, and the Label is docked on the right side:
EDIT Scratched the bit about Text being non-virtual. It is in fact virtual / overridable.
But I'm curious, why do you want to do this. In your specific example you're just calling into the base property so it doesn't appear to do anything.
Where are you expecting this value to be shown and how are you setting it?
Text is a non-virtual / overridable method on Control. There is no way for you to override the property. If you want to re-define the property you can use the Shadows keyword.
You should make sure it's a public property
Public Overridable Property Text() As String
Get
Return ControlText.Text
End Get
Set(ByVal value As String)
ControlText.Text = value
End Set End Property
This might be a stupid question, but some of them still needs to be asked just to make sure:
Have you compiled since you made the changes? Using hotkeys in Visual Studio, press [Ctrl]+[Shift]+[b] to compile the entire solution.