Tuesday, May 27, 2008

GetPath in VB.NET 2005

In VB6 we used to use App.Path to get the path of the application.  When I converted to VB.NET 2003, I started to using
System.Reflection.Assembly.GetExecutingAssembly.Location without actually knowing what I was doing, but it worked and I was getting the location of the path,

However, in VB.NET 2005, this stopped working and the path it would give me was something like:
C:\Documents And Settings\......\LocalSettings\Application Data\Microsoft\VisualStudio\8.0\ProjectAssemblies\_ean0rwersws\.....

Now the "eanOrwersws" was a random folder that it generated whenever I rebuilt the application.  This seemed odd to me.

It turns out that the better way to get the Path of the application is to use one of the following calls:
System.Windows.Forms.Application.StartupPath <-- This returns the path without a "\"

I can't tell the difference between the following two calls, but they both return the path with a "\" at the end.
System.AppDomain.CurrentDomain.BaseDirectory()
AppDomain.CurrentDomain.SetupInformation.ApplicationBase()


Wednesday, May 21, 2008

Detect the Shift, Ctrl, Return Key pressed at the same time

Another simple one.  I needed to detect if the Shift, Ctrl, and Return key were pressed at the same time.  Now, the three combinations, could consist of the Alt key as well.  Anyways, for some reason I just wasn't getting it, even though I knew it was a simple problem.  This is my solution.  If you were to debug this.  Just open a new Windows Application project and paste this in.  The key thing if you were to debug this is to put the breakpoint on the Debug line.  If you put the breakpoint on the Select Case statement (which I was doing and which was messing me up), it will appear that its not working.  Basically the reason is that if you press the Shift, Ctrl, and Return key, the first time through the Routine it will detect the Shift, or Ctrl keys, and it won't go into your if statement.  However, after it goes through those checks, it will evaluate the Return key that was pressed.  Now, when the return key is pressed you check if the Shift and Control keys are also down through the statement e.Shift and e.Control.  This returns true and you are set.

  Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    Select Case e.KeyCode
      Case Keys.Enter
        If e.Shift And e.Control Then
          Debug.Write("all three pressed")
        End If
    End Select
  End Sub

The MSDN documentation has an example where you use the e.Modifiers value, and to be honest at this point I am not sure how that value gets set.  But the above procedure does work.

-- Ted

Wednesday, May 14, 2008

Missing References Folder in Solution Explorer in VS2005

I upgraded to VS2005 and all of a sudden I couldn't find my references folder in the Solution Explorer.  Yes,  I could see it via the Properties of a project, but I liked seeing it as a folder like I did in VS2003.  The solution it turns out is very simple, in the top of the Solution Explorer is a button you can press to "Show All Files" this toggles it on and off.

Thursday, May 1, 2008

Update - Datagridview - Sorting Numeric Columns that are not bound...

I found an example on a website that did what I mention above but does it a lot better.  Below is the pasted code

    Private Sub grd_SortCompare(ByVal sender As
Object, ByVal e As System.Windows.Forms.DataGridViewSortCompareEventArgs) Handles grdList.SortCompare
        e.SortResult = CompareEx(e.CellValue1.ToString, e.CellValue2.ToString)
        e.Handled = True
        Exit Sub
    End Sub


    Public Function CompareEx(ByVal s1 As Object, ByVal s2 As Object) As Integer

        Try
' convert the objects to string if possible.
            Dim a As String = CType(s1, String)
            Dim b As String = CType(s2, String)

' If the values are the same, then return 0 to indicate as much
            If s1 = s2 then return 0

' Look to see if either of the values are numbers
            Dim IsNum1 As Boolean = IsNumeric(a)
            Dim IsNum2 As Boolean = IsNumeric(b)

' If both values are numeric, then do a numeric compare
            If IsNum1 And IsNum2 Then
                If Double.Parse(s1) > Double.Parse(s2) Then
                    Return 1
                ElseIf Double.Parse(s1) < Double.Parse(s2) Then
                    Return -1
                Else
                    Return 0
                End If
' If the first value is a number, but the second is not, then assume the number is "higher in the list"
            ElseIf IsNum1 And IsNum2 = False Then
                Return -1
' if the first values is not a number, but the second is, then assume the number is higher
            ElseIf IsNum1 = False And IsNum2 Then
                Return 1
            Else
' If both values are non nuermic, then do a normal string compare
                Return String.Compare(s1, s2)
            End If
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
        End Try

' If we got here, then we failed to compare, so return 0
        return 0
    End Function

Datagridview - Sorting Numeric Columns that are not bound to a DataSource

Or more precisely sorting Double (floating point, decimal) Columns that are not bound to a DataSource.

There are a lot of examples out there to sort datagridview columns that are bound to a datasource, but I could only find one example that had a solution to solving the problem of sorting when the data is not bound to a datasource.

This is the data that I have, in a csv file
Dharmit,Male,10.001,First
Lomesha,Female,11.001,Second
Jaymit,Male,7.001,Third
Ambrish,Male,8.001,First
Chanda,Female,172.00101,Second

The third column (lets call it Order) contains data that is not integers, they are double values.  I load it into a datagrid view by reading each line to a String Array, and then loading the array to the datagridview.

When I do a sortascending on the Order column, it sorts it as if it was String/ or Text instead of as a number.  If the Order column had values like 10, 11, 7, 8, 172 it would sort it properly, but the decimal point screws it up into thinking that it is text.  The solution to this problem is to use the SortCompare event, and to manually figure out if values are equal, greater than or less than.  Initially I didn't understand the sortResult values.  What does 1, -1, and 0 mean.  And to be honest I still don't know, just trial and error.  Some things to keep in mind.  The Data must not be be bound, and the VirtualMode must be False, and the SortCompare is called when the Sort is called, in my case I call it programatically and have set it such.  Also the code below assumes the data is numeric.

  Private Sub DataGridView1_SortCompare(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare
    If Double.Parse(e.CellValue1) > Double.Parse(e.CellValue2) Then
      e.SortResult = 1
    ElseIf Double.Parse(e.CellValue1) < Double.Parse(e.CellValue2) Then
      e.SortResult = -1
    Else
      e.SortResult = 0
    End If
    e.Handled = True
    Exit Sub
  End Sub