M
M West
trying to write a user control that will implement a custom property which
will allow the user to expand into three sub properties as shown
+ MaskColor
ColorRed
ColorGreen
ColorBlue
would appear in the property grid
i have looked at samples on msdn and code project but when adding the
control to a test form the property is not working at all and i only see
MaskColor and can only enter a string, have compared code to samples but see
no obvious differences
I enclose code for the user control MyTrans, the property i am interested in
is MaskedColor which is of type Mask Color, and the custom class MaskColor
(including the type definitions)
am I missing something or I am unable to do this ???
cheers Mark
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Region
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Windows.Forms.Design
<System.ComponentModel.DefaultProperty("OriginalImage")> Public Class
MaskTrans
Inherits System.Windows.Forms.PictureBox
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'UserControl1 overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
'MaskTrans
'
Me.BackColor = System.Drawing.Color.Transparent
Me.Size = New System.Drawing.Size(45, 75)
End Sub
#End Region
Dim imgMainImage As Image
Dim imgMaskImage As Image
Dim clrMaskColor As MaskColor
Dim clrRed As Integer
Dim blnMainImageEntered As Boolean
Dim blnMaskImageEntered As Boolean
Dim blnMaskColorEntered As Boolean
' Ensure that the BackColor remains transparent otherwise will see colour
' rather than the expected Background Graphic.
<Browsable(False)> _
Public Overrides Property BackColor() As Color
Get
' Do nothing as we have set this in the initialize component section
End Get
Set(ByVal Value As System.Drawing.Color)
' Do Nothing
End Set
End Property
' Ensure that the BackgroundImage is not set as they may conflict with
' the transparency and also the applied Background Graphic.
<Browsable(False)> _
Public Overrides Property BackgroundImage() As Image
Get
' Do nothing as we have set this in the initialize component section
End Get
Set(ByVal Value As System.Drawing.Image)
' Do Nothing
End Set
End Property
'<Editor(GetType(MaskColorRGBEditor), GetType(UITypeEditor)), _
'Category("Appearance"), Description("Define the mask colour that will be
applied to the image.")> _
<Category("Appearance")> _
Public Property MaskedColor() As MaskColor
Get
Return clrMaskColor
End Get
Set(ByVal Value As MaskColor)
clrMaskColor = Value
End Set
End Property
<Category("Appearance"), Description("The Image that defines the
transparency to be implemented, as defined by the mask color.")> _
Public Property MaskedImage() As Image
Get
Return imgMaskImage
End Get
Set(ByVal Value As Image)
imgMaskImage = Value
blnMaskImageEntered = True
ValidateUserEntries()
End Set
End Property
<Category("Appearance"), Description("The Image that will be made
transparent.")> _
Public Property OriginalImage() As Image
Get
Return imgMainImage
End Get
Set(ByVal Value As Image)
imgMainImage = Value
blnMainImageEntered = True
ValidateUserEntries()
End Set
End Property
Private Sub ValidateUserEntries()
If blnMainImageEntered And blnMaskImageEntered Then
TransformImage()
End If
End Sub
Private Sub TransformImage()
Dim bmpCardBitmap As New Bitmap(OriginalImage)
Dim bmpMaskBitmap As New Bitmap(MaskedImage)
Dim bmpMerge As Bitmap
Dim cropImage As Image
Dim clrTransMaskColor As Color = Color.FromArgb(0, 255, 0)
Dim grMain As Graphics = Graphics.FromImage(bmpMaskBitmap)
bmpCardBitmap.MakeTransparent(Color.White)
grMain.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
grMain.DrawImage(bmpCardBitmap, 0, 0, bmpCardBitmap.Width,
bmpCardBitmap.Height)
grMain.Dispose()
Me.Region = SkinRegion(bmpMaskBitmap, clrTransMaskColor)
End Sub
Private Function SkinRegion(ByVal image As Bitmap, ByVal TransKey As Color)
As Region
Dim BaseRegion As New Region(New RectangleF(0, 0, image.Width,
image.Height))
Dim x, y As Integer
Dim sx, sy As Integer
Dim IsExcludeRegion As Boolean = False
Dim IsTransparent As Boolean = False
Dim HoldColor As New Color
For y = 0 To image.Height - 1
For x = 0 To image.Width - 1
HoldColor = image.GetPixel(x, y)
IsTransparent = (HoldColor.R = TransKey.R And HoldColor.G = TransKey.G And
HoldColor.B = TransKey.B)
If IsTransparent And Not IsExcludeRegion Then
sx = x
sy = y
IsExcludeRegion = True
ElseIf Not IsTransparent And IsExcludeRegion Then
BaseRegion.Exclude(New Rectangle(sx, sy, x + 1 - sx, y + 1 - sy))
MessageBox.Show("rect " & sx & "," & sy & "," & x + 1 - sx & "," & y + 1 -
sy)
IsExcludeRegion = False
End If
Next
If IsExcludeRegion Then
BaseRegion.Exclude(New Rectangle(sx, sy, x + 1 - sx, y + 1 - sy))
MessageBox.Show("rect " & sx & "," & sy & "," & x + 1 - sx & "," & y + 1 -
sy)
IsExcludeRegion = False
End If
Next
HoldColor = Nothing
SkinRegion = BaseRegion
BaseRegion = Nothing
End Function
End Class
---- custom class and type converter class
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization
<TypeConverter(GetType(MaskColorConverter)), _
DescriptionAttribute("Expand to see the available Color attributes to define
the mask that will be applied to the image.")> _
Public Class MaskColor
Private clrRed As Short
Private clrGreen As Short
Private clrBlue As Short
<DefaultValueAttribute(0), DescriptionAttribute("Red color portion of the
Mask Colour")> _
Public Property ColorRed() As Short
Get
Return clrRed
End Get
Set(ByVal Value As Short)
clrRed = Value
End Set
End Property
<DefaultValueAttribute(255), DescriptionAttribute("Green color portion of
the Mask Colour")> _
Public Property ColorGreen() As Short
Get
Return clrGreen
End Get
Set(ByVal Value As Short)
clrGreen = Value
End Set
End Property
<DefaultValue(0), Description("Blue color portion of the Mask Colour")> _
Public Property ColorBlue() As Short
Get
Return clrBlue
End Get
Set(ByVal Value As Short)
clrBlue = Value
End Set
End Property
End Class
Friend Class MaskColorConverter
Inherits ExpandableObjectConverter
Public Overloads Overrides Function CanConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal destinationType As Type) As Boolean
If (destinationType Is GetType(MaskColor)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, destinationType)
End Function
Public Overloads Overrides Function ConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, _
ByVal value As Object, _
ByVal destinationType As System.Type) As Object
If (destinationType Is GetType(System.String) AndAlso _
TypeOf value Is MaskColor) Then
Dim MaskCol As MaskColor = CType(value, MaskColor)
' build the color string as Red, Green and Blue
Return MaskCol.ColorRed & "," & MaskCol.ColorGreen & "," & MaskCol.ColorBlue
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
Public Overloads Overrides Function CanConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal sourceType As System.Type) As Boolean
If (sourceType Is GetType(String)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function
Public Overloads Overrides Function ConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, _
ByVal value As Object) As Object
If TypeOf value Is String Then
Try
Dim s As String = CType(value, String)
Dim ColorParts() As String
Dim ColorString As String = ""
ColorParts = Split(s, ",")
If Not IsNothing(ColorParts) Then
Dim MaskCol As MaskColor = New MaskColor
If Not IsNothing(ColorParts(0)) Then
MaskCol.ColorRed = CType(ColorParts(0), Short)
End If
If Not IsNothing(ColorParts(1)) Then
MaskCol.ColorGreen = CType(ColorParts(1), Short)
End If
If Not IsNothing(ColorParts(2)) Then
MaskCol.ColorBlue = CType(ColorParts(2), Short)
End If
End If
Catch ex As Exception
Throw New ArgumentException("Can not convert '" & CType(value, String) & _
"' to type MaskColor")
End Try
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
End Class
will allow the user to expand into three sub properties as shown
+ MaskColor
ColorRed
ColorGreen
ColorBlue
would appear in the property grid
i have looked at samples on msdn and code project but when adding the
control to a test form the property is not working at all and i only see
MaskColor and can only enter a string, have compared code to samples but see
no obvious differences
I enclose code for the user control MyTrans, the property i am interested in
is MaskedColor which is of type Mask Color, and the custom class MaskColor
(including the type definitions)
am I missing something or I am unable to do this ???
cheers Mark
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Region
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.Windows.Forms.Design
<System.ComponentModel.DefaultProperty("OriginalImage")> Public Class
MaskTrans
Inherits System.Windows.Forms.PictureBox
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'UserControl1 overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
'MaskTrans
'
Me.BackColor = System.Drawing.Color.Transparent
Me.Size = New System.Drawing.Size(45, 75)
End Sub
#End Region
Dim imgMainImage As Image
Dim imgMaskImage As Image
Dim clrMaskColor As MaskColor
Dim clrRed As Integer
Dim blnMainImageEntered As Boolean
Dim blnMaskImageEntered As Boolean
Dim blnMaskColorEntered As Boolean
' Ensure that the BackColor remains transparent otherwise will see colour
' rather than the expected Background Graphic.
<Browsable(False)> _
Public Overrides Property BackColor() As Color
Get
' Do nothing as we have set this in the initialize component section
End Get
Set(ByVal Value As System.Drawing.Color)
' Do Nothing
End Set
End Property
' Ensure that the BackgroundImage is not set as they may conflict with
' the transparency and also the applied Background Graphic.
<Browsable(False)> _
Public Overrides Property BackgroundImage() As Image
Get
' Do nothing as we have set this in the initialize component section
End Get
Set(ByVal Value As System.Drawing.Image)
' Do Nothing
End Set
End Property
'<Editor(GetType(MaskColorRGBEditor), GetType(UITypeEditor)), _
'Category("Appearance"), Description("Define the mask colour that will be
applied to the image.")> _
<Category("Appearance")> _
Public Property MaskedColor() As MaskColor
Get
Return clrMaskColor
End Get
Set(ByVal Value As MaskColor)
clrMaskColor = Value
End Set
End Property
<Category("Appearance"), Description("The Image that defines the
transparency to be implemented, as defined by the mask color.")> _
Public Property MaskedImage() As Image
Get
Return imgMaskImage
End Get
Set(ByVal Value As Image)
imgMaskImage = Value
blnMaskImageEntered = True
ValidateUserEntries()
End Set
End Property
<Category("Appearance"), Description("The Image that will be made
transparent.")> _
Public Property OriginalImage() As Image
Get
Return imgMainImage
End Get
Set(ByVal Value As Image)
imgMainImage = Value
blnMainImageEntered = True
ValidateUserEntries()
End Set
End Property
Private Sub ValidateUserEntries()
If blnMainImageEntered And blnMaskImageEntered Then
TransformImage()
End If
End Sub
Private Sub TransformImage()
Dim bmpCardBitmap As New Bitmap(OriginalImage)
Dim bmpMaskBitmap As New Bitmap(MaskedImage)
Dim bmpMerge As Bitmap
Dim cropImage As Image
Dim clrTransMaskColor As Color = Color.FromArgb(0, 255, 0)
Dim grMain As Graphics = Graphics.FromImage(bmpMaskBitmap)
bmpCardBitmap.MakeTransparent(Color.White)
grMain.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
grMain.DrawImage(bmpCardBitmap, 0, 0, bmpCardBitmap.Width,
bmpCardBitmap.Height)
grMain.Dispose()
Me.Region = SkinRegion(bmpMaskBitmap, clrTransMaskColor)
End Sub
Private Function SkinRegion(ByVal image As Bitmap, ByVal TransKey As Color)
As Region
Dim BaseRegion As New Region(New RectangleF(0, 0, image.Width,
image.Height))
Dim x, y As Integer
Dim sx, sy As Integer
Dim IsExcludeRegion As Boolean = False
Dim IsTransparent As Boolean = False
Dim HoldColor As New Color
For y = 0 To image.Height - 1
For x = 0 To image.Width - 1
HoldColor = image.GetPixel(x, y)
IsTransparent = (HoldColor.R = TransKey.R And HoldColor.G = TransKey.G And
HoldColor.B = TransKey.B)
If IsTransparent And Not IsExcludeRegion Then
sx = x
sy = y
IsExcludeRegion = True
ElseIf Not IsTransparent And IsExcludeRegion Then
BaseRegion.Exclude(New Rectangle(sx, sy, x + 1 - sx, y + 1 - sy))
MessageBox.Show("rect " & sx & "," & sy & "," & x + 1 - sx & "," & y + 1 -
sy)
IsExcludeRegion = False
End If
Next
If IsExcludeRegion Then
BaseRegion.Exclude(New Rectangle(sx, sy, x + 1 - sx, y + 1 - sy))
MessageBox.Show("rect " & sx & "," & sy & "," & x + 1 - sx & "," & y + 1 -
sy)
IsExcludeRegion = False
End If
Next
HoldColor = Nothing
SkinRegion = BaseRegion
BaseRegion = Nothing
End Function
End Class
---- custom class and type converter class
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization
<TypeConverter(GetType(MaskColorConverter)), _
DescriptionAttribute("Expand to see the available Color attributes to define
the mask that will be applied to the image.")> _
Public Class MaskColor
Private clrRed As Short
Private clrGreen As Short
Private clrBlue As Short
<DefaultValueAttribute(0), DescriptionAttribute("Red color portion of the
Mask Colour")> _
Public Property ColorRed() As Short
Get
Return clrRed
End Get
Set(ByVal Value As Short)
clrRed = Value
End Set
End Property
<DefaultValueAttribute(255), DescriptionAttribute("Green color portion of
the Mask Colour")> _
Public Property ColorGreen() As Short
Get
Return clrGreen
End Get
Set(ByVal Value As Short)
clrGreen = Value
End Set
End Property
<DefaultValue(0), Description("Blue color portion of the Mask Colour")> _
Public Property ColorBlue() As Short
Get
Return clrBlue
End Get
Set(ByVal Value As Short)
clrBlue = Value
End Set
End Property
End Class
Friend Class MaskColorConverter
Inherits ExpandableObjectConverter
Public Overloads Overrides Function CanConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal destinationType As Type) As Boolean
If (destinationType Is GetType(MaskColor)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, destinationType)
End Function
Public Overloads Overrides Function ConvertTo( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, _
ByVal value As Object, _
ByVal destinationType As System.Type) As Object
If (destinationType Is GetType(System.String) AndAlso _
TypeOf value Is MaskColor) Then
Dim MaskCol As MaskColor = CType(value, MaskColor)
' build the color string as Red, Green and Blue
Return MaskCol.ColorRed & "," & MaskCol.ColorGreen & "," & MaskCol.ColorBlue
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
Public Overloads Overrides Function CanConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal sourceType As System.Type) As Boolean
If (sourceType Is GetType(String)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function
Public Overloads Overrides Function ConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As CultureInfo, _
ByVal value As Object) As Object
If TypeOf value Is String Then
Try
Dim s As String = CType(value, String)
Dim ColorParts() As String
Dim ColorString As String = ""
ColorParts = Split(s, ",")
If Not IsNothing(ColorParts) Then
Dim MaskCol As MaskColor = New MaskColor
If Not IsNothing(ColorParts(0)) Then
MaskCol.ColorRed = CType(ColorParts(0), Short)
End If
If Not IsNothing(ColorParts(1)) Then
MaskCol.ColorGreen = CType(ColorParts(1), Short)
End If
If Not IsNothing(ColorParts(2)) Then
MaskCol.ColorBlue = CType(ColorParts(2), Short)
End If
End If
Catch ex As Exception
Throw New ArgumentException("Can not convert '" & CType(value, String) & _
"' to type MaskColor")
End Try
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
End Class