Software Expressions

.Net / Software / Visual Studio / TFS / other ramblings
 

Goto

Categories

 

Archive for the 'Code Sample' Category

11 14th, 2008

Serializing images

Author: Troy

The System.Drawing.Image class is not serializable by default. This class can be used to serialize images as well as load the image from the IDataRecord.

   1:  Imports System.Drawing
   2:  Imports System.Runtime.Serialization
   3:  Imports System.Drawing.Imaging
   4:  Imports System.IO
   5:   
   6:  <Serializable()> _
   7:  Public Class SerializableImage
   8:      Implements ISerializable
   9:   
  10:      Private _master As MasterEnum = MasterEnum.Image
  11:      Private _imageBuffer As Byte()
  12:      Private _image As Image
  13:      Private _serializationFormat As ImageFormat = ImageFormat.Png
  14:   
  15:      Public Property Image() As Image
  16:          Get
  17:              If _master <> MasterEnum.Image Then
  18:                  CreateImageFromBuffer()
  19:              End If
  20:              Return _image
  21:          End Get
  22:          Set(ByVal value As Image)
  23:              If (value Is _image) Then Return
  24:              _image = value
  25:              ‘The image becomes the master once the setter is used
  26:              _master = MasterEnum.Image
  27:              _imageBuffer = Nothing
  28:          End Set
  29:      End Property
  30:   
  31:      Private Sub CreateImageFromBuffer()
  32:          ‘Once this method is called, the image becomes the master
  33:          _master = MasterEnum.Image
  34:          ‘Check if there is a buffer
  35:          If _imageBuffer Is Nothing OrElse _imageBuffer.Length = 0 Then
  36:              Image = Nothing
  37:          Else
  38:              ‘http://support.microsoft.com/?id=814675
  39:              Using s As New MemoryStream(_imageBuffer)
  40:                  If Not s Is System.IO.Stream.Null Then
  41:                      Dim tempImage As Image = _
  42:                          DirectCast(Bitmap.FromStream(s), Bitmap)
  43:                      Image = New Bitmap(tempImage)
  44:                      Dim g As Graphics = Graphics.FromImage(tempImage)
  45:                      g.DrawImage(Image, New PointF(0, 0))
  46:                      g.Dispose()
  47:                      tempImage.Dispose()
  48:                  End If
  49:                  s.Close()
  50:              End Using
  51:          End If
  52:      End Sub
  53:   
  54:      Private Property ImageBuffer() As Byte()
  55:          Get
  56:              Select Case _master
  57:                  Case MasterEnum.Image
  58:                      ‘Used for serialization
  59:                      Return CreateBufferFromImage()
  60:                  Case MasterEnum.Buffer
  61:                      Return _imageBuffer
  62:              End Select
  63:              Return _imageBuffer
  64:          End Get
  65:          Set(ByVal value As Byte())
  66:              If (value Is _imageBuffer) Then Return
  67:              _imageBuffer = value
  68:              ‘The Buffer becomes the master
  69:              _master = MasterEnum.Buffer
  70:              _image = Nothing
  71:          End Set
  72:      End Property
  73:   
  74:      Private Function CreateBufferFromImage() As Byte()
  75:          If _image Is Nothing Then Return Nothing
  76:          ‘Convert the image to a byte array using the serialization format
  77:          Using stream As New MemoryStream
  78:              _image.Save(stream, SerializationFormat)
  79:              Dim result As Byte() = stream.ToArray()
  80:              stream.Close()
  81:              Return result
  82:          End Using
  83:      End Function
  84:   
  85:      Public Property SerializationFormat() As ImageFormat
  86:          Get
  87:              Return _serializationFormat
  88:          End Get
  89:          Set(ByVal value As ImageFormat)
  90:              _serializationFormat = value
  91:          End Set
  92:      End Property
  93:   
  94:      Public Sub New()
  95:   
  96:      End Sub
  97:   
  98:      Public Sub New(ByVal image As Image)
  99:          Me.Image = image
 100:      End Sub
 101:   
 102:      Public Sub New(ByVal record As IDataRecord, ByVal fieldIndex As Integer)
 103:          Load(record, fieldIndex)
 104:      End Sub
 105:   
 106:      Public Sub New(ByVal record As IDataRecord, ByVal fieldName As String)
 107:          Load(record, fieldName)
 108:      End Sub
 109:   
 110:      Private Sub Load(ByVal record As IDataRecord, ByVal fieldName As String)
 111:          If record Is Nothing Then Throw New ArgumentNullException(“record”)
 112:          Load(record, record.GetOrdinal(fieldName))
 113:      End Sub
 114:   
 115:      Private Sub Load(ByVal record As IDataRecord, ByVal fieldIndex As Integer)
 116:          If record Is Nothing Then Throw New ArgumentNullException(“record”)
 117:          If record.IsDBNull(fieldIndex) Then Return
 118:          ImageBuffer = DirectCast(record.GetValue(fieldIndex), Byte())
 119:      End Sub
 120:   
 121:      Public Sub New(ByVal info As SerializationInfo, _
 122:          ByVal context As StreamingContext)
 123:          ‘Image
 124:          Dim data As Byte() = _
 125:              DirectCast(info.GetValue(“image”, GetType(Byte())), Byte())
 126:          If data IsNot Nothing AndAlso data.Length > 0 Then
 127:              ‘http://support.microsoft.com/?id=814675
 128:              Using s As New MemoryStream(data)
 129:                  If Not s Is System.IO.Stream.Null Then
 130:                      Dim tempImage As Image = _
 131:                          DirectCast(Bitmap.FromStream(s), Bitmap)
 132:                      Image = New Bitmap(tempImage)
 133:                      Dim g As Graphics = Graphics.FromImage(tempImage)
 134:                      g.DrawImage(Image, New PointF(0, 0))
 135:                      g.Dispose()
 136:                      tempImage.Dispose()
 137:                  End If
 138:                  s.Close()
 139:              End Using
 140:          End If
 141:      End Sub
 142:   
 143:      Public Sub GetObjectData(ByVal info As SerializationInfo, +
 144:          ByVal context As StreamingContext) Implements ISerializable.GetObjectData
 145:          info.AddValue(“image”, ImageBuffer, GetType(Byte()))
 146:      End Sub
 147:   
 148:      Private Enum MasterEnum
 149:          Buffer
 150:          Image
 151:      End Enum
 152:   
 153:  End Class
07 18th, 2007

It appears as if there is no timer available for Silverlight. I noticed two options that were utilized; one was using the Storyboard as a timer and another was using System.Windows.Browser.HtmlTimer. Although this causes an obsolete warning, it does work in Silverlight Alpha 1.1, and from some comments on a CodeProject page it looks as if some other timer will become available in the future. So for now I’m going to be using the HtmlTimer to provide the heartbeat for sprites.

   1:  using System.Windows.Browser;
   2:   
   3:  public class WorldBase
   4:  {
   5:      private HtmlTimer _heartBeat = new HtmlTimer();
   6:      private int _beatsPerSecond;
   7:      private DateTime _lastBeat;
   8:   
   9:      public WorldBase()
  10:      {
  11:          _lastBeat = DateTime.Now;
  12:          _heartBeat.Interval = 50;
  13:          _heartBeat.Tick += new EventHandler(_heartBeat_Tick);
  14:          _beatsPerSecond = 50;
  15:          _heartBeat.Enabled = true;
  16:      }
  17:   
  18:      void _heartBeat_Tick(object sender, EventArgs e)
  19:      {
  20:          //Update the BeatsPerSecond
  21:          _beatsPerSecond = 1 / (DateTime.Now - _lastBeat).Seconds;
  22:          //Provide a hearbeat for the world of sprites
  23:          ...
  24:      }
  25:  }

   1:  Public Class Project
   2:      Inherits BusinessBase(Of Project)
   3:   
   4:      Public ReadOnly Property LineItems() As LineItemsCollection
   5:          Get
   6:              CanReadProperty(True)
   7:              If _lineItems Is Nothing Then
   8:                  If Me.IsNew Then
   9:                      _lineItems = LineItemList.NewLineItemList(Me)
  10:                  Else
  11:                      _lineItems = LineItemList.GetLineItems(Me)
  12:                  End If
  13:                  AddHandler _lineItems.ListChanged, _
  14:                  AddressOf LineItemChangedHandler
  15:              End If
  16:              Return _lineItems
  17:          End Get
  18:      End Property
  19:   
  20:      Public Sub LineItemChangedHandler(_
  21:          ByVal sender As Object, _
  22:          ByVal e As System.ComponentModel.ListChangedEventArgs)
  23:          If (e.ListChangedType = ListChangedType.ItemAdded) Then
  24:              _lineItems(e.NewIndex).Project = Me
  25:          End If
  26:      End Sub
  27:   
  28:   
  29:  End Class
  30:   
  31:  Public Class LineItem
  32:      Inherits BusinessBase(Of LineItem)
  33:   
  34:      <NotUndoable()> <NonSerialized()> Private _project As Project
  35:   
  36:      Public Property Project() As Project
  37:          Get
  38:              If _project Is Nothing Then
  39:                  _project = Project.GetProject(_projectId)
  40:              End If
  41:              Return _project
  42:          End Get
  43:          Friend Set(ByVal value As Project)
  44:              If Not value.ID = _projectId Then
  45:                 _project = proj
  46:              ProjectId = proj.ID
  47:              End If
  48:          End Set
  49:      End Property
  50:   
  51:      Public Property ProjectId() As Guid
  52:          Get
  53:              CanReadProperty(True)
  54:              Return _projectId
  55:          End Get
  56:          Private Set(ByVal value As Guid)
  57:              If _projectId <> value Then
  58:                  _projectId = value
  59:                  PropertyHasChanged()
  60:              End If
  61:          End Set
  62:      End Property
  63:   
  64:  End Class
03 30th, 2007

This example illustrates implementing a custom exception, implemeting the ISerializable interface and adding a property to the exception.

   1:  [Serializable]
   2:  public class DexException : System.ApplicationException, ISerializable
   3:  {
   4:      private DateTime _timeStamp;
   5:   
   6:      public DateTime TimeStamp
   7:      {
   8:          get { return _timeStamp; }
   9:          set { _timeStamp = value; }
  10:      }
  11:   
  12:      public DexException() : base()
  13:      {
  14:          _timeStamp = DateTime.Now;
  15:      }
  16:   
  17:      public DexException(string message) : base(message)
  18:      {
  19:          _timeStamp = DateTime.Now;
  20:      }
  21:   
  22:      protected DexException(SerializationInfo info, 
  23:                StreamingContext context) : base(info, context)
  24:      {
  25:          _timeStamp = info.GetDateTime("TimeStamp");
  26:      }
  27:   
  28:      [SecurityPermissionAttribute(SecurityAction.Demand, 
  29:              SerializationFormatter=true)]
  30:      public override void GetObjectData(
  31:             SerializationInfo info, StreamingContext context)
  32:      {
  33:          info.AddValue("TimeStamp", _timeStamp);
  34:      }
  35:  }
03 7th, 2007

MatrixNode

Author: Troy

It’s strange, but this is the second project now, where I’ve found a use for what was originally called the TdoMatrix. It’s a simple name value pair class with a list of child classes of the same type. It only supports two methods, “Add” and “Find”. The class is used for building filter dependencies. Adding filter dependencies can be accomplished like this:
myMatrix.Add(”Toyota”).Add(”Camry”).Add(”Silver”).Value = MyCarPicture
Now if silver was available for many cars, you could do this:
myMatrix.Add(”Toyota”).Add(”Camry”, “Corolla”, “Echo”).Add(”Silver”)
You can call Add multiple times, if it already exists, the add will be ignored.

   1:  Imports system.ComponentModel
   2:   
   3:  Public Interface IMatrixNode(Of T)
   4:      ReadOnly Property Name() As String
   5:      Property Value() As T
   6:      Function Add(ByVal ParamArray nodeNames() As String) As IMatrixNode(Of T)
   7:      Function Find(ByVal name As String) As IMatrixNode(Of T)
   8:  End Interface
   9:   
  10:  Public Class MatrixNode(Of T)
  11:      Inherits List(Of IMatrixNode(Of T))
  12:      Implements IMatrixNode(Of T)
  13:   
  14:      Private _name As String
  15:      Private _value As T
  16:      Private _index As Dictionary(Of String, IMatrixNode(Of T)) = Nothing
  17:   
  18:      Public Sub New(ByVal aName As String)
  19:          _name = aName
  20:      End Sub
  21:   
  22:      Public ReadOnly Property Name() As String Implements IMatrixNode(Of T).Name
  23:          Get
  24:              Return _name
  25:          End Get
  26:      End Property
  27:   
  28:      Public Property Value() As T Implements IMatrixNode(Of T).Value
  29:          Get
  30:              Return _value
  31:          End Get
  32:          Set(ByVal value As T)
  33:              _value = value
  34:          End Set
  35:      End Property
  36:   
  37:      Private ReadOnly Property Index() As _
  38:          Dictionary(Of String, IMatrixNode(Of T))
  39:          Get
  40:              If (_index Is Nothing) Then _index = _
  41:                   New Dictionary(Of String, IMatrixNode(Of T))
  42:              Return _index
  43:          End Get
  44:      End Property
  45:   
  46:      Private Overloads Function Add(ByVal ParamArray nodeNames() As String) _
  47:          As IMatrixNode(Of T) Implements IMatrixNode(Of T).Add
  48:          If (nodeNames.Length = 0) Then Return Nothing
  49:          Dim nodes(nodeNames.Length) As IMatrixNode(Of T)
  50:          For i As Integer = 0 To nodeNames.Length - 1
  51:              Dim iNode As IMatrixNode(Of T) = Nothing
  52:              If Not Index.TryGetValue(nodeNames(i), iNode) Then
  53:                  iNode = New MatrixNode(Of T)(nodeNames(i))
  54:                  Add(iNode)
  55:                  Index.Add(iNode.Name, iNode)
  56:              End If
  57:              nodes(i) = iNode
  58:          Next
  59:          If (nodes.Length = 1) Then Return nodes(0)
  60:          Return New MatrixGroup(Of T)(nodes)
  61:      End Function
  62:   
  63:      Public Shadows Function Find(ByVal name As String) _
  64:          As IMatrixNode(Of T) Implements IMatrixNode(Of T).Find
  65:          Return Index(name)
  66:      End Function
  67:  End Class
  68:   
  69:  Public Class MatrixGroup(Of T)
  70:      Implements IMatrixNode(Of T)
  71:   
  72:      Private _childNodes() As IMatrixNode(Of T)
  73:   
  74:      Public Sub New(ByVal ParamArray nodes() As IMatrixNode(Of T))
  75:          _childNodes = nodes
  76:      End Sub
  77:   
  78:      Public Function Add(ByVal ParamArray nodeNames() As String) _
  79:          As IMatrixNode(Of T) Implements IMatrixNode(Of T).Add
  80:          For Each node As IMatrixNode(Of T) In _childNodes
  81:              node.Add(nodeNames)
  82:          Next
  83:          Return Me
  84:      End Function
  85:   
  86:      Public ReadOnly Property Name() As String Implements IMatrixNode(Of T).Name
  87:          Get
  88:              Return "Temporary Group"
  89:          End Get
  90:      End Property
  91:   
  92:      Public Property value() As T Implements IMatrixNode(Of T).Value
  93:          Get
  94:              If (_childNodes.Length > 0) Then Return _childNodes(0).Value
  95:              Return Nothing
  96:          End Get
  97:          Set(ByVal value As T)
  98:              For Each node As IMatrixNode(Of T) In _childNodes
  99:                  node.Value = value
 100:              Next
 101:          End Set
 102:      End Property
 103:   
 104:      Public Shadows Function Find(ByVal name As String) _
 105:          As IMatrixNode(Of T) Implements IMatrixNode(Of T).Find
 106:          Throw New NotSupportedException( _
 107:              "Find cannot be executed on the MatrixGroup")
 108:      End Function
 109:   
 110:  End Class

There are several tricks that you need to know in order to generate the necessary synergy between Microsoft Project and Team Foundation Servers work items. One of those being, how do you update “PercentComplete” in Microsoft Project when the Developers only update CompletedWork and RemainingWork (and TFS does not allow complex mappings which could translate these into percent complete). One option is to generate a macro in MS Project that performs the necessary calculations. The other option would be to create a web service and register this service with TFS when any work item is updated. The web service would then query the work item, calculate and update the percentage. This also requires adding an additional “PercentComplete” field in the work item. I’d like to take this approach in the long term, but short-term, the following MS Project macro does the trick.

Sub CalcPercentComplete()
    Dim task As task
    Dim taskComplete As Long
    For Each task In ActiveProject.tasks
        If (Not task.Rollup) Then
            taskComplete = task.PercentComplete
            If (task.ActualWork = 0) Then
                taskComplete = 0
            ElseIf (task.RemainingWork = 0) Then
                taskComplete = 100
            Else
                taskComplete = Round(task.ActualWork * 100 / (task.ActualWork + task.RemainingWork))
            End If
            task.PercentComplete = taskComplete
        End If
    Next task
End Sub

This little bit of code has been useful in a console application to automatically modify the AssemlbyInfo.cs files and update the version number.

static void Main(string[] args)
{
    if (args.Length != 2)
        Console.WriteLine("Usage: ApplyVersionNo <folder> <version_no>");
    else {
        Regex regexAsmVersion =
            new Regex(@"\[assembly: AssemblyVersion\(""([0-9.\*]*)""\)\]");
        Regex regexAsmFileVersion =
            new Regex(@"\[assembly: AssemblyFileVersion\(""([0-9.\*]*)""\)\]");
        string folder = args[0];
        string version = args[1];
        foreach (string filename in Directory.GetFiles(
            folder, "AssemblyInfo.cs", SearchOption.AllDirectories))
        {
            string contents = File.ReadAllText(filename);
            string newContents = regexAsmVersion.Replace(
                contents, @"[assembly: AssemblyVersion(""" + version + @""")]");
            newContents = regexAsmFileVersion.Replace(
                newContents, @"[assembly: AssemblyFileVersion(""" + version + @""")]");
            File.WriteAllText(filename, newContents);
        }
    }
}
10 25th, 2006

There are few things that need to be done (albeit very obvious) that need to be done to allow forms embedded within a panel or other control.

    //viewForm is of type Form, parent is of type 
    viewForm.TopLevel = False;
    viewForm.Dock = DockStyle.Fill;
    viewForm.FormBorderStyle = FormBorderStyle.None;
    viewForm.Parent = parent;
    viewForm.Show();
03 6th, 2006

C# ColorFade routine

Author: Troy

private Color ColorFade(Color fromColor, Color toColor, byte fade)
{
    byte fromR = fromColor.R;
    byte fromG = fromColor.G;
    byte fromB = fromColor.B;
    byte toR = toColor.R;
    byte toG = toColor.G;
    byte toB = toColor.B;
    byte r = Fade(fromR, toR, fade);
    byte g = Fade(fromG, toG, fade);
    byte b = Fade(fromB, toB, fade);
    return Color.FromArgb(r, g, b);
}

private byte Fade(byte from, byte to, byte fade)
{
    int h = (to >= from) ? to : from;
    int l = (to < from) ? to : from;
    int fadeInt = fade;
    return (byte)(l + (h-l) * fadeInt / 255);
}