WinSoft.se

About Visual Basic and .NET

Some applications have that cool search feature that filters on what you search for, and displays the result in real time. The data that you are searching in is loaded, and then the record(s) that matches your search from that set of data is display. Usually, you would do this if you are handling fairly little data, and you would do this on a separate thread from the GUI thread, to prevent that your application get poor responsiveness. This whole process works incredible well with the Data Grid View of the .NET Framework.

The following example requires a form with a textbox (TextBox1) and a data grid view (DataGridView1). To use the application, just type something in the textbox, and watch the grid filtering its records. The Load event of the form populates the grid. The TextChanged of the textbox filters the grid.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    'Configure the data grid view.
    DataGridView1.ReadOnly = True
    DataGridView1.Columns.Add("ColA", "Some column")
    DataGridView1.Columns.Add("ColB", "Some other column")
    DataGridView1.AllowUserToAddRows = False
    DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
    DataGridView1.Rows.Clear()

    'Add lots of rows.
    For A As Integer = 500 To 999
        Dim Index As Integer = DataGridView1.Rows.Add()
        DataGridView1.Rows(Index).Cells(0).Value = A.ToString("000")
        DataGridView1.Rows(Index).Cells(1).Value = "Hello"
    Next

    'Add two rows with some names in them.
    Dim Temp As Integer = DataGridView1.Rows.Add()
    DataGridView1.Rows(Temp).Cells(0).Value = "Anders"
    DataGridView1.Rows(Temp).Cells(1).Value = "Bengt"

    Temp = DataGridView1.Rows.Add()
    DataGridView1.Rows(Temp).Cells(0).Value = "Calle"
    DataGridView1.Rows(Temp).Cells(1).Value = "David"

    'Again, add lots of rows.
    For A As Integer = 300 To 999
        Dim Index As Integer = DataGridView1.Rows.Add()
        DataGridView1.Rows(Index).Cells(0).Value = A.ToString("000")
        DataGridView1.Rows(Index).Cells(1).Value = "Good bye"
    Next

    'Now we have 1.203 rows in the grid. Do some resizing of the columns.
    DataGridView1.AutoResizeColumns()

End Sub

Private Sub TextBox1_TextChanged(ByVal _
     sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
    If DataGridView1.RowCount > 0 Then

        'What is the user searching for? Remove case information.
        Dim SearchFor As String = TextBox1.Text.ToLower().Trim()

        'If the user has cleared the search box, show all rows.
        If SearchFor = "" Then
            For I As Integer = 0 To DataGridView1.Rows.Count - 1
                DataGridView1.Rows(I).Visible = True
            Next
        Else

            'When the user types something in the textbox, search for
            'rows with cells that holds that value.
            For I As Integer = 0 To DataGridView1.Rows.Count - 1

                'Extract the values from the grid. Remove case information.
                Dim ColA As String = CType(DataGridView1.Rows(I).Cells(0).Value, _
String).ToLower()
                Dim ColB As String = CType(DataGridView1.Rows(I).Cells(1).Value, _
String).ToLower()

                'Show only matching rows.
                If ColA.IndexOf(SearchFor) > -1 OrElse ColB.IndexOf(SearchFor) > -1 Then
                    DataGridView1.Rows(I).Visible = True
                Else
                    DataGridView1.Rows(I).Visible = False
                End If

            Next
        End If

        'Select the first visible row.
        For I As Integer = 0 To DataGridView1.Rows.Count - 1
            If DataGridView1.Rows(I).Visible Then
                DataGridView1.CurrentCell = DataGridView1.Rows(I).Cells(0)
                Exit For
            End If
        Next

    End If
End Sub

If it is in your control, stay with SQL Server! If it isn’t, this is how you can do it.

When you install the .NET Connector for MySQL, a class library called MySql.Data is installed. You can add a reference to it from the Add Reference dialog. This gives you a new set of classes for accessing a MySQL database. This is what a connection to a database can look like:

Dim ConnectionString As String = "Server=XXX;Port=3306;Database=XXX;Uid=XXX;Pwd=XXX"
Using Cn As New MySql.Data.MySqlClient.MySqlConnection(ConnectionString)
  Cn.Open()

  Console.WriteLine(Cn.State.ToString())

  Cn.Close()
End Using

If you know you ADO.NET, the rest should be a stroll in the park. This code lists keywords in MySQL:

Dim ConnectionString As String = "Server=XXX;Port=3306;Database=mysql;Uid=XXX;Pwd=XXX"
Using Cn As New MySql.Data.MySqlClient.MySqlConnection(ConnectionString)
  Cn.Open()

  Using Cmd As New MySql.Data.MySqlClient.MySqlCommand("SELECT * FROM help_keyword", Cn)
    Dim R As MySql.Data.MySqlClient.MySqlDataReader = Cmd.ExecuteReader()
    While R.Read()
      Console.WriteLine(R.GetString(1))
    End While
    R.Close()
  End Using

  Cn.Close()
End Using

The file sync solution WsBackup has been with me for a long while, but I am not using it anymore and I am not developing it anymore. I did find a similar application with more features called PathSync. It has one button that you click to build a list of actions that the program will take, and another button to carry out the actions. Clear and simple, perfect if you are using USB stick to move files between different computers.

Since I created a DropBox account, USB sticks are unnecessary. DropBox synchronies files as they are changed via a virtual folder on the Internet, so the files are always available from any computer, without having to carry around USB sticks. Check it out att http://www.dropbox.com/.

Att gnälla på kristendomen är kanske att sparka på någon som redan ligger, men det skulle vara väldigt intressant att få höra en förklaring på detta:

Moderata kristna, alltså de som inte är fundamentalister, anser att människan är en produkt av evolutionen och litar generellt på vetenskapen. Berättelsen om Adam och Eva har aldrig hänt på riktigt, det är endast en symbolisk historia. Vi har evolverats och vi är kusiner med chimpanserna. Helt ok, det är så det är. Tror man dessutom på Jehova, så må det vara hänt.

Den förskräckliga teologin från Nya Testamentet som går ut på att Jesus sonar Adams brott, kräver inte den att man faktiskt tror på Adam? Eller dör Jesus för att förstärka moralen i en fabel? Och varför säger man att Judas bedrog Jesus med en kyss, om det nu var Jehova som offrade sin son till sig själv, för att övertala sig själv att förlåta dig för synder som du personligen inte begått? Hela tanken med moralen i NT är väl att man till och med ska kunna döma ut barn som bärare av en arvssynd, för att legitimera det blodsoffer som Jesus ändå var? Hade inte Judas gjort det han gjorde, hade hela Jehovas plan med sitt blodsoffer fallerat.

Det är något som är väldigt skumt här, även med anhängarna av denna religion (som för övrigt har en tendens att bära mordvapnet runt halsen). Det är konstigt att så många väljer religionen över förnuftet, även i dessa upplysta tider.

You just got to love the YouTube user cdk007. In his (at this point) latest video, he spends 10 minutes to explain how radiometric dating to a hypothetic creationist, adding the objections you would expect from a creationist. If you ever hear the argument that radiometric dating doesn’t work (assuming that we don’t know how atoms work), get them to watch this! Or at least, make sure you know the correct answer to the following question:

How do we know that we actually can trust radiometric dating?

Hur fungerar detta nu igen?

Please read this first. This post shows how detect mouse input in The Wall.

The Wall provides functionality for displaying data on a screen, an important component for anyone building an intelligent home. The system relies on the user’s ability use VBScript to collect data he or she wants to display, but there are some built in functions for simplifying this. I will cover these functions later. Finally, it has a very simple mechanism for detecting clicks or touch screen activity, demonstrated here.

To activate click detection, call the RegisterClickCallback function and pass the name of the function that will be called when a click is detected, “ClickCallback” in this case.

The following code will register a text item for displaying the current date and time, a numeric item for displaying the number of detected clicks, and another text item for displaying the coordinate of the click (in characters):

'Blueish background color.
BackgroundColor = "#334499"

'The background grid can be useful when designing the screen.
BackgroundGrid = True

'Every 60 seconds, display the current date and time.
RegisterTextItem 60, "DateAndTime", 0, 0, "#00ffff", "UpdateDateAndTime"

'For the fun of it, a click counter updated each second.
RegisterNumericItem 1, "Counter", 0, 2, "#ffff00", "UpdateCounter"
Set Item=GetItem("Counter")
Item.CharacterCount=3

Dim ClickCounter
ClickCounter=0

'And a string that displays the coordinates.
RegisterTextItem 1, "Coordinates", 0, 4, "#ff88ff", "UpdateCoordinates"

Dim LastX
Dim LastY
LastX = -1
LastY = -1

'This is the magic: Activate a callback for each click.
RegisterClickCallback "ClickCallback"

'Callback: Display date and time.
Sub UpdateDateAndTime(ByVal Item)
   Item.Value = "Date: " & GetDate() & " Time: " & GetShortTime()
End Sub

'Callback: Display the click counter.
Sub UpdateCounter(ByVal Item)
   Item.Value = ClickCounter
End Sub

'Callback: Display the coordinates where the click occured.
Sub UpdateCoordinates(ByVal Item)
   Item.Value = LastX & ", " & LastY
End Sub

'This callback is not called on a given interval, but
'when the user clicks (or points at the touch screen).
Sub ClickCallback(ByVal X, ByVal Y)
   'Save the coordinates and increase the counter.
   ClickCounter = ClickCounter + 1
   LastX = X
   LastY = Y
End Sub

The result might look like this after 7 clicks:

Please read this first. This post shows how to display bars using The Wall.

Bars are created using the RegisterBarItem function. These are the arguments:

Parameter 1: UpdateFrequency (32 bit integer) tells how often the text should be updated (that is, how often the callback function will be called) in seconds. 0 means that the item never will be updated. All callback functions are called at startup, and if the UpdateFrequency parameter is greater than 0, it will be called again and again until The Wall is closed. In the example above, CallbackA will be called once, CallbackB will be called each second and CallbackC will be called every two seconds.

Parameter 2: Name (string) is the name of the item for later reference.

Parameter 3 and 4: The X and Y position in characters for the item.

Parameter 5: The color of the item in HTML format.

Parameter 6: The name of the callback procedure. All callback procedures take one object parameter. The type of the object that is passed depend on the type of item you add.

In the following example, I create four bars, and I then use the GetItem function to get a reference to each bar so that I can set some properties of the bar.

HighAlarmLevel gets or sets how high value the Value property can be before it causes the bar to enter alarm state.

LowAlarmLevel gets or sets how low the value of the Value property can be before it causes the bar to enter alarm state.

Orientation gets or sets the bar orientation. It can be Horizontal or Vertical.

Size gets or sets the height of a vertical bar or the length of a horizontal bar.

ValueVisible gets or sets whether the value of the bar will be printed out on the bar. If so, ValueColor control the color and DecimalCount controls the number of decimals that will be used.

Finally, the script holds the callback functions for the four bars. I have chosen to call them UpdateFirstBar, UpdateSecondBar, UpdateThirdBar and UpdateFourthBar.

'Grey background color.
BackgroundColor = "#666666"

'Register 4 bars, each with one second interval.
RegisterBarItem 1, "Bar1", 3, 1, "#00ff00", "UpdateFirstBar"
RegisterBarItem 1, "Bar2", 7, 1, "#00ff00", "UpdateSecondBar"
RegisterBarItem 1, "Bar3", 1, 5, "#00ff00", "UpdateThirdBar"
RegisterBarItem 1, "Bar4", 1, 6, "#00ff00", "UpdateFourthBar"

Dim B

'Do some initialization of the first bar:
Set B = GetItem("Bar1")
B.HighAlarmLevel = 10
B.DecimalCount = 2
B.Orientation = Vertical
B.ValueColor = "#ffffff"
B.Size = 4

'Do some initialization of the second bar:
Set B = GetItem("Bar2")
B.Orientation = Vertical
B.ValueVisible = False
B.Size = 4

'Do some initialization of the third bar:
Set B = GetItem("Bar3")
B.Orientation = Horizontal
B.ValueVisible = False
B.Size = 9

'And the fourth:
Set B = GetItem("Bar4")
B.HighAlarmLevel = 10
B.DecimalCount = 2
B.Orientation = Horizontal
B.ValueColor = "#ffffff"
B.Size = 9

'The callbacks. Item.Value is a double that represents the fill percentage.

Sub UpdateFirstBar(ByVal Item)
   Item.Value = (Item.Value + 0.31)
End Sub

Sub UpdateSecondBar(ByVal Item)
   Item.Value = (Item.Value + 0.5)
End Sub

Sub UpdateThirdBar(ByVal Item)
   Item.Value = (Item.Value + 2)
End Sub

Sub UpdateFourthBar(ByVal Item)
   Item.Value = (Item.Value + 1)
End Sub

This is a screenshot of The Wall running the above script:

Please read this first. This post shows how to display text numeric using The Wall.

To register a numeric item, call the RegisterNumericItem function. It takes the same arguments as the RegisterTextItem function, but you might want to set some properties to the numeric item.

In this example, I add one text item and one numeric item. I then use the GetItem function to get a reference to the numeric item, so that I can set some of its properties.

The numeric items have properties for setting the expected range of the numeric value. These properties are called LowAlarmLevel and HighAlarmLevel. In this example, I set the HighAlarmLevel to 20, making the item flash if the Value property holds a value that equals to 20 or is higher.

Since the callback function HandleNumber is called each second (see the first argument in the RegisterNumericItem call) the value property will be out of range after 20 seconds, and the numeric item will start flashing on the screen.

Here is the VBScript code for this (must be located in TheWall.vbs):

'Make full screen on primary screen.
'Exclude this line for windowed mode.
MakeFullscreen 0

'Grey background color.
BackgroundColor = "#666666"

'Register a static text item.
RegisterTextItem 0, "MyStaticText", 1, 1, "#bbccdd", "InitTextItem"

'Register a numeric item with one update per second.
RegisterNumericItem 1, "MyNumericItem", 38, 1, "#00ff00", "HandleNumber"

'Do some initialization of the numeric item. Get a reference...
Dim N
Set N = GetItem("MyNumericItem")

'...set the upper alarm threshold...
N.HighAlarmLevel = 20

'...the number of characters positions I want to display...
N.CharacterCount = 3

'...and the number of decimals I want to display. None.
N.DecimalCount = 0

'The callback for the text item. Called once.
Sub InitTextItem(ByVal Item)
   Item.Value = "An increasing number with alarm at 20:"
End Sub

'The callback for the numeric item. Called once a second.
Sub HandleNumber(ByVal Item)
   Item.Value = (Item.Value + 1)
End Sub

You should see something like this on your screen:

 An increasing number with alarm at 20: 17

Note that the Value property of a text item is a String (as in the InitTextItem callback function) but for a numeric item, the Value property is a Double (as in the HandleNumber callback function).

Please read this first. This post shows how to display text values using The Wall.

This is a very simple panel. To run it, place this code in a file called TheWall.vbs, place it next to TheWall.exe and start TheWall.exe. If you are running a single display system, you must delete the first line or change it so that it says MakeFullscreen 0.

'Make full screen on secondary screen (0 = primary screen).
'Exclude this line for windowed mode.
MakeFullscreen 1

'Black background color.
BackgroundColor = "#000000"

'Register three text items.
RegisterTextItem 0, "A", 0, 0, "#00ff00", "CallbackA"
RegisterTextItem 1, "B", 1, 1, "#0000ff", "CallbackB"
RegisterTextItem 2, "C", 2, 2, "#00ffff", "CallbackC"

Sub CallbackA(ByVal Item)
   'For a text item, value (what the item is displaying) is a string.
   Item.Value = "Some green text"
End Sub

Sub CallbackB(ByVal Item)
   Item.Value = "Some blue text"
End Sub

Sub CallbackC(ByVal Item)
   Item.Value = "Some cyan text"
End Sub

This is the result:

Each item you want The Wall to display has two parts: The registration and the callback function. In the example above, the registration is represented by three calls to the RegisterTextItem function, each call for every item. The registration tells The Wall what items it should display, the callback function tells The Wall the value that the item should display. These are the arguments of the RegisterTextItem function:

Parameter 1: UpdateFrequency (32 bit integer) tells how often the text should be updated (that is, how often the callback function will be called) in seconds. 0 means that the item never will be updated. All callback functions are called at startup, and if the UpdateFrequency parameter is greater than 0, it will be called again and again until The Wall is closed. In the example above, CallbackA will be called once, CallbackB will be called each second and CallbackC will be called every two seconds.

Parameter 2: Name (string) is the name of the item for later reference.

Parameter 3 and 4: The X and Y position in characters for the item.

Parameter 5: The color of the item in HTML format.

Parameter 6: The name of the callback procedure. All callback procedures take one object parameter. The type of the object that is passed depend on the type of item you add.

If this program gets to run for 71 seconds, the output will be A=1, B=71 and C=36 because CallbackA is called once at startup, CallbackB is called every second and CallbackC is called each other second (you might need to adjust the first line):

MakeFullscreen 1
BackgroundColor = "#000000"

RegisterTextItem 0, "A", 0, 0, "#00ff00", "CallbackA"
RegisterTextItem 1, "B", 1, 1, "#0000ff", "CallbackB"
RegisterTextItem 2, "C", 2, 2, "#00ffff", "CallbackC"

Dim A
A = 0

Dim B
B = 0

Dim C
C = 0

Sub CallbackA(ByVal Item)
   A = A + 1
   Item.Value = ("A=" & CStr(A))
End Sub

Sub CallbackB(ByVal Item)
   B = B + 1
   Item.Value = ("B=" & CStr(B))
End Sub

Sub CallbackC(ByVal Item)
   C = C + 1
   Item.Value = ("C=" & CStr(C))
End Sub

The reason for using callback functions for collecting the values that should be displayed is that the value might be likely to change. The reason for using VBScript for this is that you might want to display values that The Wall doesn’t know how to collect. Can you grab the value using VBScript, you can feed it to The Wall. No limits!