SpriteHand
Module Border
  Andy's Blog
Module Border
Author: host Created: 3/6/2006 9:55 PM
Adventures in .NET

Book Review: Foundations of WF
By Andy Beaulieu on 11/8/2006 7:56 AM

Looking for a good intro to Windows Workflow Foundation?

For most people, the best way to learn is by example. And that seems to be the creed behind "Foundations of WF" by Brian Myers. This book is short on theory and long on example as it takes the reader through scads of Windows Workflow Foundation activities.

It's a skinny book at just 224 pages plus index but no paper is wasted as the author fires up his first solution walk-thru on page 4. From there on, it's all code as the author builds on previous chapters to show how to use many WF activities.

Chapter 10 pulls together the previous sections with a final real world example: an Employee Performance Review application implemented in ASP.NET and SQL Server.

If you're looking for lots of WF theory and concepts, look elsewhere. But "Foundations of WF" by Brian Myers has much to offer to the kinesthetic learner.

Comments (0)

Submit using Enter on multiple controls
By Andy Beaulieu on 10/9/2006 6:48 PM

ASP.NET 2.0 adds the DefaultButton property, which allows you to specify which button causes a postback when the Enter key is pressed.

But what if you have multiple controls on the page that could potentially cause a postback? For example, maybe you have multiple search textboxes on your page - any of which the user should be able to press Enter on and cause a postback?

In the example below we will assume there is a textbox named "txtFind" and when the user hits <enter> on txtFind, we want to execute a Postback on btnFind.

First we add a client-side handler to the control that should cause the postback when enter is hit. You also pass in the ClientId of the element you want to cause the postback:

txtFind.Attributes.Add("onkeydown", "return OnKeyDown(event, '" + btnFind.ClientID + "');");

Then we need to add some script to handle that event in both IE and Mozilla -

    function OnKeyDown(e, submitButton)

    {

        var nKey = -1;

        var sourceElement;

 

        if (e && e.which)

            nKey = e.which;    // NS

        else

            if (window.event && window.event.keyCode)

                nKey = window.event.keyCode;  // IE

       

        if (nKey == 13)

        {

             document.getElementById(submitButton).click();

             return false;

        }

 

        return true;

    }

 

Comments (0)

Notes for ASP.NET Class
By Andy Beaulieu on 9/13/2006 1:25 AM

Here are some various notes for the ASP.NET class that I am teaching this week (more to come):

A Visual Studio Add-In That Converts C# Code To Visual Basic
VB.NET Naming Conventions
CSS Friendly ASP.NET 2.0 Control Adapters (Beta 2.0)

Enterprise Library
(for .NET 2.0)
Exception Handling Block
Logging Application Block
(for .NET 1.1)

Upcoming Local Events
Next Code Camp in Waltham
Next MSDN Event in Syracuse

ASP.NET Performance Tips
Keep Sites Running Smoothly By Avoiding These 10 Common ASP.NET Pitfalls
10 Tips for Writing High-Performance Web Applications

A "Complete" Data Grid Example for ASP.NET 1.1
       
Zip Download

AJAX/Atlas
     
Scriptaculous
      Fiddler Tool

Data Access Layer
     
ActionPack
      ActionPack Video Intro

Simple Printing from the browser
(Method 1) Add some Javascript to an HTML button

(Method 2) Add some Javascript to a Button from the server side:
Button2.Attributes.Add("onclick", "window.print(); return false;")

Note that Method 2 can also be used for other things like a Confirm dialog for a postback

Button1.Attributes.Add("onclick", "return confirm('Are you sure?')")

Dynamically Enabling Page Caching, Based on DEBUG Mode
Because of the headaches that page caching can cause when you are in development mode, you may want to dynamically enable or disable page caching based on something like a compiler constant:

#If DEBUG Then
   
lblStatus.Text = "*NOT* using output caching (debug mode)"
#Else
   
Response.Cache.SetExpires(Date.Now.AddMinutes(20))
   
lblStatus.Text = "using output caching (Production mode)"
#End If


 

Comments (0)

"Atlas" gets a Name
By Andy Beaulieu on 9/12/2006 6:49 AM

... from a post by Scott Guthrie where he also estimates the v1.0 release "around the end of this year."

1) The client-side “Atlas” javascript library is going to be called the Microsoft AJAX Library. This will work with any browser, and also support any backend web server (read these blog posts to see how to run it on PHP and ColdFusion).

2) The server-side “Atlas” functionality that nicely integrates with ASP.NET will be called the ASP.NET 2.0 AJAX Extensions. As part of this change the tag prefix for the “Atlas” controls will change from <atlas:>to <asp:>. These controls will also be built-in to ASP.NET vNext.

3) The “Atlas” Control Toolkit today is a set of free, shared source controls and components that help you get the most value from the ASP.NET AJAX Extensions. Going forward, the name of the project will change to be the ASP.NET AJAX Control Toolkit.

Comments (0)

ReportViewer Control - Customization at Runtime
By Andy Beaulieu on 8/30/2006 7:14 AM

Let's say you just created a really cool Report for the .NET 2.0 ReportViewer Control (well, as cool as a report can be anyway).

But wait... At runtime, you want to examine and maybe even change attributes of the report. Like column names, labels, etc.

How do we get at Report properties at runtime?

One way is to tweak the RDLC (Client Report Definition) file before it is fed to the ReportViewer Control. RDLC is based on XML, so we can use XPath queries to find and tweak RDLC properties.

There is a post here that describes this method, and another example below.

First we create a utility function to load in the RDLC and tweak or examine it as necessary...

private TextReader GetCustomRDLC(string rdlcSource)

{

    TextReader readerReport;

    XmlDocument xmlReport = new XmlDocument();

    Stream streamReport;

 

    streamReport = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(rdlcSource);

 

    xmlReport.Load(streamReport);

 

    XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlReport.NameTable);

    nsManager.AddNamespace("dns", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");

 

    XmlNodeList nodes = xmlReport.SelectNodes("//dns:Table[@Name='table1']//dns:Details//dns:Textbox", nsManager);

 

    foreach (XmlNode node in nodes)

    {

        System.Diagnostics.Debug.WriteLine(node.Attributes["Name"].Value);

    }

 

    return new StringReader(xmlReport.OuterXml);

 

}

... then we can use this function to feed the ReportViewer Control...

 

 

// create a datasource for the report and set to the datatable dt1

ReportDataSource rds = new ReportDataSource();

rds.Name = "DataSet2_Employees";

dt1.DefaultView.Sort = "FirstName";

rds.Value = dt1.DefaultView;

 

 

 

reportViewer1.LocalReport.DataSources.Clear();

reportViewer1.LocalReport.DataSources.Add(rds);

 

reportViewer1.LocalReport.LoadReportDefinition(GetCustomRDLC("ReportViewerTest.Report2.rdlc"));

 

reportViewer1.RefreshReport();

Comments (0)

Marshaling a Byte Array to COM object
By Andy Beaulieu on 8/25/2006 7:05 AM

I have been helping someone port a Delphi app to WindowsForms and we ran into something interesting. The Delphi app uses a 3rd-party ActiveX control to display spreadsheets. Unforunately, the ActiveX control has not been ported to .NET, and the Delphi app stores the spreadsheet control data as a proprietary format BLOB in the database.

The ActiveX control had documentation for the method we needed to call:

Syntax
ReadFromBlob hBlob, nReservedBytes

Part           Type       Description
hBlob          OLE_HANDLE Reference to a BLOB variable in memory.
nReservedBytes Integer    Size of the BLOB variable. Not implemented in this version and must be 0.

So, after adding the ActiveX control to WindowsForms, how to feed it these bytes? We need to create an unmanaged buffer to hold the data and get that to the method. We can use AllocCoTaskMem of the Marshal class to allocate the unmanaged buffer and then marshal it to the ActiveX control...

// assume we have a byte array inside byteData read from DB.
int
size = byteData.Length;
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(size) * size);
Marshal.Copy(byteData, 0, buffer, size);
int ptr = buffer.ToInt32();

// now we can feed the control 
myControl.ReadFromBlob(ptr, 0);

Marshal.FreeCoTaskMem(buffer);

Comments (3)

Where is my Profile object?
By Andy Beaulieu on 8/1/2006 8:15 AM

Profiles are supposed to be easy in ASP.NET 2.0. You just add a section in your web.config like so:

      <profile defaultProvider="CustomizedProfileProvider">

        <providers>

              <add name="CustomizedProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="MyConnectionString" applicationName="/MyApplicationName" />

        providers>

        <properties>

              <add name="MySetting" type="int16" defaultValue="10" />

        properties>

      profile>

... after which ASP.NET 2.0 generates a nice strongly typed class for you so you can access your settings like so:

short x = Profile.MySetting;

Unfortunately, the strongly typed class is generated into your App_code folder. And if you have happened to use the VS2005 Web Application Projects Add-in, you won't have an App_code folder, which means you won't have access to the Profile strongly typed object.

There are two ways around this problem that I know of:

(1) there is another add-in called the WebProfile Generator just for these circumstances.

(2) if you can live with "loosely typed" Profile access, you can just code against a ProfileBase instance like so:

 

ProfileBase profile = ProfileBase.Create(Membership.GetUser().UserName);

 

short newSetting = 42;

profile.SetPropertyValue("MySetting", newSetting );

profile.Save();

 

Comments (0)

ApplicationException is old school?!
By Andy Beaulieu on 7/27/2006 6:24 PM

This is an odd change on a Microsoft "best practice..." For .NET Framework v1.x, it was recommended that you always inherit from ApplicationException when creating custom exception classes for your application.

But for Framework 2.x, they have revoked this recommendation, as you can see here...

For most applications, derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.

I'm not sure why they made this distinction? ApplicationException is inherited from Exception anyway, and I can't imagine there is significant performance issues there? Anyone? Bueller?

Comments (1)

Some miscellaneous stuff
By Andy Beaulieu on 7/6/2006 5:41 PM

web.config Encryption
"Can't I encrypt portions of my web.config so people can't just pop that file open and find my db passwords and other sensitive stuff?" ASP.NET 2.0 has expanded support for config section encryption, and this article gives a good overview of using aspnet_regiis to do just that.

 

Drawing Primitives using JavaScript
After all the iterations of the web browser, isn't it funny how we still can't do things like draw simple shapes?! Don't worry, there is always a kluge. Until Vector Markup Language is supported in more browsers, we can use this LGPL javascript library to draw simple shapes.

Comments (0)

Notes for VB.NET Class
By Andy Beaulieu on 6/14/2006 12:44 PM

Here are a couple of notes for the VB.NET class I instructed at this week...

(1) Creating a global exception handler for WindowsForms (.NET 1.1):  This is a multistep process (note that in .NET 2.0 they give you a global exception handler in Project properties which is nicer). Create a Sub Main module that creates your main form and adds a handler for the Application.ThreadException. In Project Properties, change your startup object to Sub Main. (code below)

 

Module SubMain

    Public Sub main()

        Try
           
AddHandler Application.ThreadException, AddressOf HandleExceptionEvent

            Dim frmMain As New Form1
            Application.Run(frmMain)

        Catch ex As Exception
            HandleException(ex)

        End Try

    End Sub

    Private Sub HandleExceptionEvent(ByVal sender As Object, ByVal e As System.Threading.ThreadExceptionEventArgs)

        HandleException(e.Exception)

    End Sub

    Private Sub HandleException(ByVal ex As Exception)

        MsgBox("Sorry, an error has occurred:" & ex.Message)

    End Sub

End Module

 

(2) Creating a TextBox class that handles Enter as Tab key:  some users prefer hitting ENTER on each WindowsForms field to "tab" to the next field. We can do this by creating an inhertied textbox and handling its KeyPress event. First create a new Class and then implement as follows

Public Class TextBoxEnterTab
    Inherits TextBox

    Private Sub TextBoxEnterTab_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress

        If e.KeyChar = Chr(13) Then

            SendKeys.Send("{TAB}")
            e.Handled = True

        End If

    End Sub

End Class

(3) Code Generation Tools: Check out MyGeneration dOOdads and CodeSmith

(4) Miscellaneous tools and utilities for development
VBCommenter - generates comment blocks for VB.NET  http://www.gotdotnet.com/team/ide/

NDoc - generates documentation automatically form XML comments  http://ndoc.sourceforge.net

NET Reflector - used to disassemble assemblies  http://www.aisto.com/roeder/dotnet/

REGEXLIB - an online Regular Expression library to use with the Regular Expression Validator controls http://www.regexlib.com

Enterprise Library - Microsoft's Application Blocks for handling common development tasks http://www.microsoft.com/downloads/details.aspx?familyid=5A14E870-406B-4F2A-B723-97BA84AE80B5&displaylang=en
   http://msdn.microsoft.com/library/?url=/library/en-us/dnpag2/html/EntLib2.asp

Atlas   http://atlas.asp.net - Microsoft's AJAX library, including Behaviors

Comments (0)

Module Border Module Border
Module Border
  Subscribe
Module Border
RSS   Twitter
Module Border Module Border
Module Border
  Diversions
Module Border

TALKING RAGDOLL
This Windows Phone 7 App was created using Silverlight, the  Physics Helper Library,  and the Farseer Physics Engine. It gets interesting when you import your friends photos and have your way with them!

MORE INFO



DROPPYPOP
This Windows Phone 7 game was created using Silverlight, the  Physics Helper Library,  and the Farseer Physics Engine.
DEMO

MORE INFO



BOSS LAUNCH
This physics game won first place in the Server Quest Contest. Created using Silverlight 2, the Physics Helper Library,  and the Farseer Physics Engine.
PLAY IT

MORE INFO



DESTROY ALL INVADERS
A scrolling shooter game where the objective is to destroy the invading UFO's flying over a neighborhood of your choosing. Imagery provided by Microsoft Virtual Earth. Created using Silverlight 2.
PLAY IT

INFO AND CODE



PHYSICS HELPER DEMOS
These demos were created for the Physics Helper Library, which makes it easy to create physics games and simulations using Expression Blend, Silverlight, and the Farseer Physics Engine.
PLAY IT

INFO AND CODE



HOOK SHOT
This little basketball game took first place in the TeamZoneSports Silverlight Contest. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



SORT THE FOOBARS
A game where you need to sort the good foobars from the bad ones. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



POLYGON PHYSICS DEMO
A demo showing polygon physics where the user draws physics objects with the mouse. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



SILVERLIGHT ROCKS!
Destroy the asteroids before they destroy your ship! Created using Silverlight 2.
PLAY IT

INFO AND CODE



FISH GAME
A simple game of harpoon-the-fish. Written using the AJAX Sprite Toolkit.
PLAY IT

INFO AND CODE

Module Border Module Border
Module Border
  Search_Blog
Module Border
Module Border Module Border
Module Border
  Blog_Archive
Module Border
Module Border Module Border
Copyright (c) 2014 andy.beaulieu.com - Login