How to change default property of a custom Control - vb.net

The default property of my custom button is Text.I want to change to a custom property named MaximumClicks
Public Property MaximumClicks As Integer
Get
Return maxClick
End Get
Set(value As Integer)
maxClick = value
End Set
End Property

You can apply the DefaultPropertyAttribute to your class:
<DefaultProperty("MaximumClicks")> _
Public Class CustomButton
Inherits Button
Public Property MaximumClicks As Integer
Get
' etc

Related

.NET inherited label doesn't autosize

I'd like to inherit from Windows.Forms.Label, so I've made something like that:
Public Class CustomLabel
Inherits Label
Public Property CustomText As String
Protected Property DefaultText as
Public Overrides Property Text As String
Get
Return If(CustomText <> "", CustomText, MyBase.Text)
End Get
Set(value As String)
MyBase.Text = value
End Set
End Property
End Class
The issue is using this, even if AutoSize property is still true, the label keep it's original size whatever the value set to CustomText.
So I thought that Mybase.Text property isn't updated when CustomText is set to I've changed to :
Public Class CustomLabel
Inherits Label
Public Property CustomText As String
Get
Return _txt
End Get
Set(value As String)
_txt = value
MyBase.Text = value
End Set
End Property
Protected _txt As String
Protected Property DefaultText As String
Public Overrides Property Text As String
Get
Return If(CustomText <> "", CustomText, DefaultText)
End Get
Set(value As String)
DefaultText = value
End Set
End Property
End Class
But still the same issue.
And, on the other side, when I set the Text property on a standard Label in the same place in the code where I set my CustomLabel, the autosize works.
Any idea ? Thanks
After some other tries, I've check how the TextChanged event is raised. It appears that the control is firstly initialized by the designer, and the CustomText is set to nothing, and as expected the TextChanged event is raised.
However, later in the code when CustomText property is set to the wanted value, I don't know why, but the event is not raised, even if the string is strictly different.
So to get a working code I have to write:
Public Property CustomText As String
Get
Return _txt
End Get
Set(value As String)
_txt = value
OnTextChanged(EventArgs.Empty) 'instead of Mybase.Text = value
End Set
End Property
To force the event and then trigger the label resize.
So it looks as solved, but if anyone has an explanation, I'd be happy to know it.

Set default value to an image "Public Property"

I try to set default value to an image Public Property of a UserControl. I tried to do that with a variable but I get an error Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.
Private Image_ As Image = My.Resources.MyImage
<Category("Appearance")> <DisplayName("Image")> <DefaultValue(Image_)> <Description("...")>
Public Property Image As Image
Get
Return NestedControl.Image
End Get
Set(ByVal value As Image)
NestedControl.Image = value
End Set
End Property
I also tried to set default value like this <DefaultValue(GetType(Image), "My.Resources.MyImage")> but when I do reset to UserControl's property it turns to "None"!!!
Any idea?
While the System.ComponentModel.DefaultValueAttribute does not support this, you can use the old-style ResetPropertyName and ShouldSerializePropertyName methods to achieve the same function.
This is documented in Defining Default Values with the ShouldSerialize and Reset Methods.
Imports System.ComponentModel
Public Class MyUserControl
Private Image_ As Image = My.Resources.MyImage
Public Sub New()
InitializeComponent()
ResetImage() ' set default
End Sub
<Category("Appearance")> <DisplayName("Image")> <Description("...")>
Public Property Image As Image
Get
Return NestedControl.Image
End Get
Set(ByVal value As Image)
NestedControl.Image = value
End Set
End Property
Public Sub ResetImage()
If Image IsNot Nothing Then Image.Dispose()
Image = Image_
End Sub
Public Function ShouldSerializeImage() As Boolean
Return (Image IsNot Image_)
End Function
End Class

How to do a collection property inside another collection in user control

I have a user control with a property "Rules" that is a generic list.
Every "rule" is associated to a combobox control and i have to create a property to host data for the combobox. I used another generic list to accomplish this.
In design works well, i can add items normally in property grid, but when i run the program the values are not maintained.
Rules property:
Private _regras As New List(Of ParametrosColunasGrid)
<Category("Ecletica")> _
<Browsable(True)> _
<System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content)>
Public Property Regras() As List(Of ParametrosColunasGrid)
Get
Return _regras
End Get
Set(value As List(Of ParametrosColunasGrid))
_regras = value
End Set
End Property
Public Class ParametrosColunasGrid
'...
Private _itens_Combo As New List(Of ItemComboBox)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property ItensCombo As List(Of ItemComboBox)
Get
Return _itens_Combo
End Get
Set(value As List(Of ItemComboBox))
_itens_Combo = value
End Set
End Property
'...
End Class
ItemComboBox Class:
<Serializable()>
Public Class ItemComboBox
Public Property Value As String
Public Property Key As String
Public Overrides Function ToString() As String
Return _Value
End Function
End Class

Custom CollectionEditor never triggers a property's "set" method

I am trying to implement a way of persisting a collection in a custom settings class. I have successfully created the settings class (inheriting ApplicationSettingsBase) and can save properties using the built-in editors on a PropertyGrid, but my custom implementation of a property grid for collections doesn't persist any of the values I add. Here's my code:
Imports System.Configuration
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.ComponentModel.Design
Public Class CustomSettings
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
<UserScopedSetting()> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
<Editor(GetType(CustomStringCollectionEditor), GetType(UITypeEditor))> _
Public Property EmailAddresses() As Collection
Get
EmailAddresses = Me("EmailAddresses")
End Get
Set(ByVal value As Collection)
Me("EmailAddresses") = value
End Set
End Property
End Class
Public Class CustomStringCollectionEditor
Inherits CollectionEditor
Public Sub New()
MyBase.New(GetType(Collection))
End Sub
Protected Overrides Function CreateInstance(ByVal itemType As System.Type) As Object
Return String.Empty
End Function
Protected Overrides Function CreateCollectionItemType() As System.Type
Return GetType(String)
End Function
End Class
I set a breakpoint on the Set methods for both the BackgroundColor property and the EmailAddresses property. The BackgroundColor property works as it should - it breaks on the Set statement and stores the property correctly. But when I close the custom CollectionEditor dialog, the EmailAddresses "Set" method is never called. How can I get my custom editor to actually save the property once it's done being edited?
I think I fixed it (with help from this question). I added an override to the EditValue function in my custom editor. Here is the code:
Public Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
Dim result As Object = MyBase.EditValue(context, provider, value)
DirectCast(context.Instance, CustomSettings).EmailAddresses = DirectCast(result, List(Of String))
Return result
End Function
I also moved from a collection to a list - I read somewhere that was a safer way to go. I also added a constructor to my CustomSettings class that set the EmailAddresses property to a new List(Of String) if it was unset to begin with. I found that the first time it ran, I could edit the list and add items, but they wouldn't be persisted:
Public Sub New()
If Me("EmailAddresses") Is Nothing Then
Me("EmailAddresses") = New List(Of String)
End If
End Sub
And now it's all working like it should. But if this isn't the best way or there's an easier way to do it, please chime in.

Why does the text property overridden in user control is not showing at design time

I have a usercontrol which overrides the property Text. But this property is not shown at design time.
If I rename it to caption or value it is shown in properties at design time but Text is not shown.
public Class SomeControl
Inherits System.Windows.Forms.UserControl
Public Overrides Property Text() As String
Get
Return lblText.Text
End Get
Set(ByVal value As String)
lblText.Text = value
End Set
End Property
End Class
What to do?
Added following attributes and the problem is solved.
<EditorBrowsable(EditorBrowsableState.Always)> _
<Browsable(True)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
<Bindable(True)> _
Public Overrides Property Text() As String
Get
Return lblText.Text
End Get
Set(ByVal value As String)
lblText.Text = value
End Set
End Property
The Text property is defined as:
[Bindable(false), EditorBrowsable(EditorBrowsableState.Never), Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
Meaning, you can't browse it in the property window; you need to override the property attributes defined here (which I don't know if that will work as expected) or just set the property name to something else.
HTH.