Add Property to Properties Window - .net-4.0

I have built a UserControl class and am exposing certain properties to the parent object.
When i drag and drop the component to the parent objects designer surface, i get the effect i need (per say). What i want to further develop is the ability to pre-fill the property value (in properties window) as a default but it isnt auto-populating as i would have expected.
Here is what i have so far:
<Browsable(True), Category("Data"),
DefaultValue("01/01/1990")>
Public Property [Date] As String
Get
Return Me._dt
End Get
Set(value As String)
Me._dt = value
dtValue.Text = value
End Set
End Property
I understand that DefaultValueAttribute assigns the value if no other assignments are made, but thought it would also place that value in the field in the Properties Window.
As well, this ultimate assignment will go up one more level as a collection, so any advise or URL's for how to make a Collection of Components available via Properties Window?

I understand that DefaultValueAttribute assigns the value if no other assignments are made
That is incorrect.
The DefaultValueAttribute is just metadata that tells the designer what the default is.
It is still up to your code to ensure that the property actually gets that value.

Related

Property Default Value does not work for a new control

I have a custom user control which expands and collapses. I have to have a second "open width" property that has to be set separately from the normal width property.
When I collapse the control, it makes the width 10. When I expand the control, it returns the control width back to the "open width" property, which has to be manually set to the normal width when the control is created.
The default new width on the control is 200, so for consistency I want to set the default "open width" property to 200 as well. So I have the following:
Private _mSideBarOpenWidth As Integer
<EditorBrowsable(EditorBrowsableState.Always)>
<Browsable(True)>
<DesignerSerializationVisibility( _
DesignerSerializationVisibility.Visible)>
<DefaultValue(200)>
<Category("SideBar")>
<Description("Sets the open Width of the SideBar control.")>
Public Property SideBarOpenWidth() As Integer
Get
Return _mSideBarOpenWidth
End Get
Set(value As Integer)
_mSideBarOpenWidth = value
End Set
End Property
When I drag a new control onto the form the default value is always 0. If I change it the value does persist, it just will not start at 200. I have done quite a bit of searching on this issue and I have tried the following:
cleaning/building/rebuilding the project
closing VisualStudio and opening it back up
deleting the form and creating a new one
using the control in a new project
setting <em>DesignerSerializationVisibility.Visible</em> to <em>.Content</em>
using <em>"200"</em> with the quotes as the default value
And various combinations of all those. None of that works and the default value on a new control dragged onto the form goes to zero. Needless to say I am at a loss on why the default value will not get set to 200 when it is created.
The only time I am even accessing the property is when I am setting the width of the control Me.Width = SideBarOpenWidth
it just will not start at 200
That is not what DefaultValue does. VS uses the DefaultValue to determine whether or not the current value differs from the default and so, should be serialized and show the property value in Bold in the Property IDE. It doesn't set the value. A remark from MSDN:
A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code.
Attributes provide information about a class, property etc. Your property doesnt know about the DefaultValue attribute and they don't interact without code you add.
Instead, they specify information about the class or property (etc) to other things (designers, serializers etc). For instance, which Editor or TypeConverter to use. A good example is the Description or Category attributes - these provide information about your properties to VS which it uses in the Properties pane in the IDE.

What does Property Let means in VB?

I have often come across code that looks like this.
Public Property Get MyProperty() As String
MyProperty = m_MyProperty
End Property
Public Property Set MyProperty(ByVal value As String)
m_MyProperty = value
End Property
Or even:
Public Property Get MyProperty() As String
Return m_MyProperty
End Property
And I had never ever met with this.
Public Property Let MyProperty(ByVal value As String)
m_MyProperty = value
End Property
Is the Let keyword the same as Set ?
According to this post, it seems so.
Properties in VB
MSDN states:
Property Let Statement
Declares the name, arguments, and code that form the body of a Property Let procedure, which assigns a value to a property.
Property Set Statement
Declares the name, arguments, and code that form the body of a Property procedure, which sets a reference to an object.
In addition to it, as per MSDN definition:
Property
A named attribute of a control, field, or object that you set to define one of the object's characteristics (such as size, color, or screen location) or an aspect of its behavior (such as whether the object is hidden).
Object
Objects seen in a Microsoft Access database:
tables, queries, forms, reports, macros, and modules
objects that are defined by the system, such as the MSysObjects table
Objects seen in a Microsoft Access project:
objects stored in the Access project file: forms, reports, macros, and modules
objects stored in the Microsoft SQL Server database: tables, table properties (such as > - indexes, triggers, keys, constraints, defaults, rules, and user-defined data types), views, stored procedures, and database diagrams
objects defined by the system, such as the sysindexes table
Objects seen in both Access databases and Access projects:
data access pages, which are shortcuts (displayed in the Database window) to corresponding HTML files stored in the file system
information from another application, such as a chart (graph) or a drawing
Except that the context under which I have seen the Property Let Statement used, there is no Access or whatsoever else.
Thanks for the received comments. They guided me to MSDN, though I still can't get the meaning of the Let statement, apart that it might be interchangeable with the Set statement, as I see it.
Are they both really interchangeable?
You pretty much answered your own question.
As you can see from the MSDN docs, a Let declaration for a property is used to assign a value, i.e. to be used for any datatype except for objects (for which you would normally assign through Set anyway).
So, following the same logic, a Set declaration would be used if you want/need to be able to assign objects, and only objects (typed or not) to a property.
So, let's say you have:
Property Let MyFirstProperty(NewValue As String)
m_sMyFirstProperty = NewValue
End Property
Property Set MySecondProperty(NewValue As Object)
Set m_oMySecondProperty = NewValue
End Property
Then the following won't work:
' This won't work
MyFirstProperty = CreateObject("...")
' Neither will this
Set MyFirstProperty = CreateObject("...")
' Also, the following won't be allowed
MySecondProperty = "My new string"
But the following two statements will:
MyFirstProperty = "My new string"
Set MySecondProperty = CreateObject("...")
Note that you can have both a Let and Set declarations for the same property at the same time, depending on what you want to do:
You could handle objects being assigned to the property differently (through the Set declare) than for other datatypes (using the Let);
Or, if your internal variable for the property is a Variant, and you want to allow both objects and scalar values to be assigned to the property.
In short, then:
If you want to assign values to a property (everything but objects), add a Let handler for the property.
If you want to assign objets to a property, you'll need a Set handler for the property.

Custom property not being set in code-behind

I have a boolean custom property. The property changes the behavior of the Form, and needs to be executed for intended behavior. However, if the property is False, it's not being set in the auto-generated code-behind (since the default value is False, the code-behind generator must think it's not necessary to set it). It seems that if I set the attribute on the property: [DefaultValue(True)] it will generate code-behind saying MyProperty = False, but then it won't do it for True property values. I wish to find a way for the property to always be set in code-behind, no matter what the property's value.
It seems my only alternatives are adding in Sub New()
Me.MyProperty = Me.MyProperty
Or else turning the property into an enum, which I don't like either.
It seems that the DefaultValueAttribute controls for which values something will be generated and set in code-behind, but I can't figure out a way to make it always generate code-behind. I was hoping setting an invalid DefaultValueAttribute would, but that just seems to make the designer use the last value.

Property encapsulation inserting code automatically, but I don't want it there?

I'm making a public property, and it keeps inserting a snippet of code. What is this code for? And how come it doesn't happen to my other public properties?
Specifically the snippet:
Set(value As ObjectName())
Here's the full public property code:
Public Property PropertyName() As ObjectName()
Get
Return Me.propertyName
End Get
Set(value As ObjectName())
Me.propertyName = value
End Set
End Property
When I try deleting
(value As ObjectName())
It keeps coming back. But my other properties, that snippet of code doesn't automatically generate...
When you have a property, you need a get and set (unless it is readonly).
The get part is for when other code tries to access the value of the property. The set part is for when other code tries to write the value of the property. The (value As ObjectName()) part is simply the definition of parameter expected.
It will generate for your other properties too, if you were to start typing to define them. Visual Studio is decent at leaving existing code alone. If you already have a property definition, it won't add it.
Again, if you have a ReadOnly property, there will be no set method.

Class-level Static Variable per Instance

I'm trying to do the following:
I need a static variable to get a ListItemCollection from a List control (I can do this, but if I don't set it as Shared It's not preserving the values as it should). The thing is that this class is a SharePoint webpart, so I most probably will be using the webpart more than once, and I need this variable to be unique to each webpart, which shared doesn't accomplish.
I tried everything you can imagine. I placed a Static variable within a Sub (shared and not shared), I tried it with Properties (also Shared and not shared)...
Any Ideas are welcome.
Thanks.
By definition, static members are per-class (or per-thread with a ThreadStatic attribute).
If you need to save the property on the webpart, add the WebPartStorageAttribute on the property, also throw on a FriendlyNameAttribute on there to make it clean:
C# Version:
[FriendlyNameAttribute("What the setting will be called")]
[WebPartStorage(Storage.Shared)]
private string MyStringThatGetsSaved { get; set; }
VB.Net Version:
<WebPartStorage(Storage.Personal), FriendlyNameAttribute("What the setting will be called")>
Private mMyStringThatGetsSaved As String
Public Property MyStringThatGetsSaved () As String
Get
Return mMyStringThatGetsSaved
End Get
Set(ByVal Value As String)
mMyStringThatGetsSaved = Value
End Set
End Property
Is this what you're after? If not can you clarify a bit further?
I finally went on another way, I just added some checkboxes to the toolpart and setted the properties on the webpart.
Anyway, what I was trying to do is:
Have a Web Part that changes its controls on Edit & Browse mode. In Edit mode I show two ListBox controls, two buttons (add, remove). When I click the add button, the value has to be removed from the left ListBox and be added to the right ListBox, so far so good I was able to make this functionality with no problems... The thing is when I go back to Browse mode I need to use the items in the ListBox from the right to show (so I added a ListItemCollection control that would store the values from the ListBox on the right), the text of the item and a TextBox control, then the user would enter their text in that textbox and hit the "Search" button and a search query would be executed.
My problem is that when I go from Edit to Browse the ListItemCollection variable I added is getting restarted. So I declared it as Shared, and that does work, but when I add a new instance of the WebPart, they have the same fields displayed... I don't know if there is a way of doing a Static Class-Level variable that is unique to each instance, so I went the ToolPart way...