Category: Visual Basic 10

Big integers in .NET 4.0

The BigInteger structure becomes available if you add a reference to the System.Numerics namespace. BigInteger represents a positive or negative integer of any size.  This is great for doing arithmetic calculations with very large numbers, and is one of the problems you had to solve on your own in previous versions of .NET Framework.

After the reference is added, you can create a BigInteger using the New keyword, and an initial value can be passed to the constructor, like so:

Dim X As New System.Numerics.BigInteger(Long.MaxValue)
Console.WriteLine(X.ToString())

To do arithmetic operations, create the BigIntegers you need for the operation, and then call the static (shared) functions of the BigInteger structure to do the calculations. In this case, I call the static function Multiply.

Dim X As New System.Numerics.BigInteger(Long.MaxValue)
Dim Y As New System.Numerics.BigInteger(Long.MaxValue)
Dim Z As System.Numerics.BigInteger = _
     System.Numerics.BigInteger.Multiply(X, Y)
Console.WriteLine(Z.ToString())

Just by adding a few of these lines to the above code, will give you one insanely large number.

Z = System.Numerics.BigInteger.Multiply(Z, Z)
Z = System.Numerics.BigInteger.Multiply(Z, Z)
Z = System.Numerics.BigInteger.Multiply(Z, Z)
Z = System.Numerics.BigInteger.Multiply(Z, Z)

One way to serialize this number in SQL Server could be to store the underlying bytes of the number that the BigInteger instance represents. The BigInteger structure has a member function that returns these bytes as a byte array called GetByteArray. An existing byte array can be passed to the constructor of the BigInteger to reconstruct the number.

Hardware accelerated graphics through XNA: Getting started

There are some features of the XNA Framework that is unavailable from Visual Basic, but this should not stop you from writing descent games in Visual Basic. On my machine, I have installed XNA Game Studio 3.1 (a game developing environment from Microsoft) and I also have a beta of Visual Studio 2010 that I am going to use. This example will just contain the code necessary to get something on the screen, a sprite floating across.

From VS2010, I am using a regular console application and the target platform for the project is .NET Framework 3.5.

Now I must add two references: Microsoft.Xna.Framework and Microsoft.Xna.Framework.Game. I use version 3.1, the version that got installed when I installed XNA Game Studio 3.1.

The next step is to create the game class. I call my class TestGame. TestGame should inherit from the Microsoft.Xna.Framework.Game class. In here I create a Main method to get the program started, and I select that method to be the starting point for the program in the Project Settings window. This is the code so far:

Public Class TestGame
    Inherits Microsoft.Xna.Framework.Game

    Public Shared Sub Main()

    End Sub

End Class

In the Main method, I create my game (the TestGame class) and from the constructor, a graphics device manager for the game. I use the graphics device manager to set my preferred resolution (800×600) and to switch to fullscreen mode. Note that I want to keep the reference to the graphics device manager as a member of my game class.

Public Class TestGame
    Inherits Microsoft.Xna.Framework.Game

    Private Gfx As Microsoft.Xna.Framework.GraphicsDeviceManager

    Public Shared Sub Main()
        Dim Game As New TestGame()
        Game.Run()
    End Sub

    Public Sub New()
        Me.Gfx = New Microsoft.Xna.Framework.GraphicsDeviceManager(Me)
        Me.Gfx.PreferredBackBufferWidth = 800
        Me.Gfx.PreferredBackBufferHeight = 600
        If Not Me.Gfx.IsFullScreen Then
            Me.Gfx.ToggleFullScreen()
        End If
    End Sub

End Class

The next thing to do is some overrides from the base class. These methods will be overloaded:

Protected Overrides Sub Initialize()
    MyBase.Initialize()
End Sub

Protected Overrides Sub LoadContent()
    MyBase.LoadContent()
End Sub

Protected Overrides Sub UnloadContent()
    MyBase.UnloadContent()
End Sub

Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
    MyBase.Update(gameTime)
End Sub

Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
    MyBase.Draw(gameTime)
End Sub

Just to make something happen on the screen, I am adding these members:

Private Sb As Microsoft.Xna.Framework.Graphics.SpriteBatch
Private SpriteTexture As Microsoft.Xna.Framework.Graphics.Texture2D
Private SpriteX As Integer = 0
Private SpriteY As Integer = 0

The SpriteBatch will manage my sprites and the Texture2D is the sprite graphics. In the LoadContent function, I will load a sprite from my hard drive.

Protected Overrides Sub LoadContent()
    Me.Sb = New Microsoft.Xna.Framework.Graphics.SpriteBatch(Me.Gfx.GraphicsDevice)
    Me.SpriteTexture = Microsoft.Xna.Framework.Graphics.Texture2D.FromFile(Me.Gfx.GraphicsDevice, _
         "mysprite.png")
    MyBase.LoadContent()
End Sub

The Update function is for changing the game scenery.

Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
    SpriteX += 1
    SpriteY += 1
    MyBase.Update(gameTime)
End Sub

And the Draw function is for screen rendering.

Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
    Me.Gfx.GraphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.Black)
    Me.Sb.Begin(Microsoft.Xna.Framework.Graphics.SpriteBlendMode.AlphaBlend)
    Me.Sb.Draw(Me.SpriteTexture, New Microsoft.Xna.Framework.Rectangle(Me.SpriteX, Me.SpriteY, 32, 32), _
         Microsoft.Xna.Framework.Graphics.Color.Red)
    Me.Sb.End()
    MyBase.Draw(gameTime)
End Sub

This is the complete code that produces a sprite that floats over the screen in Visual Basic using XNA:

Public Class TestGame
    Inherits Microsoft.Xna.Framework.Game

    Private Gfx As Microsoft.Xna.Framework.GraphicsDeviceManager

    Private Sb As Microsoft.Xna.Framework.Graphics.SpriteBatch
    Private SpriteTexture As Microsoft.Xna.Framework.Graphics.Texture2D
    Private SpriteX As Integer = 0
    Private SpriteY As Integer = 0

    Public Shared Sub Main()
        Dim Game As New TestGame()
        Game.Run()
    End Sub

    Public Sub New()
        Me.Gfx = New Microsoft.Xna.Framework.GraphicsDeviceManager(Me)
        Me.Gfx.PreferredBackBufferWidth = 800
        Me.Gfx.PreferredBackBufferHeight = 600
        If Not Me.Gfx.IsFullScreen Then
            Me.Gfx.ToggleFullScreen()
        End If
    End Sub

    Protected Overrides Sub Initialize()
        MyBase.Initialize()
    End Sub

    Protected Overrides Sub LoadContent()
        Me.Sb = New Microsoft.Xna.Framework.Graphics.SpriteBatch(Me.Gfx.GraphicsDevice)
        Me.SpriteTexture = Microsoft.Xna.Framework.Graphics.Texture2D.FromFile(Me.Gfx.GraphicsDevice, _
              "mysprite.png")
        MyBase.LoadContent()
    End Sub

    Protected Overrides Sub UnloadContent()
        MyBase.UnloadContent()
    End Sub

    Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
        SpriteX += 1
        SpriteY += 1
        MyBase.Update(gameTime)
    End Sub

    Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
        Me.Gfx.GraphicsDevice.Clear(Microsoft.Xna.Framework.Graphics.Color.Black)
        Me.Sb.Begin(Microsoft.Xna.Framework.Graphics.SpriteBlendMode.AlphaBlend)
        Me.Sb.Draw(Me.SpriteTexture, New Microsoft.Xna.Framework.Rectangle(Me.SpriteX, Me.SpriteY, 32, 32), _
                Microsoft.Xna.Framework.Graphics.Color.Red)
        Me.Sb.End()
        MyBase.Draw(gameTime)
    End Sub

End Class

The simplest query tool ever

A colleague wanted to do a database query from a computer without any database client. He needed a tool that allowed him to type in a SQL query, and receive a sortable grid with the result set. All of these features are built-in in the .NET Framework, and it didn’t take me more than 2 minutes to do an exe file with these features using Visual Studio 2010. I used .NET 2.0 because these basic features are available in that version, and he did not want to install a newer version of the .NET Framework.

This is the user interface: A tab strip with three tabs. One for a connection string, one for the query and one for the result grid. The first two contains a textbox each, and the third contains a DataGridView control. Also, the program has a status bar with a label and a toolstrip with two buttons; one for testing the connectionstring that the user enters in the textbox of the first tab, and one for executing the query and presenting the result in the grid.

The program consist one variable and four event handlers in one form. The variable holds the result set.

Private Ds As DataSet

The first function responds to the Load event of the form. This function restores the last values that from the textboxes. This is just for user convenience.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
    txtCn.Text = CType(Application.UserAppDataRegistry.GetValue("Cn", ""), String)
    txtQuery.Text = CType(Application.UserAppDataRegistry.GetValue("Query", ""), String)
End Sub

The second function responds to the Close event of the form. This function saves the values from the textboxes so that they can be restored (in the Load event) in the next session. Also, if needed, it disposes the dataset variable.

Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) _
Handles Me.FormClosed
    Application.UserAppDataRegistry.SetValue("Cn", txtCn.Text)
    Application.UserAppDataRegistry.SetValue("Query", txtQuery.Text)
    If Not Ds Is Nothing Then
        Ds.Dispose()
    End If
End Sub

This is the handler for the test button. It simply connects to the given data source, and tells if it succeeds or fails.

Private Sub btnTestConnection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnTestConnection.Click
    'Jump to the connection tab (the first one).
    TabControl1.SelectedTab = tabConnection

    'Do the test.
    Me.Cursor = Cursors.WaitCursor
    Dim Success As Boolean = False
    Try
        Using Cn As New SqlClient.SqlConnection(txtCn.Text)
            Cn.Open()
            Success = (Cn.State = ConnectionState.Open)
            Cn.Close()
        End Using
    Catch ex As Exception
    End Try
    Me.Cursor = Cursors.Default
    If Success Then
        lblStatus.Text = "Connection test succeeded."
        MessageBox.Show("Connection test succeeded.", Me.Text, _
            MessageBoxButtons.OK, MessageBoxIcon.Information)
    Else
        lblStatus.Text = "Connection test failed."
        MessageBox.Show("Connection test failed.", Me.Text, MessageBoxButtons.OK, _
            MessageBoxIcon.Error)
    End If
End Sub

Finally, this is the handler for the execute button.

Private Sub btnExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnExecute.Click
    'Remove the current data table as data source of the grid.
    DataGridView1.DataSource = Nothing

    If Not Me.Ds Is Nothing Then
        'If there is an old data set in memory, dispose that.
        Me.Ds.Dispose()
        'To remember that no data is present, set the variable to NULL.
        Me.Ds = Nothing
    End If

    'Jump to the result tab (the third one).
    TabControl1.SelectedTab = tabResult

    'Do the query and bind the result. Quick and dirty error "handling".
    Me.Cursor = Cursors.WaitCursor
    Try
        Using Cn As New SqlClient.SqlConnection(txtCn.Text)
            Cn.Open()
            Using Cmd As New SqlClient.SqlCommand(txtQuery.Text, Cn)
                Using Da As New SqlClient.SqlDataAdapter(Cmd)
                    Ds = New DataSet()
                    Da.Fill(Ds)
                    If Ds.Tables.Count > 0 Then
                        DataGridView1.DataSource = Ds.Tables(0)
                        If Ds.Tables.Count > 1 Then
                            Me.Cursor = Cursors.Default
                            MessageBox.Show("More than one dataset was returned.", "Query", _
                                MessageBoxButtons.OK, MessageBoxIcon.Information)
                        End If
                    Else
                        Me.Cursor = Cursors.Default
                        MessageBox.Show("No dataset was returned.", "Query", _
                            MessageBoxButtons.OK, MessageBoxIcon.Information)
                    End If
                End Using
            End Using
            Cn.Close()
        End Using
        lblStatus.Text = "Success."
    Catch ex As Exception
        lblStatus.Text = "Failed. " & ex.Message
            Me.Cursor = Cursors.Default
        MessageBox.Show(ex.Message, "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
    Me.Cursor = Cursors.Default
End Sub

So, making a personal query tool doesn’t have to take more than a couple of minutes in .NET.

ASP.NET 4.0: Diagrams

To get your hands on this new and cool feature, create an ASP.NET 4.0 application or web site from within Visual Studio 2010. Check the Data section of the Toolbox window for a new control called Chart. Dragging out a Chart onto a web page creates the following code:

<asp:Chart ID="Chart1" runat="server">
  <Series>
    <asp:Series Name="Series1">
  </asp:Series>
  </Series>
    <ChartAreas>
      <asp:ChartArea Name="ChartArea1">
    </asp:ChartArea>
  </ChartAreas>
</asp:Chart>

There is a huge amount of properties available for the chart. They control the look of the chart, the chart type among other things. I don’t have any databases installed on this computer, so to get some data to do a chart from; I connect the control to a data source that represents the system database master. I use the following query to get a bunch of large numbers:

SELECT [name],[number] FROM dbo.spt_values WHERE [number]>17000

I use number as Y value member.

This is what I have to do to get the fully functional chart! Fooling around with chart types and visual properties is dangerously amusing.

If you haven’t got a database server at all, you can quickly create an object data source in Visual Basic, and assign that to your chart. Connection this code…

Public Class MyChartData

    Private mValue As Integer

    Public Sub New(ByVal Value As Integer)
        Me.mValue = Value
    End Sub

    Public ReadOnly Property Value() As Integer
        Get
            Return Me.mValue
        End Get
    End Property

    Public Shared Function GetItems() As MyChartData()
        Dim Ret As New List(Of MyChartData)()
        Ret.Add(New MyChartData(10))
        Ret.Add(New MyChartData(20))
        Ret.Add(New MyChartData(15))
        Ret.Add(New MyChartData(25))
        Return Ret.ToArray()
    End Function

End Class

…gives you this beautiful result:

Ah, the simplicity! Aaaaah, the power!

Collection initializers

Now I have had the opportunity to try out the new collection initializers of Visual Basic 10. This is good stuff and I am very happy about being able to do line breaks when I use this (just as C programmers can do whenever they want). Examine this simple example that consist of a ContactPerson class, and a generic collection that I initialize using the collection initializer.

Module Module1

    Public Class ContactPerson
        Public FirstName As String
        Public LastName As String
        Public EMail As String

        Public Overrides Function ToString() As String
            Return Me.FirstName & " " & Me.LastName & " " & Me.EMail
        End Function
    End Class

    Sub Main()

        Dim L As New List(Of ContactPerson) From {
         {New ContactPerson With {.FirstName = "Anders", .LastName = "Andersson", .EMail = "anders@some.thing"}},
         {New ContactPerson With {.FirstName = "Bertil", .LastName = "Bengtsson", .EMail = "bertil@some.thing"}},
         {New ContactPerson With {.FirstName = "Calle", .LastName = "Ceder", .EMail = "calle@some.thing"}}
         }

        For Each P As ContactPerson In L
            Console.WriteLine(P.ToString())
        Next

    End Sub

End Module

Note that the element type does not require any special constructor, I can provide a constructor and target that, but here I am using the object initializer that was introduced in Visual Basic 9.

Instead of the parenthesis that I would use to call the List constructor, I use the From keyword with a curly bracket, and each element is surrounded by curly brackets, separated by a comma. Finally, I have to use another set of curly brackets because I use the object initializer for each element, instead of a regular constructor.

If I adapt this code to use a constructor for each element, this is how it could look. This uses the new collection initializer and traditional constructors (and therefor less curly brackets).

Module Module1

    Public Class ContactPerson
        Public Sub New(ByVal FirstName As String, ByVal LastName As String, ByVal EMail As String)
            Me.FirstName = FirstName
            Me.LastName = LastName
            Me.EMail = EMail
        End Sub
        Public FirstName As String
        Public LastName As String
        Public EMail As String

        Public Overrides Function ToString() As String
            Return Me.FirstName & " " & Me.LastName & " " & Me.EMail
        End Function
    End Class

    Sub Main()

        Dim L As New List(Of ContactPerson) From {
         {New ContactPerson("Anders", "Andersson", "anders@some.thing")},
         {New ContactPerson("Bertil", "Bengtsson", "bertil@some.thing")},
         {New ContactPerson("Calle", "Ceder", "calle@some.thing")}
         }

        For Each P As ContactPerson In L
            Console.WriteLine(P.ToString())
        Next

    End Sub

End Module

Collection initializers

There are only a few new changes and additions made to the language Visual Basic in version 10. Changes in version 7, 8 and 9 were huge, and from version 9, I really like what it has become, and all that is needed in version 10 is some polishing. I will spend a few posts on some of the features.

In version 9, we got object initializers and in Visual Basic 10 the initializers will work for arrays and collections. Microsoft call them Collection Initializers. This is a good example of polishing, because the object initializers did not help that much, especially not if you have implemented the constructors that you desire.

A Collection Initializer is a different story. Here, we actually accomplish something useful.

Now, we can create a collection and initialize it with some elements that also are initialized, all in one single line!

The syntax is:

Dim Variable = New CollectionClass = {{element initialization}, {element initialization}, …}

If you want to initialize a collection of objects, and each object is initialized with two integer values (this could be a polygon with points), the could would look like this (if I use the generic collection):

Dim C = New List(Of MyPoint) From {{10, 20}, {15, 25}, {30, 40}}

This would require 4 lines in Visual Basic 9. One to create the collection, and one for each element. If you like, you can break the line at a comma in Visual Basic 10. Good for formatting.