Best vb.net questions in June 2011

Adding two .NET SqlDecimals increases precision?

12 votes

in .NET, when I add two SqlDecimals, like so:

SqlDecimal s1 = new SqlDecimal(1);
SqlDecimal s2 = new SqlDecimal(1);
SqlDecimal s3 = s1 + s2;

then s3 has precision 2, whereas both s1 and s2 have precision 1.

This seems odd, especially as the documentation states that the return value of the addition operator is "A new SqlDecimal structure whose Value property contains the sum." I.e. according to the documentation, addition should not change the precision.

Am I missing something here? Is this intended behaviour?

Cheers,

Tilman

This article (http://msdn.microsoft.com/en-us/library/ms190476.aspx) explains the behavior for the SQL types, and I assume the .NET Sql data types reflect that in their behavior.

How to calculate the total time a user spending on an application?

11 votes

I want to create an application that able to calculate the total time the user (i.e. myself) spent on a particular application, for example Firefox. And this application should display warning message if the user spent a lot of time on Firefox (for example 1 hour or more)

Reason: I'm a VB.NET developer. During my working hours, my main tool is Visual Studio and I suppose to do coding. But I need Firefox occasionally to access internet (particularly SO and other sites) to find solutions for my programming problems. The problem is I addicted to SO and SO sucks my time for hours until I have forgotten that I suppose to continue coding and not browsing the SO site.

My question: How to calculate the total time a user spending on an open application like Firefox?

Update:

I need to play a song as warning message to myself if I stay too long on Firefox. My intent is to create a winform or windows service to achieve this

This is not a programming problem. This is a discipline problem. My advises:

  1. First of all, don't rely on application to tell you what to do.
  2. Secondly, the application can warn you but ultimately you can disable it, turn it off.
  3. Thirdly, my suggestion to your real problem i.e. no discipline and poor work ethic is to put up a small banner in front of your monitor with this text "Focus on your work" or "Code it now" or "SO is evil"

How to create a new System.String type with other name?

10 votes

I try to describe my problem step by step because I do not know how to say it in correct programming terms.

When I use a System.String type, I do the following:

  1. Declare the type: Dim Str1 as String
  2. Assign its value: Str1 = "This is a string"

I want to create a new type that just like the System.String type but in different name. For example, I want to create a UrlString type for string like this:

  1. Declare the type: Dim Str2 as UrlString
  2. Assign its value: Str2 = "http://www.example.com"

My question is: How do I create the UrlString type?

The reason: I want to create the UrlString type to help me to identify the value of the content. For example, UrlString type means the string is in url format, PhoneString means the string is in phone format, CreditCardString type means the string is in credit card format and so on.

UPDATE:

Thanks Marc Gravell and GSerg. Here is the solution:

Class UrlString
    Private ReadOnly value As String

    Public Sub New(ByVal value As String)
        Me.value = value
    End Sub

    Public Shared Widening Operator CType(ByVal value As String) As UrlString
        Return New UrlString(value)
    End Operator

    Public Shared Widening Operator CType(ByVal u As UrlString) As String
        Return u.value
    End Operator

    Public Overrides Function GetHashCode() As Integer
        Return If(value Is Nothing, 0, value.GetHashCode())
    End Function

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        Return String.Equals(value, DirectCast(obj, String))
    End Function

    Public Overrides Function ToString() As String
        Return value
    End Function
End Class

You need to add an implicit conversion operator from string to UrlString for that to work. In C#:

class UrlString
{
    private readonly string value;
    public UrlString(string value) { this.value = value; }
    public static implicit operator UrlString(string value)
    {
        return new UrlString(value);
    }
    public override int GetHashCode()
    {
        return value == null ? 0 : value.GetHashCode();
    }
    public override bool Equals(object obj)
    {
        return string.Equals(value, (string)obj);
    }
    public override string ToString()
    {
        return value;
    }
}

Then:

UrlString foo = "abc";

How to turn off monitor using vb.net code

8 votes

How to turn off monitor using vb.net code? Ok, actually I found the c# solution. But I need the vb.net solution. I have tried online C# to vb.net converter, but the converter complaining that there are errors in it.

Please help me to translate following C# code to vb.net:

using System.Runtime.InteropServices; //to DllImport

public int WM_SYSCOMMAND = 0x0112;
public int SC_MONITORPOWER = 0xF170; //Using the system pre-defined MSDN constants that can be used by the SendMessage() function .


[DllImport("user32.dll")]
private static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);
//To call a DLL function from C#, you must provide this declaration .


private void button1_Click(object sender, System.EventArgs e)
{

SendMessage( this.Handle.ToInt32() , WM_SYSCOMMAND , SC_MONITORPOWER ,2 );//DLL function
}

UPDATE:

I use this online converter

UPDATE: Here is the solution in vb.net

Imports System.Runtime.InteropServices

Public Class Form1
    Public WM_SYSCOMMAND As Integer = &H112
    Public SC_MONITORPOWER As Integer = &HF170

    <DllImport("user32.dll")> _
    Private Shared Function SendMessage(ByVal hWnd As Integer, ByVal hMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    End Function

    Private Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        SendMessage(Me.Handle.ToInt32(), WM_SYSCOMMAND, SC_MONITORPOWER, 2)
    End Sub


End Class

Try this

Public WM_SYSCOMMAND As Integer = &H112
Public SC_MONITORPOWER As Integer = &Hf170

<DllImport("user32.dll")> _
Private Shared Function SendMessage(hWnd As Integer, hMsg As Integer, wParam As Integer, lParam As Integer) As Integer
End Function

Private Sub button1_Click(sender As Object, e As System.EventArgs)
    SendMessage(Me.Handle.ToInt32(), WM_SYSCOMMAND, SC_MONITORPOWER, 2)
End Sub

No increment operator in VB.net

7 votes

I am fairly new to vb.net and came across this issue while converting a for loop in C# to VB.net I realized that the increment operators are not available in vb.net (++ and --) whereas i was able it do something like cnt +=1

I researched a bit and came across Eric's post on the same, but wasn't really able to understand fully on it. He mentions of In VB, a STATEMENT cannot be just an EXPRESSION. not sure how that really fits in.

I hope someone here would be able to explain why this doesn't work in the same way as it does in C#. (Hope this will also hold true as in why we have == in C# for comparison)

I would say that the language designers simply thought that BASIC was a better baseline than C when designing Visual BASIC. You can follow the lineage of C (and, earlier, BCPL) through C++, Java and C#.

The VB lineage comes from the original BASIC from Dartmouth (and, earlier, Fortran) and is a different beast altogether.

In other words, what started as the venerable BASIC:

LET I = I + 1

has probably been hacked and destroyed enough :-)

As per Eric's post, i++; is indeed just an expression, one that yields i with the side effect that i is incremented after the event (i++; is an expression, just like the non-side-effect expression i;).

That's because C allows these naked expressions, even things like 42; which doesn't really do much but is perfectly valid. In other words, the following is a complete C program:

int main (void) { 1; 2; 3; 4; 5; 6; 7; 8; 9; return 0; }

All those expressions are valid but useless.

In BASIC, this was not really done, because BASIC consisted of statements (things that did something). That's why i += 1 (a statement incrementing i) is considered kosher but i++ (an expression doing nothing which just happens to have a side effect which increments i) isn't. You could argue that it's just semantic hair-splitting and no doubt the VB designers did argue.

But the group that won the day were the "we don't need no steekin' C in our beloved language" group.

You should be thankful for small mercies, at least you're not having to deal with COBOL:

MOVE DD_WS_I + 1 TO DD_WS_I.

Visual Basic Regular Expression Question

5 votes

I have a list of string. When user inputs chars in, the program would display all possible strings from the list in a textbox.

Dim fruit as new List(Of String) 'contains apple,orange,pear,banana
Dim rx as New Regex(fruit)

For example If user enters a,p,l,e,r , then the program would display apple and pear. It should match any entry for which all letters have been entered, regardless of order and regardless of additional letters. What should I add to rx? If it's not possible with Regular Expressions, then please specify any other ways to do this.

LINQ Approach:

Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" }
Dim input As String = "a,p,l,e,r"
Dim letters As String = input.Replace(",", "")
Dim result = fruits.Where(Function(fruit) Not fruit.Except(letters).Any())

Regex Approach:

A regex pattern to match the results would resemble something like:

"^[apler]+$"

This can be built up as:

Dim fruits As New List(Of String) From { "apple", "orange", "pear", "banana" }
Dim input As String = "n,a,b,r,o,n,g,e"
Dim letters As String = input.Replace(",", "")
Dim pattern As String = "^[" + letters + "]+$"
Dim query = fruits.Where(Function(fruit) Regex.IsMatch(fruit, pattern))

Merging 2 Lists in LINQ

5 votes

I have two Lists of custom objects:

List1: Year, Month, ValueA
List2: Year, Month, ValueB

I want to get a third List with a merge between the two:

List3: Year, Month, ValueA, ValueB

Is there any elegant way to perform that in LINQ VB.Net?

Example:

List1:
2010 - 6 - 2
2010 - 7 - 5
2010 - 10 - 3

List2:
2010 - 7 - 2
2010 - 8 - 1
2010 - 10 - 2

List3 (result):
2010 - 6 - 2 - 0
2010 - 7 - 5 - 2
2010 - 8 - 0 - 1
2010 - 10 - 3 - 2

Thanks in advance.

Solution VB.Net translation of the solution :

Dim ListA = From a In List1
    Group Join b In List2
    On a.Year Equals b.Year And a.Month Equals b.Month Into bGroup = Group
    From b In bGroup.DefaultIfEmpty()
    Select a.Year, a.Month, a.Value1, Value2 = If(b Is Nothing, 0, b.Value2)
Dim ListB = From b In List2
    Group Join a In List1
    On b.Year Equals a.Year And b.Month Equals a.Month Into aGroup = Group
    From a In aGroup.DefaultIfEmpty()
    Select b.Year, b.Month, Value1 = If(a Is Nothing, 0, a.Value1), b.Value2
Dim List3 = ListA.Union(ListB)

Sure, you're looking to perform a Full Outer Join on the data, which doesn't exist in LINQ, so we fake it with two unioned Left Outer Joins:

var A = from a in List1
    join b in List2 on new { a.Year, a.Month } equals new { b.Year, b.Month }
        into bgroup
    from b in bgroup.DefaultIfEmpty()
    select new { a.Year, a.Month, a.ValueA, ValueB = (b == null ? 0 : b.ValueB) };

var B = from b in List2
    join a in List1 on new { b.Year, b.Month } equals new { a.Year, a.Month } 
        into agroup
    from a in agroup.DefaultIfEmpty()
    select new { b.Year, b.Month, ValueA = (a == null ? 0 : a.ValueA), b.ValueB };

var List3 = A.Union(B);

Many apologies for the C#, I could not get my VB.Net example to work for the life of me. You need two left outer joins to be unioned to produce the correct answer. None of the code converters I tried worked either.


The following is VB.Net that LINQPad chokes on, but every example I can find says should be correct:

Dim A = From a In List1 _
    Group Join b In List2 _
        On New With { a.Year, a.Month } Equals New With { b.Year, b.Month} _
        Into bGroup = Group _
    From b In bGroup.DefaultIfEmpty() _
    Select a.Year, a.Month, a.ValueA, ValueB = If(b Is Nothing, 0, b.ValueB)

Dim B = From b In List2 _
    Group Join a In List1 _
        On New With { b.Year, b.Month } Equals New With { a.Year, a.Month} _
        Into aGroup = Group _
    From a In aGroup.DefaultIfEmpty() _
    Select b.Year, b.Month, ValueA = If(a Is Nothing, 0, a.ValueA), b.ValueB

Dim List3 = A.Union(B)

VB.Net why is this not a bug?

5 votes

I encounter what I believe to be a bug and I was just wondering if this is already known as a issue or if this is not a issue and why.

The problem related to Read Only Properties on a Type when compiling with the VB.Net Compiler in Visual Studio 2008.

Follows are the class definitions and a small C# program which will not compile. (And is correct in not compiling IMHO because the property being set in the Delegate is Read-only)

public interface ITest
{
    bool PrivateBool { get; }
}

public class TestClass : ITest
{
    bool privateBool = false;

    public bool PrivateBool
    {
        get
        {
            return privateBool;
        }
    }

    bool publicBool = false;

    public bool PublicBool
    {
        get { return publicBool; }
        set { publicBool = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass tc = new TestClass();
        //Compile Error
        //tc.PrivateBool = false;

        //Compile Error
        //Action act = new Action(delegate()
        //{
        //    tc.PrivateBool = false;
        //});

        //Action<TestClass> test = new Action<TestClass>(delegate(TestClass tcc)
        //{
        //    tcc.PrivateBool = false;               
        //});

        //Compile Time Error
        //Action<TestClass> test = new Action<TestClass>( tz=> tz.PrivateBool = false);

        //Compile Time Error
        //Action test = new Action(tc.PrivateBool = false);
    }
}

In VB.Net However this is a larger issue… the program will compile and execute with no exception. But the property is not set. This was a nightmare to catch in the debugger at Run time and we feel that the compiler should have caught that we are assigning to a ready only property just as the CSharp compiler alerts you when compiling.

Module Module1

    Sub Main()

        Dim tc As New TestClass()
        Dim setP = New Action(Of TestClass)(Function(d As TestClass) _
                                                d.PrivateBool = False _
                                                )

        setP.Invoke(tc)


    End Sub

End Module

Can anyone explain if this is correct logic and why?

I assume that someone will respond that the job of the compiler was fulfilled by examining the parameter type to the delegate and that the delegate was typed to accept that parameter just as it should when parsing a Method Body or a Function Body.

My rebuttal to this would be that the compiler DOES throw an error when that property is attempted to be set from within a method but not the delegate. Delegates should be parsed the same as a Method.

Is the C# compiler over extending itself? I think not. My experience is that this is a bug in the vb.net compiler and should be fixed by a patch to the IDE.

Last but surely not least what occurs when the Invoke happens?

The delegate surely does not use reflection to set the property automagically so I assume the CLR sees the read-only qualifier and a NOOP gets executed. Is that actually what occurs or is the behavior undefined?

Thank you for your time!

In VB.NET 2008, there are no statement lambdas. All lambdas are functions. They return a value, not perform an action.

Your VB lambda simply compares d.PrivateBool and False and returns the result of the comparison.

This is not a bug and by design. It is therefore advisable to avoid assigning VB.NET 2008's lambdas to an Action, this is highly confusing for an unprepared person.

Statement lambdas appeared in VB.NET 2010.

How to get a checked radio button in a groupbox?

4 votes

I have a lot of radio buttons in a groupbox. Normally I will check each radio button individually using If radiobutton1.Checked = True Then.

But I think maybe there is smart way to check which radio button being checked in a groupbox. Any idea?

try this

Dim rButton As RadioButton = 
        GroupBox1.Controls
       .OfType(Of RadioButton)
       .Where(Function(r) r.Checked = True)
       .FirstOrDefault()

this will return the Checked RadioButton in a GroupBox

How to save System.Collections.Specialized.NameValueCollection instance to hard disk and load it back as an instance?

4 votes

I have following instance of System.Collections.Specialized.NameValueCollection:

Dim UserSelection As New System.Collections.Specialized.NameValueCollection

UserSelection.Add("D_Color1", "Black")
UserSelection.Add("D_Color2", "Green")
UserSelection.Add("D_Color3", "Purple")

I need to save this instance to hard disk and then load it back from hard disk as an instance. How do I do that?

With the BinaryFormatter

Using fs As New FileStream("DataFile.dat", FileMode.Create)
   Dim formatter As New BinaryFormatter
   formatter.Serialize(fs, UserSelection)
End Using

And to deserialize

Using fs As New FileStream("DataFile.dat", FileMode.Open)
    Dim formatter As New BinaryFormatter
    UserSelection = DirectCast(formatter.Deserialize(fs), NameValueCollection)
End Using

How to get the number of CPU cycles used by a process

4 votes

I have a need to get the number of CPU cycles used by a specific process using C# (or VB.Net). This information is available in the Process properties popup within Sysinternal's Process Explorer. For instance, the browser that I'm using the post this message has currently used 18,521,360,165 cyles (give or take a few hundred million). Does anyone know how to get this information from a .Net app? I know how to get the CPU usage (percentage), but this isn't what I'm looking for. I need a way to compare CPU usage between two different processes running at different times.

Thank you, Matt

Update:
Why do I need this? I'm the leader of the local .Net user group and we're running a code challenge where developers submit code to solve a problem. I need a way to measure the performance of one entry against another. Currently I'm using a timer to measure performance. The server is 100% dedicated to this, but that doesn't guarantee that something else might be happening at the same time. Obviously, this is frought with all kinds of potential issues, but generally speaking, it's fairly accurate. Measuring the number of CPU cycles used would be an almost fool proof way to measure how well someone's entry performs against another. I'm certain that someone can shoot holes all over this - no need to try at this point. ;-) I hope that helps explain the reason behind my question and why a timer is insufficient for solving my problem.

Process Explorer calls QueryProcessCycleTime to get that information. You will probably have to use P/Invoke to call it. I would expect its P/Invoke signature to look like:

[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool QueryProcessCycleTime(IntPtr ProcessHandle, out ulong CycleTime);

How do you test for a renamed partial method?

4 votes

I'm using Linq to SQL, which generates partial classes and partial methods. You then extend that generated code by implementing your your customizations manually in another partial class. One of the hooks L2S gives you is the ability to implement partial methods that get called when a property changes. For example, if you have a property named "MyProp", then you can implement a partial method like so:

' Given to you in the generator
Partial Private Sub OnMyPropChanged()
End Sub

' Manually implemented in my custom class
' I cannot specify that this is an implementation of a Partial, even though it is...
Private Sub OnMyPropChanged()
   Console.WriteLine("My prop changed... do something here")
End Sub

The problem I'm having is the name of "MyProp" has now changed to "MyNewPropName", so now the partial in the generator creates Partial Private Sub OnMyNewPropNameChanged(), but my version of the partial method still has the old name. Effectively, I now have an orphaned private method that never gets called which means my code is broken at runtime. How would you test for something like this, or even better - is there a way to specify that my version of OnMyPropChanged() is an implementation of a partial method such that the I get a compile time breakage if there isn't a corresponding partial in the generated code?

By using static anlysis (code analysis) you will get a warning/error when your code contains any internal (private, freid, internal) members that are never accessed or only ever set. this may help finding such constellations. (IIRC the concerning error code is CA1811)