LinearGradientBrush properties and methods - two troubles

  • Thread starter Thread starter C
  • Start date Start date
C

C

I get this thing to work fine but I am writing very inefficient and
dirty code with LinearGradientBrush. Either something is missing in
VB.net or I am doing something wrong.

Trouble 1:

For example, I have written

Dim arrowBrush As System.Drawing.Drawing2D.LinearGradientBrush
= New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)

Dim arrowBrushV As
System.Drawing.Drawing2D.LinearGradientBrush = New
System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Vertical)

If hv <> 1 Then arrowBrush = arrowBrushV ' not horizontal =
vertical

This is because arrowBrush does not have a property called
LinearGradientMode. Is there a better way to do this? arrowBrush has a
horizontal gradient; arrowBrushV has a vertical. I define two brushes
and then set the first one to second if the arrow should be vertical
(hv not equal to 1).

Trouble 2:

Another thing that does not work is

arrowBrush.LinearColors(0) = arrowColor1
'Color.FromArgb(0, 201, 170)
arrowBrush.LinearColors(1) = arrowColor2 '
Color.FromArgb(255, 0, 0)

This seems to be a VB.net bug because it does not change the colours
at all.

arrowBrush.LinearColors = New Color() {arrowColor1,
arrowColor2}
works.

Question 3:

Do I need to dispose the brushes or do they disappear anyway at the
end of the subroutine?

The full subroutine is appended below. It works. Everyone is free to
use it.

Sub drawArrow(ByVal g As Graphics, ByVal hv As Short, ByVal
arrowStart As Point, ByVal arrowLength As Short, ByVal arrowThick As
Short, ByVal arrowWidth As Short, ByVal arrowColor1 As Color, ByVal
arrowColor2 As Color)

Dim arrowPoints(6) As Point
Dim rect As Rectangle = New Rectangle(10, 10, 6, 4)

If hv = 1 Then
rect.X = arrowStart.X
rect.Y = arrowStart.Y
rect.Height = arrowWidth
rect.Width = arrowLength + arrowThick + 1
Else
rect.X = arrowStart.X
rect.Y = arrowStart.Y
rect.Height = arrowLength + arrowThick + 1
rect.Width = arrowWidth
End If

Dim arrowBrush As System.Drawing.Drawing2D.LinearGradientBrush
= New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)
Dim arrowBrushV As
System.Drawing.Drawing2D.LinearGradientBrush = New
System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Vertical)
If hv <> 1 Then arrowBrush = arrowBrushV

' arrowBrush.LinearColors(0) = arrowColor1
'Color.FromArgb(0, 201, 170)
' arrowBrush.LinearColors(1) = arrowColor2 '
Color.FromArgb(255, 0, 0)
arrowBrush.LinearColors = New Color() {arrowColor1,
arrowColor2}

If hv = 1 Then ' horizontal

arrowPoints(0).X = arrowStart.X
arrowPoints(0).Y = arrowStart.Y - arrowThick / 2

arrowPoints(1).X = arrowPoints(0).X + arrowLength
arrowPoints(1).Y = arrowPoints(0).Y

arrowPoints(2).X = arrowPoints(1).X
arrowPoints(2).Y = arrowPoints(1).Y - (arrowWidth -
arrowThick) / 2

arrowPoints(3).X = arrowPoints(2).X + arrowThick
arrowPoints(3).Y = arrowStart.Y

arrowPoints(4).X = arrowPoints(2).X
arrowPoints(4).Y = arrowPoints(2).Y + arrowWidth

arrowPoints(5).X = arrowPoints(2).X
arrowPoints(5).Y = arrowStart.Y + arrowThick / 2

arrowPoints(6).X = arrowStart.X
arrowPoints(6).Y = arrowPoints(5).Y

Else

arrowPoints(0).X = arrowStart.X - arrowThick / 2
arrowPoints(0).Y = arrowStart.Y

arrowPoints(1).X = arrowPoints(0).X
arrowPoints(1).Y = arrowPoints(0).Y - arrowLength

arrowPoints(2).X = arrowPoints(1).X - (arrowWidth -
arrowThick) / 2
arrowPoints(2).Y = arrowPoints(1).Y

arrowPoints(3).X = arrowStart.X ' tip
arrowPoints(3).Y = arrowPoints(2).Y - arrowThick

arrowPoints(4).X = arrowPoints(2).X + arrowWidth
arrowPoints(4).Y = arrowPoints(2).Y

arrowPoints(5).X = arrowStart.X + arrowThick / 2
arrowPoints(5).Y = arrowPoints(2).Y

arrowPoints(6).X = arrowPoints(5).X
arrowPoints(6).Y = arrowStart.Y

End If

g.FillPolygon(arrowBrush, arrowPoints)

' g.DrawPolygon(Pens.White, arrowPoints)

Me.Invalidate()

End Sub
 
Am 03.09.2010 17:57, schrieb C:
I get this thing to work fine but I am writing very inefficient and
dirty code with LinearGradientBrush. Either something is missing in
VB.net or I am doing something wrong.

Trouble 1:

For example, I have written

Dim arrowBrush As System.Drawing.Drawing2D.LinearGradientBrush
= New System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Horizontal)

Dim arrowBrushV As
System.Drawing.Drawing2D.LinearGradientBrush = New
System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White,
Color.Black, System.Drawing.Drawing2D.LinearGradientMode.Vertical)

If hv <> 1 Then arrowBrush = arrowBrushV ' not horizontal =
vertical

This is because arrowBrush does not have a property called
LinearGradientMode. Is there a better way to do this? arrowBrush has a
horizontal gradient; arrowBrushV has a vertical. I define two brushes
and then set the first one to second if the arrow should be vertical
(hv not equal to 1).


Assuming System.Drawing is imported as by default:

Dim mode As Drawing2D.LinearGradientMode
Dim arrowBrush As Drawing2D.LinearGradientBrush

mode = If(hv = 1, Drawing2D.LinearGradientMode.Horizontal, Drawing2D.LinearGradientMode.Vertical)
arrowBrush = New Drawing2D.LinearGradientBrush(rect, Color.White, Color.Black, mode)

(note that the If-operator is used here, not the IIf function
or the If-statement)
Trouble 2:

Another thing that does not work is

arrowBrush.LinearColors(0) = arrowColor1
'Color.FromArgb(0, 201, 170)
arrowBrush.LinearColors(1) = arrowColor2 '
Color.FromArgb(255, 0, 0)

This seems to be a VB.net bug because it does not change the colours
at all.

arrowBrush.LinearColors = New Color() {arrowColor1,
arrowColor2}
works.

Yep, obviously does not work. Well, with the first version, the
brush can't take notice of the changes within the array, so it
doesn't take further actions to update it's internal colors.
That's different when assigning the property.
I think that's a flaw in the Framework, not in GDI+.
Question 3:

Do I need to dispose the brushes or do they disappear anyway at the
end of the subroutine?

If you want to free unused ressources ASAP, you have to dispose them.
Otherwise they will be disposed at an undetermined point in time
later (whenever the GC thinks it's time to clean up ressources (maybe
never before the process quits)).
 
After serious thinking Armin Zingler wrote :
Am 03.09.2010 17:57, schrieb C:


Assuming System.Drawing is imported as by default:

Dim mode As Drawing2D.LinearGradientMode
Dim arrowBrush As Drawing2D.LinearGradientBrush

mode = If(hv = 1, Drawing2D.LinearGradientMode.Horizontal,
Drawing2D.LinearGradientMode.Vertical) arrowBrush = New
Drawing2D.LinearGradientBrush(rect, Color.White, Color.Black, mode)

(note that the If-operator is used here, not the IIf function
or the If-statement)

I would probably Import System.Drawing.Drawing2D as well, and write it like this:

Dim mode As LinearGradientMode = If(hv = 1, LinearGradientMode.Horizontal, LinearGradientMode.Vertical)

' create a brush and make sure it goes away...
Using arrowBrush As LinearGradientBrush = New LinearGradientBrush(rect, Color.White, Color.Black, mode)
' do stuff with the brush
End Using ' brush resources cleaned up right here!
 
Am 03.09.2010 17:57, schrieb C:












Assuming System.Drawing is imported as by default:

      Dim mode As Drawing2D.LinearGradientMode

Is this LinearGradientMode an object?
      Dim arrowBrush As Drawing2D.LinearGradientBrush

      mode = If(hv = 1, Drawing2D.LinearGradientMode.Horizontal, Drawing2D.LinearGradientMode.Vertical)

This is nicer and cleaner than what I am doing.
      arrowBrush = New Drawing2D.LinearGradientBrush(rect, Color.White, Color.Black, mode)

(note that the If-operator is used here, not the IIf function
or the If-statement)

Looks like you cannot change the gradient mode of a brush.
Yep, obviously does not work. Well, with the first version, the
brush can't take notice of the changes within the array, so it
doesn't take further actions to update it's internal colors.
That's different when assigning the property.
I think that's a flaw in the Framework, not in GDI+.

Crazy.



If you want to free unused ressources ASAP, you have to dispose them.
Otherwise they will be disposed at an undetermined point in time
later (whenever the GC thinks it's time to clean up ressources (maybe
never before the process quits)).

I presume the brush does not need megabytes of resources, but Using ..
End Using might be a better practice.
 
After serious thinking Armin Zingler wrote :










I would probably Import System.Drawing.Drawing2D as well, and write it like this:

Doesn't all this come automatically from the IDE/compiler?
Dim mode As LinearGradientMode = If(hv = 1, LinearGradientMode.Horizontal, LinearGradientMode.Vertical)

' create a brush and make sure it goes away...
Using arrowBrush As LinearGradientBrush = New LinearGradientBrush(rect,Color.White, Color.Black, mode)
    ' do stuff with the brush
End Using ' brush resources cleaned up right here!

I guess this might be a good habit to form.

Thanks.
 
Am 03.09.2010 19:22, schrieb Tom Shelton:
I would probably Import System.Drawing.Drawing2D as well, and write it like this:

I only explained why I cut the namespace, not what I would import.
Of course, we can additionally import Drawing2D, but that was
not my point.
 
Am 03.09.2010 20:24, schrieb C:
Is this LinearGradientMode an object?

It's a type. That's what you put after the "As" keyword. ;-)
You can hover the mouse over the type or go to it's definition
(via context menu or Shift+F2 (of whatever is your current
shortcut)). In short, it's an Enum type.

I presume the brush does not need megabytes of resources, but Using ..
End Using might be a better practice.

Yes, but the question was not _how_ to dispose them. Sure,
Using is useful.
 
Am 03.09.2010 20:24, schrieb C:





It's a type. That's what you put after the "As" keyword. ;-)
You can hover the mouse over the type or go to it's definition
(via context menu or Shift+F2 (of whatever is your current
shortcut)). In short, it's an Enum type.



Yes, but the question was not _how_ to dispose them. Sure,
Using is useful.

Thanks. You have been very patient with me.

FillPolygon is either a bug or a feature, but in any case, it does not
do what one would expect it to do. It does not fill all the space
including the boundary as shown by DrawPolygon, which means extra
trouble for drawing very small polygons like arrows with a thickness
of or a length of 2 or 3 pixels. If the size is much larger, the
inaccuracy is not very visible.
 
Back
Top