Tuesday, December 21, 2010

How to Get Values From Form1 to Form2 (or any other forms, for that matter).

This question is asked practically every day on C# Forums: "how do I get a value from Form1 to Form2?" or the other way around. There is a shocking amount of bad advice out there on the internet about how to go about doing this. This tutorial is intended to show you more "correct" ways of passing data between forms.

The scope of this tutorial is limited to passing data between forms. We will look at both properties and custom events, but in a brief overview.

Friday, November 26, 2010

Silverlight RPN Calculator Tutorial.

Well I beat my old nemesis and finished an RPN calculator. It was much easier than I remember, but then again, I tried it like four years ago. I've learned so much in the time since, I can hardly believe how silly my old code is.

Have any of you ever used a Reverse Polish Notation calculator? I did in high school. It was easily the best calculator ever (the HP=32SII). RPN is great, because you don't have to use parenthesis. The stack and the order in which you key the operators maintains order of operations.

Today, I'll walk you through creating one. Note this tutorial is technically for Silverlight, but except for the marked sections, it can be applied wholesale to WinForms or WPF. Most if this is simple stack logic, and that exists on all .NET platforms.

Read more after the jump.

Tuesday, November 23, 2010

Postfix expression parser.

A question on DreamInCode lead me to my old nemesis, the Postfix expression parser. I'd fallen in love with a Reverse Polish Notation calculator in high school (the HP-32SII, they sadly don't make them anymore). When I tried to program a RPNC to use on my PC years ago, I failed miserably. But I've learned a lot since then, and I figured I could at least try a simple postfix parser.

It wasn't that bad. You don't have to check for a lot of things a calculator does. Here's the body of the code. I made it static, since you really don't need to instantiate it. If I ever make it into a calculator, I'd probably make it non-static, and make the stack a class-level field.

class PostfixParser
{
    const string Placeholder = "[x]";

    private static Dictionary<string, Func<double, double, double>> op;

    private static List<string> operators = new List<string>() { "+", "-", "*", "/" };

    static PostfixParser()
    {
        op = new Dictionary<string, Func<double, double, double>>();
        op.Add("+", (x, y) => x + y);
        op.Add("-", (x, y) => x - y);
        op.Add("*", (x, y) => x * y);
        op.Add("/", (x, y) => x / y);
        op.Add("^", (x, y) => Math.Pow(x, y));
    }

    public static double ParseExp(string exp, double? val)
    {
        string[] tokens = exp.Split(new string[] { " " } , StringSplitOptions.RemoveEmptyEntries);
        if (tokens.Contains(Placeholder) && val == null)
            throw new InvalidOperationException("Placeholder token detected in expression, but parameter \"val\" was null.");
        Stack<double> stack = new Stack<double>();
        foreach (string token in tokens)
        {
            if (operators.Contains(token))
            {
                if (stack.Count < 2)
                    throw new InvalidOperationException("Operator imbalance.");
                double y = stack.Pop();
                double x = stack.Pop();
                stack.Push(op[token](x, y));
            }
            else
            {
                double n;
                if (token == Placeholder)
                    n = val.Value;
                else if (!double.TryParse(token, out n))
                    throw new InvalidOperationException("Invalid token detected: " + token);
                stack.Push(n);
            }
        }

        if (stack.Count > 1)
            throw new InvalidOperationException("More than one result on the stack.");
        if (stack.Count < 1)
            throw new InvalidOperationException("No results on the stack.");
        return stack.Pop();
    }

    public static double ParseExp(string exp)
    {
        return ParseExp(exp, null);
    }
}

This can be used like this:
string fToCExp = "5 9 / [x] 32 - *";
string cToFExp = "9 5 / [x] * 32 + ";
Console.WriteLine("100C converted to F:");
Console.WriteLine(PostfixParser.ParseExp(cToFExp, 100));
Console.WriteLine("32F converted to C:");
Console.WriteLine(PostfixParser.ParseExp(fToCExp, 32));
Console.ReadKey();

To give an output of:

100C converted to F:
212
32F converted to C:
0

You could add more operators if you wished, like a 1/x or a SQRT, but since most other operators are unary rather than binary, you'd have to change your popping logic.

Note: I did it with a placeholder value in mind. I used "[x]" for whatever reason, but it could be anything that won't parse into a double by itself or match one of the operators. You could remove this altogether, if you cared to.

Tuesday, October 26, 2010

More extension methods: To and In. Also, a static class to make Sequences.

It's been quite a while since I posted. I've been quite busy with work. But without further ado, here's a static class I've been working on (code after the break):

Wednesday, September 1, 2010

Silverlight: Performing Multiple Asynchronous Calls

If you've spent any time with Silverlight, you've probably used it with a Web Service (ASMX or WCF, either one). And the first thing that jumps out at you is the fact that Silverlight does not and in fact cannot generate synchronous methods to call the web methods. In stead of a method called GetData that returns a value, you have a GetDataAsync method and a GetDataCompleted handler, to which the return value will be in the EventArg parameter.

This is not a bad thing. I don't particularly want a plugin blocking the browser's UI thread with a long-running synchronous call. In fact, I've read (somewhere, can't find the reference) that this is the reason that MS didn't allow Silverlight to do synchronous calls.

However, there are times when you need to do multiple calls, and then have something happen when they are all done. You can't trust that calls will finish in the order that you start them in, because these calls can run simultaneously. There are a few options to do this. I'll show you two examples. Article continues after the jump.

Monday, August 30, 2010

Trimming/rounding a date time. Floors and ceilings.

Well, first, credit where credit is due. I found this on StackOverflow and only slightly modified it. But it's too good not to share.

This code will let you "round" a date time to any given interval. You can get the floor or ceiling, or do a traditional round.

Here's the code:

public static class Extensions
{
    public static DateTime Floor(this DateTime date, TimeSpan span)
    {
        if (span == TimeSpan.FromMinutes(0))
            return date;
        long ticks = date.Ticks / span.Ticks;
        return new DateTime(ticks * span.Ticks);
    }

    public static DateTime Ceil(this DateTime date, TimeSpan span)
    {
        if (span == TimeSpan.FromMinutes(0))
            return date;
        long ticks = (date.Ticks + span.Ticks - 1) / span.Ticks;
        return new DateTime(ticks * span.Ticks);
    }

    public static DateTime Round(this DateTime date, TimeSpan span)
    {
        if (span == TimeSpan.FromMinutes(0))
            return date;
        long ticks = (date.Ticks + (span.Ticks / 2)) / span.Ticks;
        return new DateTime(ticks * span.Ticks);
    }
}


Here's a simple example using Floor:
DateTime dt = new DateTime(2010, 8, 29, 15, 26, 23);
Console.WriteLine("Floor:");
Console.WriteLine(dt.Floor(TimeSpan.FromSeconds(0)));
Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(1)));
Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(5)));
Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(10)));
Console.WriteLine(dt.Floor(TimeSpan.FromMinutes(60)));
Console.WriteLine();

Console.WriteLine("Ceil:");
Console.WriteLine(dt.Ceil(TimeSpan.FromSeconds(0)));
Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(1)));
Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(5)));
Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(10)));
Console.WriteLine(dt.Ceil(TimeSpan.FromMinutes(60)));
Console.WriteLine();

Console.WriteLine("Round:");
Console.WriteLine(dt.Round(TimeSpan.FromSeconds(0)));
Console.WriteLine(dt.Round(TimeSpan.FromMinutes(1)));
Console.WriteLine(dt.Round(TimeSpan.FromMinutes(5)));
Console.WriteLine(dt.Round(TimeSpan.FromMinutes(10)));
Console.WriteLine(dt.Round(TimeSpan.FromMinutes(60)));
Console.ReadKey();

And here's the output:

Floor:
8/29/2010 3:26:23 PM
8/29/2010 3:26:00 PM
8/29/2010 3:25:00 PM
8/29/2010 3:20:00 PM
8/29/2010 3:00:00 PM

Ceil:
8/29/2010 3:26:23 PM
8/29/2010 3:27:00 PM
8/29/2010 3:30:00 PM
8/29/2010 3:30:00 PM
8/29/2010 4:00:00 PM

Round:
8/29/2010 3:26:23 PM
8/29/2010 3:26:00 PM
8/29/2010 3:25:00 PM
8/29/2010 3:30:00 PM
8/29/2010 3:00:00 PM

Tuesday, August 24, 2010

Finding the calling method.

I've been tasked with writing a logging component of a current application we're working on. My co-worker provided me with a snippet of code that has proven to be quite useful:

using System.Diagnostics;
using System.Reflection;
.
.
.
//dig through the stack trace to find the calling method
StackTrace stackTrace = new StackTrace();
//since this is two methods removed from the caller, go two deep
StackFrame stackFrame = stackTrace.GetFrame(2); 
MethodBase methodBase = stackFrame.GetMethod();
string caller = methodBase.ReflectedType + "." + methodBase.Name;

I'm getting the third frame, because the method is two deep in the logger code, but you can use whatever number necessary to get the right frame. This gives you the whole Fully.Qualified.Namespace.Class.MethodName, which can be quite useful.