2010-05-07 53 views
0

如标题所示,我需要序列化我的字体。 不幸的是,我尝试了以下方法。vb.net的字体序列化

这就是我所拥有的和发生的事情;

我有一个绘图应用程序,某些变量和属性需要序列化。 (所以,已经使用了Xml.Serialization。)

现在这已经在大部分中完成了,并且我创建了一些需要序列化的其他属性并且它可以工作。

有一个基类和类,如drawablestar,drawableeclipse等。全部从这个类继承。我的drawabletextbox类也是如此。 基类是可序列化的,如下面的示例所示。

它看起来像这样...

Imports System.Xml.Serialization 
<Serializable()> _ 
Public MustInherit Class Drawable 
    ' Drawing characteristics. 
    'Font characteristics 
    <XmlIgnore()> Public FontFamily As String 
    <XmlIgnore()> Public FontSize As Integer 
    <XmlIgnore()> Public FontType As Integer 

    <XmlIgnore()> Public ForeColor As Color 
    <XmlIgnore()> Public FillColor As Color 


    <XmlAttributeAttribute()> Public LineWidth As Integer = 0 

    <XmlAttributeAttribute()> Public X1 As Integer 
    <XmlAttributeAttribute()> Public Y1 As Integer 
    <XmlAttributeAttribute()> Public X2 As Integer 
    <XmlAttributeAttribute()> Public Y2 As Integer 


    ' attributes for size textbox 
    <XmlAttributeAttribute()> Public widthLabel As Integer 
    <XmlAttributeAttribute()> Public heightLabel As Integer 

    '<XmlTextAttribute()> Public FontFamily As String 
    '<XmlAttributeAttribute()> Public FontSize As Integer 


    'this should actually not be here.. 
    <XmlAttributeAttribute()> Public s_InsertLabel As String 


    ' Indicates whether we should draw as selected. 
    <XmlIgnore()> Public IsSelected As Boolean = False 


    ' Constructors. 
    Public Sub New() 
     ForeColor = Color.Black 
     FillColor = Color.White 
     'FontFamily = "Impact" 
     'FontSize = 12 

    End Sub 


    Friend WriteOnly Property _Label() As String 

     Set(ByVal Value As String) 
      s_InsertLabel = Value 

     End Set 

    End Property 

    Public Sub New(ByVal fore_color As Color, ByVal fill_color As Color, Optional ByVal line_width As Integer = 0) 
     LineWidth = line_width 
     ForeColor = fore_color 
     FillColor = fill_color 

     ' FontFamily = Font_Family 
     ' FontSize = Font_Size 

    End Sub 

    ' Property procedures to serialize and 
    ' deserialize ForeColor and FillColor. 
    <XmlAttributeAttribute("ForeColor")> _ 
    Public Property ForeColorArgb() As Integer 
     Get 
      Return ForeColor.ToArgb() 
     End Get 
     Set(ByVal Value As Integer) 
      ForeColor = Color.FromArgb(Value) 
     End Set 
    End Property 

    <XmlAttributeAttribute("BackColor")> _ 
    Public Property FillColorArgb() As Integer 
     Get 
      Return FillColor.ToArgb() 
     End Get 
     Set(ByVal Value As Integer) 
      FillColor = Color.FromArgb(Value) 
     End Set 
    End Property 



    'Property procedures to serialize and 
    'deserialize Font 

    <XmlAttributeAttribute("InsertLabel")> _ 
    Public Property InsertLabel_() As String 
     Get 
      Return s_InsertLabel 
     End Get 
     Set(ByVal value As String) 
      s_InsertLabel = value 
     End Set 
    End Property 


    <XmlAttributeAttribute("FontSize")> _ 
    Public Property FontSizeGet() As Integer 
     Get 
      Return FontSize 
     End Get 
     Set(ByVal value As Integer) 
      FontSize = value 
     End Set 
    End Property 

    <XmlAttributeAttribute("FontFamily")> _ 
    Public Property FontFamilyGet() As String 
     Get 
      Return FontFamily 
     End Get 
     Set(ByVal value As String) 
      FontFamily = value 
     End Set 
    End Property 

    <XmlAttributeAttribute("FontType")> _ 
    Public Property FontType_() As Integer 
     Get 
      Return FontType 
     End Get 
     Set(ByVal value As Integer) 
      FontType = value 
     End Set 
    End Property 


#Region "Methods to override" 

    Public MustOverride Sub Draw(ByVal gr As Graphics) 

    ' Return the object's bounding rectangle. 
    Public MustOverride Function GetBounds() As Rectangle 

    ...... ........ 
..... 

End Class 

我的文本框类,它看起来像这样,是需要保存的字体之一。

Imports System.Math 
Imports System.Xml.Serialization 
Imports System.Windows.Forms 


<Serializable()> _ 
Public Class DrawableTextBox 
    Inherits Drawable 

    Private i_StringLength As Integer 
    Private i_StringWidth As Integer 
    Private drawFont As Font = New Font(FontFamily, 12, FontStyle.Regular) 

    Private brsTextColor As Brush = Brushes.Black 
    Private s_insertLabelTextbox As String = "label" 

    ' Constructors. 

    Public Sub New() 
    End Sub 


    Public Sub New(ByVal objCanvas As PictureBox, ByVal fore_color As Color, ByVal fill_color As Color, Optional ByVal line_width As Integer = 0, Optional ByVal new_x1 As Integer = 0, Optional ByVal new_y1 As Integer = 0, Optional ByVal new_x2 As Integer = 1, Optional ByVal new_y2 As Integer = 1) 

     MyBase.New(fore_color, fill_color, line_width) 

     Dim objGraphics As Graphics = objCanvas.CreateGraphics() 

     X1 = new_x1 
     Y1 = new_y1 

     'Only rectangles ,circles and stars can resize for now b_Movement 
     b_Movement = True 

     Dim frm As New frmTextbox 
     frm.MyFont = drawFont 
     frm.ShowDialog() 

     If frm.DialogResult = DialogResult.OK Then 


      FontFamily = frm.MyFont.FontFamily.Name 
      FontSize = frm.MyFont.Size 
      FontType = frm.MyFont.Style 

      'drawFont = frm.MyFont 

      drawFont = New Font(FontFamily, FontSize) 
      drawFont = FontAttributes() 

      brsTextColor = New SolidBrush(frm.txtLabel.ForeColor) 

      s_InsertLabel = frm.txtLabel.Text 

      i_StringLength = s_InsertLabel.Length 


      'gefixtf 
      Dim objSizeF As SizeF = objGraphics.MeasureString(s_InsertLabel, drawFont, New PointF(X2 - X1, Y2 - Y1), New StringFormat(StringFormatFlags.NoClip)) 
      Dim objPoint As Point = objCanvas.PointToClient(New Point(X1 + objSizeF.Width, Y1 + objSizeF.Height)) 

      widthLabel = objSizeF.Width 
      heightLabel = objSizeF.Height 

      X2 = X1 + widthLabel 
      Y2 = Y1 + heightLabel 

     Else 
      Throw New ApplicationException() 
     End If 
    End Sub 


    ' Draw the object on this Graphics surface. 
    Public Overrides Sub Draw(ByVal gr As System.Drawing.Graphics) 

     ' Make a Rectangle representing this rectangle. 
     Dim rectString As Rectangle 

     rectString = New Rectangle(X1, Y1, widthLabel, heightLabel) 
     rectString = GetBounds() 


     ' See if we're selected. 
     If IsSelected Then 

      gr.DrawString(s_InsertLabel, drawFont, brsTextColor, X1, Y1) 

      'gr.DrawRectangle(Pens.Black, rect) ' Pens.Transparent 
      gr.DrawRectangle(Pens.Black, rectString) 

      ' Draw grab handles. 
      DrawGrabHandle(gr, X1, Y1) 
      DrawGrabHandle(gr, X1, Y2) 
      DrawGrabHandle(gr, X2, Y2) 
      DrawGrabHandle(gr, X2, Y1) 
     Else 

      gr.DrawString(s_InsertLabel, drawFont, brsTextColor, X1, Y1) 
      'gr.DrawRectangle(Pens.Black, rect) ' Pens.Transparent 
      gr.DrawRectangle(Pens.Black, rectString) 

     End If 

    End Sub 

    'get fontattributes 
    Public Function FontAttributes() As Font 
     Return New Font(FontFamily, 12, FontStyle.Regular) 

    End Function 

    ' Return the object's bounding rectangle. 
    Public Overrides Function GetBounds() As System.Drawing.Rectangle 
     Return New Rectangle(_ 
      Min(X1, X1), _ 
      Min(Y1, Y1), _ 
      Abs(widthLabel), _ 
      Abs(heightLabel)) 
    End Function 


    ' Return True if this point is on the object. 
    Public Overrides Function IsAt(ByVal x As Integer, ByVal y As Integer) As Boolean 
     Return (x >= Min(X1, X2)) AndAlso _ 
       (x <= Max(X1, X2)) AndAlso _ 
       (y >= Min(Y1, Y2)) AndAlso _ 
       (y <= Max(Y1, Y2)) 
    End Function 

    ' Move the second point. 
    Public Overrides Sub NewPoint(ByVal x As Integer, ByVal y As Integer) 
     X2 = x 
     Y2 = y 
    End Sub 

    ' Return True if the object is empty (e.g. a zero-length line). 
    Public Overrides Function IsEmpty() As Boolean 
     Return (X1 = X2) AndAlso (Y1 = Y2) 

    End Function 


End Class 

的坐标(X1,X2,Y1,Y2),需要绘制一个圆,矩形等。(在其它类)。该所有作品。 如果我加载保存的文件,它会显示绘制对象的正确位置和正确大小。如果我打开我的XML文件,我可以看到所有的值都被正确保存(包括我的FontFamily)。

另外,当我加载之前保存的图纸时,可以调整的颜色将被保存并正确显示。

当然,因为坐标工作,如果我插入一个textField,它显示的位置是正确的。 然而问题来了,我的fontSize和fontfamily不起作用。

正如你可以看到我在基类中创建它们,但这并不是 的工作。我的方法完全关闭吗?我能做什么 ? 之前节省 img14.imageshack.us/i/beforeos.jpg/

加载字体跳回无衬线和尺寸12

我真的可以在这里使用一些帮助后..

编辑:我一直在使用的样品从本网站 http://www.vb-helper.com/howto_net_drawing_framework.html

UPDATE:

创建字体属性的问题在于xml序列化器不会采用它。 @OregonGhost我确定这就是你的意思,我只是没有真正遵循你的解决方案(以为我做了,原谅我)。

所以我想嘿为什么不创建某种字体类,将继承我的基类,因为这将是序列化(有点疯狂,我知道..创建一个字体类的字体类)。所以我可以创建自己的“自己的”字体对象,而不是使用标准的字体类(因为这不适用于xml序列化程序)。但决定不这样做。

@OregonGhost现在我看到的东西确实在C#中,我假设你的意思确实是这样的

public Font FontObject 
     { 
      get 
      { 
       return (Font) settings["font"]; 
      } 
      set 
      { 
       settings["font"] = value; 
      } 
     } 

在该设置是一个哈希表。

你是在暗示这样的事情?

回答

-1

我真的不能读取VB.NET代码,因为它使我的眼睛流血,但如果我正确地理解你的代码,你正在做的字体初始化为成员初始化。这是在构建时运行的,但是XML反序列化发生在基本上,之后:创建对象(这就是为什么它需要无参数构造函数),然后设置XML中找到的属性。所以,基本上,你过早阅读这些属性。

我对这个解决方案是有一个实际的Font属性与创建这些属性字体的吸气剂。这样,实际的字体对象就会在您需要时创建(当您获取属性时),并且通常是在反序列化之后。无论您每次在getter中返回一个新的字体对象还是将其缓存用于后续调用,仍然由您决定。我更喜欢前者,然后在使用后立即处理字体对象。

注:在计算器上的代码的语法不BBCode的,只是一切都缩进用四个空格。选择代码,然后按下带有零和一个按钮的按钮。我修正了这个帖子。

+0

日Thnx我只是编辑,现在我在读您的文章。 看起来非常有帮助!我会研究它....谢谢你的答复,非常感谢。 – jovany 2010-05-07 08:54:13

+0

噢,我想我明白你的意思,但我已经试过了。 你可以看到注释代码 _ 公共财产FontFamilyGet()作为字符串 获取 返回的FontFamily 最终获取 设置(BYVAL值作为字符串) 的FontFamily =值 结束设定 结束物业 _ 公共财产FontType_()作为整数 获取 返回FontType 最终获取 设置(BYVAL值作为整数) FontType =值 结束设定 高端物业 可惜没有 – jovany 2010-05-07 11:37:37

+0

我不明白你的意思。只需创建一个像这样的getter:'public Font Font {get {return new Font(FontFamily,...); }};'(对不起,没有VB.NET,我在C#中),你不会遇到问题。您可以编辑您的问题,以更详细地了解您已经尝试过的内容,但评论对此非常有限。 – OregonGhost 2010-05-07 12:25:21