Reputation: 20464
I inherited the System.Windows.Forms.Form
class, then I shadowed the Form.Opacity
property.
In my scenario, the acceptable opacity value must be between 0% and 99%, and for this I just tried to auto-fix the provided value with a simple conditional, however, I still can set the opacity to 100% in the designer's property grid:
This is the code I'm using:
VB.NET:
Public Class HUDForm : Inherits Form
<Browsable(True)>
<Category("Window Style")>
<Description("The opacity level of this HUDForm.")>
<EditorBrowsable(EditorBrowsableState.Always)>
Public Shadows Property Opacity As Double
Get
Return MyBase.Opacity
End Get
Set(ByVal value As Double)
If (value >= 1.0R) Then
value = 0.99R
End If
MyBase.Opacity = value
End Set
End Property
End Class
C# (online translation):
public class HUDForm : Form {
[Browsable(true)]
[Category("Window Style")]
[Description("The opacity level of this HUDForm.")]
[EditorBrowsable(EditorBrowsableState.Always)]
public new double Opacity {
get { return base.Opacity; }
set {
if (value >= 1.0) {
value = 0.99;
}
base.Opacity = value;
}
}
}
Upvotes: 0
Views: 1438
Reputation: 11801
The Form
's designer is the controlling factor as it is handling the validation of the Opacity property as well as several other properties. You will need to create a custom DocumentDesigner Class and set the DesignerAttribute on your HUDForm Class. For the official word on extending design time support, see: Extending Design-Time Support.
The class System.Windows.Forms.Design.FormDocumentDesigner
is the specified designer for the Form
class. This designer is inherited when your class inherits from the Form
class. FormDocumentDesigner
ultimately inherits from ComponentDesigner Class. A designer may provide alternate property implementations that are in effect during design. It does so by modifying the PropertyDescriptors that are sent to the VS designer's propertygrid. This modification is done in the PreFilterProperties
method. In this case, alternate property definitions are provide for the Opacity, Menu, IsMdiContainer, Size, ShowInTaskBar, WindowState, AutoSize, AcceptButton, and and CancelButton properties.
As you can not inherit from System.Windows.Forms.Design.FormDocumentDesigner
, you would need to re-implement this class with your desired function.
Here is a very abbreviated custom DocumentDesigner that will provide the specific functionality you want only for demonstration of the technique. You will need to re-implement the reset of the function provided by the System.Windows.Forms.Design.FormDocumentDesigner
class.
Imports System.ComponentModel
Public Class myDocDesigner
Inherits System.Windows.Forms.Design.DocumentDesigner
Private Property Opacity As Double
Get
Return CDbl(MyBase.ShadowProperties.Item("Opacity"))
End Get
Set(ByVal value As Double)
If (value >= 0.99R) Then
value = 0.99R
End If
MyBase.ShadowProperties.Item("Opacity") = value
End Set
End Property
Protected Overrides Sub PreFilterProperties(ByVal properties As IDictionary)
Dim descriptor As PropertyDescriptor
MyBase.PreFilterProperties(properties)
Dim strArray As String() = New String() {"Opacity"}
Dim attributes As Attribute() = {}
Dim i As Integer
For i = 0 To strArray.Length - 1
descriptor = DirectCast(properties.Item(strArray(i)), PropertyDescriptor)
If (Not descriptor Is Nothing) Then
properties.Item(strArray(i)) = TypeDescriptor.CreateProperty(GetType(myDocDesigner), descriptor, attributes)
End If
Next i
End Sub
End Class
You would decorate your custom form like this:
Imports System.ComponentModel
Imports System.ComponentModel.Design
<Designer(GetType(myDocDesigner), GetType(IRootDesigner))>
Public Class HUDForm : Inherits Form
End Class
You will need a project reference to System.Design.dll
.
Alternate Solution
After thinking this over a bit more, I realized that the OP's constraint is more restrictive of the value than that coded in FormDocumentDesigner
, yet still satisfies those constraints. The default Opacity property has multiple checks on its allowed range. The simplest one to override is the TypeConverter applied to the property. The base implementation uses the OpacityConverter Class and the following TypeConverter is derived from that implementation.
Imports System.Globalization
Imports System.ComponentModel
Public Class OpacityConverter2
Inherits TypeConverter
Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
Return ((sourceType Is GetType(String)) OrElse MyBase.CanConvertFrom(context, sourceType))
End Function
Public Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object) As Object
If Not TypeOf value Is String Then
Return MyBase.ConvertFrom(context, culture, value)
End If
Dim currentValueAsString As String = CStr(value).Replace("%"c, " "c).Trim
Dim parsedValue As Double = Double.Parse(currentValueAsString, CultureInfo.CurrentCulture)
If (((CStr(value).IndexOf("%") > 0) AndAlso (parsedValue >= 0)) AndAlso (parsedValue <= 1)) Then
currentValueAsString = (parsedValue / 100).ToString(CultureInfo.CurrentCulture)
End If
Dim returnValue As Double = 0
Try
returnValue = CDbl(TypeDescriptor.GetConverter(GetType(Double)).ConvertFrom(context, culture, currentValueAsString))
If (returnValue > 1) Then
returnValue = (returnValue / 100)
End If
Catch exception As FormatException
Throw New FormatException("Valid Range - 0 to 99%", exception)
End Try
If ((returnValue >= 0) AndAlso (returnValue <= 0.99)) Then
Return returnValue
Else
Throw New FormatException("Valid Range - 0 to 99%")
End If
End Function
Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
If (destinationType Is Nothing) Then
Throw New ArgumentNullException("destinationType")
End If
If (destinationType Is GetType(String)) Then
Dim num As Double = CDbl(value)
Dim num2 As Integer = CInt((num * 100))
Return (num2.ToString(CultureInfo.CurrentCulture) & "%")
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
End Class
Usage:
Imports System.ComponentModel
Imports System.ComponentModel.Design
Public Class HUDForm : Inherits Form
<TypeConverter(GetType(OpacityConverter2))>
<Browsable(True)>
<Category("Window Style")>
<Description("The opacity level of this HUDForm.")>
<EditorBrowsable(EditorBrowsableState.Always)>
Public Shadows Property Opacity As Double
Get
Return MyBase.Opacity
End Get
Set(ByVal value As Double)
If (value >= 1.0R) Then
value = 0.99R
End If
MyBase.Opacity = value
End Set
End Property
End Class
Upvotes: 2