Property 'Bold' is 'ReadOnly'.

  • Thread starter Thread starter Vax
  • Start date Start date
V

Vax

Guest
OK, maybe this is a stupid question, I don't know. I'm running VB.NET and I'm trying to set up a few pre-arranged fonts for use in my listbox control, changing things like bold status and fontname and whatnot. So I type:

Dim fntFont As Font
fntFont.Bold = True

and I get an error that the property 'Bold' is 'ReadOnly'. What gives? do I need to attack this some other way, or am I missing something obvious?

:confused:
 
Properties for Font objects are generally specified in the class constructor. If you want to modify an existing font object, you can pass it to the constructor of a new one and modify parameters there.
 
Well, the class I'm sing inherits its properties from the listbox, but it does have a property set sub. The code I'm using (go it from an online magazine) is as follows:

Look at the public property Font. It seems to be Read/Write. What am I missing?

Option Explicit On
Option Strict On
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Windows.Forms
Imports System.ComponentModel

Namespace WKS.ODListControl

'Enables code gen to convert prop builder strings to ODItem
<TypeConverter(GetType(ODItemConverter))> _
Public Class ODItem
Implements IDisposable
Implements IComparable

Private _Image As Image
Private _Font As Font
Private _ItemHeight As Integer
Private _UserObject As Object
Private _Text As String

Public Sub New()
_Text = "New item"
End Sub

Public Sub New(ByVal text As String)
_Text = text
End Sub

Public Sub New(ByVal text As String, ByVal itemImage As Image, ByVal itemHeight As Integer, ByVal Font As Font)
If Not IsNothing(itemImage) Then _Image = CType(itemImage.Clone, Image)
If Not IsNothing(Font) Then _Font = CType(Font.Clone, Font)
_ItemHeight = itemHeight
_Text = text
End Sub

Public Sub New(ByVal userObj As Object, ByVal text As String, ByVal itemImage As Image, ByVal itemHeight As Integer, ByVal Font As Font)
If Not IsNothing(itemImage) Then _Image = CType(itemImage.Clone, Image)
If Not IsNothing(Font) Then _Font = CType(Font.Clone, Font)
_ItemHeight = itemHeight
_UserObject = userObj
_Text = text
End Sub

Public Property ItemHeight() As Integer
Get
Return _ItemHeight
End Get
Set(ByVal Value As Integer)
_ItemHeight = Value
End Set
End Property

Public Property Image() As Image
Get
Return _Image
End Get
Set(ByVal Value As Image)
_Image = Value
End Set
End Property

Public Function ShouldSerializeImage() As Boolean
Return (Not IsNothing(_Image))
MsgBox("Called")
End Function


Public Property DisplayText() As String
Get
Return _Text
End Get
Set(ByVal Value As String)
_Text = Value
End Set
End Property

Public Property UserObject() As Object
Get
Return _UserObject
End Get
Set(ByVal Value As Object)
_UserObject = Value
End Set
End Property

Public Property Font() As Font
Get
Debug.WriteLine("Get font")
Return _Font
End Get
Set(ByVal Value As Font)
_Font = Value
End Set
End Property


Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub

Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If disposing Then
'Called by Dispose()
'Free managed objects
If Not IsNothing(_Image) Then _Image.Dispose()
If Not IsNothing(_Font) Then _Font.Dispose()
End If
'Free unmanaged objects.
End Sub

Protected Overrides Sub Finalize()
'Protected - don't allow to be called directly
Dispose(False)
End Sub

Public Overrides Function toString() As String
If Len(_Text) > 0 Then
Return _Text
ElseIf Not IsNothing(UserObject) Then
Return UserObject.ToString
Else
Return String.Empty
End If
End Function

Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
If IsNothing(obj) OrElse IsNothing(obj.ToString) Then Return 1
Return String.Compare(ToString, obj.ToString)
End Function
End Class

End Namespace


Well, there it is... whatcha think?
 
Once again, as divil said, in this code...
Dim fntFont As Font
fntFont.Bold = True
You are declaring a font object variable, then (without instantiating
it) trying to set a property. Instead, you should use one of the
overloaded Font constructors to both create the font, and set the
bold property, something like...
Code:
Dim fntFont As Font = New Font(fntOldFont, FontStyle.Bold)
 
sigh...

hmmm.... ok, but this just creates a new instance of a font. I suppose the next step is to set the font property of the object to this new font, but won't this also generate a readonly problem? I'd be trying it out right now, but I'm away from my machine. I'm betting this will probably work, I'm just having a little problem understanding why this would work but the MyObject.Font.Bold=True setting won't work, considering that MyObject is already instanced. Should that not mean the Font object of the MyObject object is also instanced, and thus the Bold Property should be read/write? It seems that would just plain make sense.

Y'know what's really sad about this? I'm not even getting paid to to do this, and this is how I spend my weekend. I'm sure that's saying something rather profound, not to mention unflattering.
 
I guess they made that property and similar ones readonly because behind the scenes it requires a new font handle to be created, so that might as well map to a new font object being created. Seemed odd to me at first, but it's not much of an inconvenience.

Me.Font = New Font(Me.Font, FontStyles.Bold)

Or whatever it is.
 
continuing further....

OK, that did it, thanks, but of course now I have a new problem...
how would I implement a FontColor property? Simple RGB value would be fine, but I thought the Font object would have this property inherent-- there I go thinking again, huh? I figure it would at least have a ForeColor/ BackColor property, but no...

Also, what would be an easy way to access the handle of the container for the control class, so I could get the container's default Font object? Is there a keyword for it, or do I have to include that in its construction arguments?

Thanks for the help
 
another thing...

...how do I create a font with no reference font? Let's say I just want to make an 8-point Helvetica Italics, but don't want to reference another font, i.e.,

dim fntFont as Font = New Font(Me.Font, FontStyle.Bold)

as, in this case, the Font object might well be set to Nothing, which would generate an exception, I'm pretty sure.

Could someone clue me in on the sytax for that? Thanks
 
Read your help. The constructor for the Font class is overloaded many times, at least one of which accepts a String with a Font Family name in it.
 
There are about 13 overloaded constructors. This helps explain
why the Font object properties like family, style and size are read-
only. It does seem a bit obtuse, but it isn't in any way a
restriction of capabilities.
 
Back
Top