Thursday, April 03, 2008

Today I set out to create a TextBox that would provide the user with a built-in prompt.  I didn't want a TextBox control that included a Label.  Instead, I wanted something akin to the password field in Windows Vista's logon screen; the field has the prompt built-into the TextBox in a faint, perhaps italic font when the control is empty.  Once the user performs an action that causes text to appear (i.e., typing, pasting, etc) the faint prompt disappears to accommodate the text.

Now there may be tons of implementations of a similar control out there; I didn't look.  Instead I wanted to 'reinvent the wheel' as it were and figure it out for myself.  Fortunately it only cost me between 5 to 10 minutes and I had something up and working.  The code I've included below is very raw and doesn't include many customizations (you're on your own there :-)

public sealed class PromptingTextBox : TextBox {
  public PromptingTextBox() {
     userPaint(true);
  }

  private Font _promptFont = new Font("Arial", 9.0F, FontStyle.Italic);
  private string _promptText = "Enter text here...";

  ///


  /// Sets or returns the text to display when the TextBox is empty.
  ///

  public string PromptText {
     get { return _promptText; }
     set { _promptText = value; }
  }

  protected override void Dispose(bool disposing) {
     if ( disposing )
        _promptFont.Dispose();
     base.Dispose(disposing);
  }

  protected override void OnTextChanged(EventArgs e) {
     base.OnTextChanged(e);
     userPaint(0 == TextLength);
  }

  private void userPaint(bool enabled) {
     if ( enabled != GetStyle(ControlStyles.UserPaint) ) {
        SetStyle(ControlStyles.UserPaint, enabled);
        Refresh();
     }

  }

  protected override void OnPaint(PaintEventArgs e) {
     Graphics g = e.Graphics;
     g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
     g.DrawString(_promptText, _promptFont, SystemBrushes.ControlLight, 0.0F, 0.0F);
  }
}

That's all there is to it - at least for a simple start. Enjoy!

Thursday, April 03, 2008 4:02:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, March 19, 2008

Customer Dynamics, a local Microsoft partner that focuses exclusively on Microsoft CRM, is hosting a special Microsoft CRM 4.0 Open House today (03/19/2008).  The event takes place at our local Microsoft offices and runs from 3:00 PM to 7:00 PM.  Customer Dynamics has invited us (Experlogix) to come share in the event.

It's my privilege, therefore, to attend the event and provide a short presentation on Experlogix's Product Configurator solution for CRM and interact with customers.  I'm very excited as I look forward to this event.  If you haven't already registered and your company uses (or is investigating the usage of) Microsoft CRM, please sign up and we'll see you there!

Microsoft Corporation
123 Wright Brothers Dr. Suite 100
Salt Lake City, UT 84116

Wednesday, March 19, 2008 2:29:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, March 17, 2008

In the world of AJAX and JavaScript, JSON (JavaScript Object Notation) is ubiquitous; that is, it's everywhere.  JSON is, in a nutshell, a terse, convenient mechanism for representing objects and their property values in a manner that the browser (via JavaScript itself) can reconstruct as an object.  I'm not going to go into the details of JSON and its intracacies here as there are plenty of other discussions on the topic online elsewhere.

I just wanted to point out that there is some first-class support for JSON serialization in the .NET framework v3.5.  I bring this up because a while back I was about to create my own attribute-based JSON serializer but I figured there had to be something already in place for it.  I'm glad I looked.

Using the [DataContractAttribute] and [DataMemberAttribute] which are usually associated with Windows Communication Foundation (WCF) you can easily serialize your objects to/from JSON form.  The object that provides this support (not coincidentally named DataContractJsonSerializer) is found after referencing the System.ServiceModel.Web assembly in the System.Runtime.Serialization.Json namespace.  When (de)serializing your objects, you do so against a stream.

Say, for purposes of the discussion, that you wanted to create an HTTP Handler that returned product information to the caller.  You could very easily serialize your product set in the following manner:

void IHttpHandler.ProcessRequest(HttpContext context) {
  HttpResponse res = context.Response;
  res.ContentType = "application/json";
  DataContractJsonSerializer jsSer = new DataContractJsonSerializer(typeof ( Product[] ));
  jsSer.WriteObject(res.OutputStream, getProducts());
}

The JavaScript client could then parse the result and do with it as it sees fit.  Pretty handy!

Monday, March 17, 2008 6:04:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, March 14, 2008

This past week I've been in Orlando, Florida attending the Microsoft Convergence 2008 conference.  This marks my fourth such conference and they keep getting better and better!  My primary responsibilities at this conference (and the MS Partner Conference for that matter) revolve around the booth that we have in the Expo hall.  Five of my team and co-workers were in attendance, manning the booth (Christian, Jeff, Gwyn, David, and myself) as well as an associate, Scott.  It was a good thing all five of us were there because we hardly had a moment to breathe what with the traffic our booth brought in.  It was awesome.

Not only was the week full of activity in the conference proper, we had the opportunity to witness the Space Shuttle Endeavour launch on Monday evening/Tuesday morning, hang out with partners and customers, and all-in-all have a great time.  We keep hearing how much our customers and partners LOVE our product; that sure makes a developer such as myself feel even better about what I do. :-)

I already look forward to the next conference.

Friday, March 14, 2008 2:39:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, March 11, 2008
Space Shuttle Endeavour

When I came to Orlando, Florida for the Microsoft Convergence 2008 Conference I didn't expect to get such a treat.  I found out yesterday, shortly after my arrival that we were going on an outing to watch the Space Shuttle launch.  Boy was I excited!  I had no idea it was going to launch in the first place, but was even more excited to be able to witness the launch in person, and at night.

I vividly recall when the Space Shuttle Columbia landed just 30 minutes from my house (a night landing) at White Sands in NM but I wasn't able to attend that event.  In fact, I have wanted to see a shuttle launch since the Columbia first went into space; it set many of my dreams into motion, few of which will ever come true - though seeing a launch in-person has just now! :-)

The event was amazing.  We were situated across the water from the launch pad (geographically, I'm not sure how far it actually was).  Right at 2:28 AM we saw the first billows of smoke rise from the launch pad, then the bright flare of the flames from the rockets.  The rocket, the size of a lit match's flame at arm's length, ascended rapidly but very silently into the night sky.  Perhaps most astounding and brilliant was the entire sky...not just the horizon where the launch took place, but the ENTIRE SKY turned a bright orange during the launch.  It appeared as though a small sun had risen.  The rocket was then engulfed in the low cloud coverage.

The rocket disappeared.  After a small delay of about 10 seconds or so we began to hear and actually feel the trembling and roar of the rocket boosters.  This got increasingly louder and more rumbling before waning.

Poetry in motion.

Tuesday, March 11, 2008 2:06:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Friday, February 22, 2008

I've been putting together a small WCF service that allows a client to upload a file to a server for processing.  While the details of that are for another discussion, I want to focus on what should have been a simple operation but turned out to take up most of my afternoon and some of my evening: the generation of a client proxy class and configuration file.

By way of background, this particular WCF service is hosted by a simple Windows Service, runs (by default) under the Network Service account, and exposes a TCP end point for communication.  I have a setup project that takes care of the installation and registration of the Windows Service and auto-runs it when installation is complete.  This has been running great.

However, anytime I attempted to generate a proxy class for my service via the following command line, I would get some nasy error indicating that it “Cannot obtain Metadata from net.tcp://localhost:9999/myservice”.

svcutil net.tcp://localhost:9999/myservice/mex

My configuration file was as follows:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <system.serviceModel>
      <behaviors>
         <serviceBehaviors>
            <behavior name="mex">
               <serviceMetadata />
            </behavior>
         </serviceBehaviors>
      </behaviors>
      <services>
         <service name="MyService.ExampleSvc" behaviorConfiguration="mex">
            <host>
               <baseAddresses>
                  <add baseAddress="net.tcp://localhost:9999/myservice" />
               </baseAddresses>
            </host>
           
            <!-- default endpoint -->
            <endpoint
               binding="netTcpBinding"
               contract="MyService.IExampleSvc" />
           
            <!-- metadata exchange (MEX) endpoint -->
            <endpoint
               address="mex"
               binding="mexTcpBinding"
               name="MEX"
               contract="IMetadataExchange" />
         </service>
      </services>
   </system.serviceModel>
</configuration>

However, as I mentioned, everytime I attempted to retrieve the metadata via the /mex endpoint it failed.  Right off the bat I suspected that the error had to do with the types used in the [ServiceContract] class, but I brushed that idea aside thinking that for sure it was something in the configuration file.  So I kept on battling with it.

To that end, I created a very simple WCF service (in the same application) this time with an HTTP endpoint.  I had to change the Windows Service credentials to a user with elevated permissions to register the HTTP channel (Network Service won't cut it) because I didn't want to manually mess with my HTTP security settings.  Anyway, this was just a test.  To my chagrin, it worked first try; I was able to retrieve the metadata.

So I returned to the TCP service.

Fortunately (and I'm no WCF whiz...yet :), I found a helpful behavior that I could add to the .config file that saved the day for me.  By simply adding the <serviceDebug /> element with the includeExceptionDetailInFaults attribute to the mex behavior element I was able to get some diagnostics.

<serviceBehaviors>
    <behavior name="mex">
       <serviceDebug includeExceptionDetailInFaults="true" />
       <serviceMetadata />
    </behavior>
</serviceBehaviors>

Now, in the big, fat, honkin' exception stack that was output I saw immediately that one of the embedded types used in my [ServiceContract] implementation had a nested type that was not serializable.  Once I added [Serializable()] to the offending types (there were a few of them) and recompiled it worked like a champ!  So it turns out that my initial suspiscion was correct...I need to listen to my intuition more often!

Friday, February 22, 2008 1:19:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, February 20, 2008

I ran into a peculiar behavior that Visual Studio 2008 was exhibiting today that I suspect is a bug.  If it's not a bug, then there must be a setting somewhere of which I'm not aware.

I have a couple of projects that I've developed initially in VS2003 (targeting the .NET 1.1 framework), maintained in VS2005 (targeting the .NET 2.0 framework), and recently upgraded to VS2008 (targeting the .NET 3.x framework).  These projects, rather than embedding image resources natively (that is, embedding the .png, .gif, and .jpg files as independent resources) I have some .resources files that contain string and image data.  Up to this point they've worked great.

However, I discovered today that once upgraded to VS2008 the resources were not loading.  My code for loading the resources is pretty simple:

ResourceManager mgr = new ResourceManager("MyApp.Res", Assembly.GetExecutingAssembly());
ResourceSet res = mgr.GetResourceSet(CultureInfo.InvariantCulture, true, false);

Note that my embedded resource file is named 'Res.resources', so the namespace for the ResourceManager is my application namespace followed by 'Res' because it's in the root of the application.

Now, with VS2008, the mgr.GetResourceSet() call was returning a NULL value.  Somehow my resources were not resolving! After digging a bit, I found that the '.resources' extension was being truncated off of my resource file during the embedding process so though it was present in the .exe, it's name didn't have the '.resources' extension appended!

My solution was to rename the file 'Res.resources.resources' and it worked.  Interestingly, the compiler doesn't exhibit this same behavior for the .resources files that it creates.  Has anyone else run into this or is there a setting for it?  Fortunately, I only lost about 15 minutes from discovering the issue to having it fixed, but it really feels like a hack more than a fix.

Wednesday, February 20, 2008 3:50:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Tuesday, February 12, 2008

It is once again time for our very own Utah .NET User Group monthly meeting! In fact, in lieu of this Thursday being Valentine's Day, we've bumped the meeting date up to Tuesday (TODAY - 02/12/2008), same time, same place. We realize this is short notice (shame on us). We posted the meeting on the calendar several days ago, but failed to send out the email reminder until now for which we apologize.

This month, grab your canoes, oars, and life preservers and get ready to talk about STREAMS. Streams, though fundamental and routinely used, come in many different flavors. We'll be exploring streams from the ground up; from the ever-so-commonly utilized MemoryStream and FileStream types to the not-so-frequently used CryptoStream. Hey, we may even venture into the realm of the NetworkStream, the NamedPipeServerStream and NamedPipeClientStream. Time permitting, we will delve into the very cool compression streams (such as DEFLATE and GZIP).

Time: 6:00 PM
Date: Tuesday, February 12, 2008
Place: Digital Draw Network (10897 South River Front Parkway, South Jordan) Suite 300

This month's meeting is generously sponsored by TEKsystems.

Come out and enjoy the food, the friendship, and the fun!

Tuesday, February 12, 2008 3:00:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback