Welcome to MSDN Blogs Sign in | Join | Help

Teched South East Asia

Well Teched EMEA was a success after a few close calls.  The scores were much the same as last year despite losing a few of our regular 'stars' like Kim Tripp to the Connections event in Las Vegas at the same time.

Now I am gearing up for TechEd South East Asia.  Its August 11-14 at the Kuala Lumpur Convention Centre (KLCC).  Mark your calendars and speakers, start thinking.

Please add comments on the types of subjects you would like us to cover this year and any other suggestions on how we run the event.

See you in KL!

WPF and MVC - recognizing Ink with an InkCanvas

I am in the middle of preparing an internal presentation on WPF/Blend and VS and figuring out what developers need to know about the tools.

One thing is clear, developers need good business examples showing the benefits of using WPF and blend so they can take them to their boss and get support for a new development approach.  It seems that if we have a rotating cube with video on the faces this does not always get traction with your development managers.  Go figure!

So what are the things we need to know as developers about building apps like this?  Probably the first thing to get a handle on is overall architecture.  A good framework to work in is the old Model View Controller pattern.  This is old - dating back to Smalltalk 80 but it is even more relevant today than before especially with WPF.

The basic premise is that a piece of code is in one and only one of three functional categories.

Model – this handles the data model for the presentation tier of the app.  It deals with business domain entities like Patient, Customer and so on.  Note that this is not the data layer on a multi tier application.  To talk to data we need to go through the Model to access business rules and finally data access – but the model is the representation of data that we need at the surface.

 

View – these are the view elements that we put on the page – more later.

 

Controller –There is low level Controller code and higher level stuff. In the old days we had to wire up the event handling chain ourselves so that when you click here some piece of code is executed there. Now much of this low level routing is handled by the OS – ultimately by some WinProc in Win32/Win64 code.  Higher level stuff we still do by hand, for example in winforms code when we add an event handler to a button click we are writing Controller code. 

 

We have had frameworks in the past for developers to hook into this MVC pattern.  Well we had one framework in MFC which used an MVC variant called Document/View.  In this framework you still occasionally called Controller code for example calling UpdataAllViews on the Document object is effectively giving the framework a kick to ‘Control’ the view elements.

In Winforms however we don’t have any default MVC or any other architecture pattern out of the box.  Take this piece of code:

Public void OnClick( object sender, ....)

This.textbox1.text=Patient.Name;

...

 

Our Winforms code is littered with this stuff.  What we have here is model code (Patient.Name) view code (Textbox1.) and controller code because we are pushing data around the view elements.  Of course things get a little better with CAB and software factories – but out of the box the architecture is pretty dreadful.

 

Now look at WPF.  What you create in markup is mostly View Code, with some Controller code when you assign an event handler.  The View code is interesting because it has an imperative code behind that you write in C#/VB.Net.  When you write CLR classes to add to the datacontext you are working in Model code.  Same thing when using converters – mostly model code and certainly no controller code.  So out of the box we have a pretty clean separation of along MVC lines.  Until that is we start getting sloppy.

Like your old woodwork teacher said ‘Let the saw do the work’ you need to let the framework do its job, especially handling controller code.  So  imagine that you want to capture some ink in a canvas, recognize the text and push it into a textbox.  How would you do it?

 

From your winforms days you would probably set up a handler for the LostFocus event and write some code and then push the result into the listbox.  A basic soup of model view and controller code, highly brittle and difficult to reuse.  (If you can have brittle soup).

Try this instead:

1.       Create a converter that take a strokes collection and converts it to text.

2.       Bind the textbox.text property to the strokes collection of the InkCanvas via a the converter.

3.       Feel really good about yourself

You use the InkAnalyzer object that you can get from the Tabletpc SDK. Also add a using statement for System.Windows.Ink;

class StrokesToTextConverter : IValueConverter

    {public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

              InkAnalyzer analyzer = new InkAnalyzer();

            StrokeCollection strokes = (StrokeCollection)value;    

            if (null == strokes) return "";

            if (strokes.Count == 0) return "";

            analyzer.AddStrokes(strokes);

// Perform synchronous analysis

 AnalysisStatus status = analyzer.Analyze();

string message = "";

   if (status.Successful == true)

            {

                message = analyzer.GetRecognizedString(); }

            else

            { message = "Analyze failed"      }

            analyzer.Dispose(); // Required to free unmanaged resources

            return message;

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            return null;

      }

    }

            string message = "";

            if (status.Successful == true)

            {

           message = analyzer.GetRecognizedString();

             }

             else

            {

            message = "Analyze failed";    }

            analyzer.Dispose(); // Required to free unmanaged resources

            return message;

        }

         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            return null;

        }

    }

 

 

A simple Org chart app

A couple of years ago at Teched South Africa I presented a session originally done by the great Jeff Prosise around the provider model in ASP.Net.  I remember suggesting that this was not only a neat way to handle membership, roles and whatever in ASP.Net but was a great architectural pattern that you should use when you can.

Well a couple of weeks ago Hans came up with the idea of our team building an application and demoing it to our extended team when we meet later this year.  The app is to be an Org chart browser.  Carrie will be in charge of the cool graphics WPF/Silverlight, and I will handle the heavy metal of the program.  Of course I have chosen a provider model to access org charts and present them in a canonical form to the developer/Blend designer.

So to recap, the membership provider model works like this – you program against static members of the Membership class to get instances of MembershipUser classes.  These latter classes represent the individual users and their accounts.  A typical call would be:

MemberhshipUser user = Membership.GetUserByEmail(“fred.witkins@mycompany.com”);

The plumbing beneath all of this is using a MembershipProvider class that is specified in a config file.  The Membership static methods are loading this dll and making calls into it to get and modify instances of the MembershipUser class. 

So there are three main classes that make this work, Membership, MembershipUser and for those writing providers a subclass of MembershipProvider.

 

Lets do this with the Org chart:  I will use OrgChart, OrgPerson and OrgChartProvider classes.

 

The key class is the OrgChart that will have static methods that return OrgPerson objects.  Thus:

OrgPerson person = OrgChart.GetPersonByEmail(“fred.witkins@mycompany.com”);

An OrgPerson is analgous to a User in the Membership case but this time there is the added wrinkle that OrgPersons are related to one another in ways that Users are not – we all have managers (except for one of us) and some of us are privileged to  have direct reports.  So what is the most simple way to navigate the tree of OrgPersons?  Well here is my first stab at a canonical schema for OrgPerson

public class OrgPerson

    {

 

 

        private OrgChartProvider _provider;

        /// <summary>

        /// bit to state if this OrgChartPerson has been accessed.  Use for lazy evaluation of org trees

        /// </summary>

        private Boolean _hasBeenTraversed;

 

        private string _firstName;

 

        /// <summary>

        /// Properties use accessors to appear in Blend and other databinding tools

        /// </summary>

        ///

        private string _salutation;// mr mrs etc

 

        public string Salutation

        {

            get { return _salutation; }

            set { _salutation = value; }

        }

        private string _title;

 

        public string Title

        {

            get { return _title; }

            set { _title = value; }

        }

 

 

 

        public string FirstName

        {

            get { return _firstName; }

            set { _firstName = value; }

        }

        private string _lastName;

 

        public string LastName

        {

            get { return _lastName; }

            set { _lastName = value; }

        }

....

 

 

You get the idea.  I also add a property that accesses the direct reports of the person but here is the rub, I want to be able to have the OrgChartProvider writer optimize the traversal of the tree but to keep it intuitive and simple to the app programmer.  Of course its up to the provider writer to choose to do this or not but I decided to add a little hook to help him do that:

private List<OrgPerson> _directReports;

 

        public List<OrgPerson> DirectReports

        {

            get

            {

                if (!_directsTraversed && _provider != null)

                {

 

                    this._directReports = _provider.FindDirectReports(this);

                    _directsTraversed = true;

                    return _directReports;

                }

            }

            set { }

        }

I keep a Boolean _directsTraversed so that the OrgChartPerson can call into the provider to get more chunks of data when it is needed.  I will later use a config section to specify private settings for the provider so that it can restrict an entire tree traversal for a simple query. This Boolean value will be set by the provider and can default to true if the entire tree is evaluated in one go.

We can handle the traversal the other way in the same manner to find a person’s manager.

private List<OrgPerson> _manager;

 

        public List<OrgPerson> Manager

        {

            get

            {

                if (!_mangerTraversed && _provider != null)

                {

 

                    this._manager = _provider.FindManager(this);

                    _mangerTraversed = true;

                }

return _directReports; // can be null if there are no directs

 

            }

            set {}

        }

 

 

This is a classic pattern to give a lazy evaluation of the manager object. In fact it is the _provider member that is doing the hard work but the programmer just sees the OrgPerson as a simple object.  So it looks like we have a two way navigation built into the tree but the magic is done by the OrgChartProvider class.  So lets look next at how that class might work.

I will again borrow the same pattern as the provider model in ASP.Net.   I will have an abstract base class:

public class OrgChartProvider

    {

 

...

        public abstract List<OrgPerson> FindDirectReports(

        string managerNameToMatchRegex,

 

        out   FindPersonStatus status);

 

 

        public enum FindPersonStatus { success, invalidName, ambiguousExpression, notImplemented };

 

       

        public abstract List<OrgPerson> FindDirectReports(

    OrgPerson manager,

 

    out   FindPersonStatus status);

 

 

        public enum FindPersonStatus { success, invalidName, ambiguousExpression, notImplemented };

 

        public abstract List<OrgPerson> FindPerson(

       OrgPerson personToMatch,

 

       out   FindPersonStatus status);

        public abstract System.Collections.Generic.List<OrgPerson> FindPerson(

            string personToMatchRegExp,

 

            out   FindPersonStatus status);

 

    };

 

 

So my implementation will fill out these abstract methods.

So I now have identified the triad of classes that make the basic provider model work.  Next I will fill out these stubs.

 

Announcing the Gadget Competition (Switzerland)

Hi Folks.  There are a series of local competitions starting around Europe Middle East and Africa (EMEA) for the best Windows Vista Gadgets.

Each subisdiary will judge the entries and award their own prizes so you are not in a global pool with a poor chance of winning.

The first country to start is Switzerland.  http://www.gadgetcompetition.ch so if you're Swiss and fancy yourself as a gadget writer then here is your chance.

I'll post up the other competitions in the region as they start.

Now as you have ideas and questions about building gadgets for any of these competitions please check out the forums on http://www.vistababble.com.

Good luck.

Posted by davewebster | 0 Comments
Filed under: ,

Teched Dev Europe Tracks

The TechEd Europe tracks are forming as follows:

Security
Business Intelligence
Mobile
Tools and Languages 
Web
Windows  (Frameworks and Base Platform, .Net 3.x)
Architecture
Dynamics
SQL
Connected Systems (Biztalk etc)
Designer
Office
Infrastructure for Developers

 

PDC Futures  virtual track (a few future oriented sessions based on content from the PDC).

 

I would really like your feedback on a couple of things here.  Infrastructure for Developers - what do you think?  We know that ITPro and Developers are different kinds of folks, but we need to be sure that we are developing solutions that are deployable and maintainable.  These would be sessions around infrastructure but aimed at us the developers.  If you like the idea, what kind of sessions would you like to see?

 The second thing I want to discuss is the closing keynote.  Now this takes time away from sessions but do you want to spend your last afternon in a deep session on SQL server or have a keynote speaker?

Cheers.

Dave
 

 

Sharing Calendars on Office Live

So I have finally joined an Aeroplane syndicate.

Charlie came breezing into my home office today with all the manuals for the Grunman Tiger.  We started talking and it soon became apparent that we would need a way to book the Tiger in advance.  This would mean that Charlie and I and the other guys would need to access her calendar from our outlook client.  It would also mean that the Chief Flying Instructor at the flying club (my old pal Laurie) would need to see the bookings also, as we are going to use some of his time to get us through our Instrument Rating.

So I used my ISP with Exchange hosting. (Can't tell you who it is unfortunately).  I created an account for the Tiger.  Configured my RPC/HTTP settings and fired up Outlook.

In all the whole process to this point took less than 5 minutes

Then I published the calendar on Office Live and invited myself and Charlie to view the shared calendar.  Another 1 minute.

Now I can book the plane and see her calendar in overlay mode.  7 minutes tops!  Wicked!

Posted by davewebster | 0 Comments
Filed under: ,

Teched Developer Europe 2007

Would you believe it planning has already started for this years TechEd Europe.  As I am running the technical content strategy this year I would like to ask you folks for your opinions.  I would like to devise a category scheme to help you navigate your way around the sessions at TechEd.  So I really need your feedback on these questions.

Now some of you will plan your whole week using the online tool and get a personal printout.  Others (like me) will look through the schedule in the morning or during a session and figure out where to go next.  The schedule is a small cramped piece of paper which anyone in the 40's will need to use reading glasses to read.  I would like your feedback on how you navigate the conference, and what's good and what stinks.

Firstly the DEV track.   I wonder if there is any point in having a DEV track at a developers conference.  I looked at last years numbers and found that out of about 200 sessions 130 were DEVxxx in other words 65%.  So what do you think about scrapping that designation?  Instead DEV would be implied for everything and we would have more track names like this:

BPI
Mobile
Tools and Languages 
Web
Windows  (Frameworks and Base Platform)
Architecture
Dynamics
SQL
Office

 Now of course some sessions cover more than one thing, such as a session on Orcas and WPF. For this I would suggest a primary category and a secondary category.

Traditionally we have used a number scheme based on courses in North American universities, so we have level 200, 300 and 400 sessions that give you various degrees of credit.  We are not North Americans so how about we scrap that too?  We would use another scheme to show depth or breadth of a session.  Perhaps we could use European ski run designations, Blue, Red, Black each with a different shape so you can see it quickly in the black and white printout. 

Therefore the session number becomes just like a primary key in a table, of less interest except when filling in your online eval forms.

It would look like this:

teched tracks

 Another question is about accessibility.  For those of us ageing rockers or those with visual impairments would you like to be able to get a printout of sessions in larger point sizes?

 

Ok please let me have your input.  Don't forget that this is not a discussion about content yet, my team will be working as hard as ever to bring you the Best Developer Conference in the world!
.


.

Bent pin on an IDE disk drive

It turned out that Santa had brought my son some PC games and as his machine was basically in bits on Christmas Eve I started to put it all back together.  Unfortunately I was a little too fortified with Christmas Cheer (Camel Valley Sparkling Wine) and I got the IDE cable of his hard drive back-to-front, thus breaking that one pin that lines up with the blanked hole on the interface. The pin was now 2 mm long and would not reach into its hole in the interface cable.

Here is how to fix a broken pin on an IDE disk drive:

·        Get a pin or needle used for sewing. 

·        Insert the pin into the correct hole in the interface card.

·        Remove pin and cut to length

·        Get a bar of chocolate

·        Eat the chocolate

·        Take aluminium foil from the chocolate bar and tear a tiny piece from it.

·        Pack the tiny piece of foil into the appropriate hole in the interface cable

·        Insert the pin into the hole in the interface cable -   thick end first.

·        Attach cable to disk.

·        Never remove cable

·        Never tell anyone.

I hope that helps.

Happy New Year.

Posted by davewebster | 1 Comments

Christmas PC Shenanigans

Well the weather here in Cornwall over Christmas was pretty horrible - no flying during the holiday.  Still I was able to build a new machine for my sister (even more demanding than J9) ,check out Laurie’s new box up at the airfield, and wreck my son’s machine.

Here are the specs for Sue’s machine:

  • Sempron 3300 CPU
  • Motherboard  K8M800-M2 AMD 754 Micro ATX  
  • 1.25 Gb PC133 DDR RAM
  • SAPPHIRE - RADEON X1300 PRO 256MB AGP GRAPHICS CARD
  • 2*SATA 80GB RAID 0 disks
  • AKASA AK-920 EVO120 - CPU cooler fan

I kept the old hard disk and made it the E: drive as before and kept the DVD Rewriter.

The power supply was a little too weak at 180 watts so I replaced that with a new 300W unit from PC World. Then we looked at the case and decided to junk that and replace it with a nice unit with front access to the USB and sound card but that was purely for aesthetics.

I assembled the whole thing with my sister crooning to my kids how ‘clever’ their daddy was.  Then it was time to switch on...

... Nothing!

So I have my sister looking over my shoulder as I am trying to figure out what had happened.  I took everything off the motherboard, removed the motherboard and checked for damage and reinstalled everything.  Still no BIOS.

Sue began to look agitated.  Well there are really on two things that can be wrong at this stage, either the motherboard is defective or I have zapped the CPU.  I guessed on the motherboard and went into town to replace it. This was Christmas Eve and I had one shot to get this working.  I installed everything including the space age CPU cooler and... it worked!  I had a bios and memory.  It took about 5 minutes to set up the RAID 0 on the SATA drives, then about 45 minutes to install Windows Vista Ultimate and we got a whopping 4.0 performance score with the disks coming in at 5.9! 

Clever Daddy indeed.

Sue also has a Lexmark p4350 printer and Virgin broadband using a SpeedTouch modem.  Both these devices installed OK despite the fact that Lexmark have not published a Vista specific driver.  In fact the only thing missing from the Lexmark install is the All-In-One-Center suite, and with the fax and scanning wizard there is really not much need for it anyway.

I put on Office 2007 Ultimate and Sue is one happy camper.

Total performance scores:

·        processor 4.0

·        Memory 4.0

·        desktop performance 4.8

·        Gaming graphics 4.2

·        primary hard disk 5,9

Phew! If you knew my sister you would know how nerve wracking it was.

Posted by davewebster | 1 Comments
Filed under:

Lauries machine goes VISTA!

I mentioned in my last post that I was rebuilding Laurie’s machine – a good friend and a flight trainer in Perranporth flying club.  Laurie frequently does Radio Telephony exams as part of the private pilot’s license. This entails linking two machines in separate rooms and having the student use headphones and a mic to simulate the radio calls.  The current setup was running Windows ME and Windows 98 and the RT exam program was not working.  It was definitely time for an upgrade.  I was also desperate to redeem myself for flying the Cessna 172 all the way to the Scilly Isles and back with the seatbelt hanging out the door.  This had seriously banged up the side of the plane just behind the door and cracked the window.  So yes, I would be delighted to help.

In any case, as a flying instructor in Cornwall there are many days with nothing much to do because of low cloud, wind, or other bad weather so a nice fast machine to browse the web or write documents is a good idea.

I had planned on using the same case and power supply that he had in the old machine but when I opened it up the power supply was woefully inadequate and the good folks at http://www.puterz.co.uk had recommended a slight upsell to the original motherboard that did not fit in the case – and anyway a new case is only twenty quid. 

After a trip or two to PC World in Truro I had a new case,  350 Watt power supply, Geforce 6200 graphics card, new motherboard, AMD Sempron Processor 160Gb EIDE disk, I used my son Andrews DVD-RW drive (I’ll tell him when he notices) and also 1Gb of RAM I had after upgrading J9s machine. I kept Laurie’s old sound card and wireless card.  I also kept the old disk to preserve the files and favourites.

I installed Windows Vista Ultimate, Office 2007, MSN IM, and the Radio Telephony app.  The performance score was pretty good, about 3.5 and incredibly better than he had before.  Then it was time to take the box to Laurie.

I explained how to start the machine using the power button, how to login, search for files, and a bit about how to run Office 2007.  I created links to his old files and IE tab groups for the met office aviation weather, NOTAMs (Notices To Airmen) and his hotmail. Then I changed the default file format in Office to the old format so he could share files with the rest of the instructors. I was very pleased with myself.

Laurie was terrified.

One of the problems we have as Geeks is that we don’t tell people when to pay attention and when to stop.  So as I am customizing his environment poor Laurie is trying to remember what I am doing even though it is only a one time operation.  Now Laurie is 78 years old and has a wealth of experience flying DC10s in the Middle East.  He can teach a new pilot to land a single engine Cessna in cloud and at night and he does not break a sweat but now he is completely freaked out by what I have done to his computer – I have even change the case.

So I went through things again slowly put links to his favourites on the desktop and then left… for Switzerland.

That was last weekend.  Tomorrow lunchtime I will call in with the other machine for the Radio Telephony exam app, set it up and see how he is doing. 

I’ll keep ya posted.

 

Posted by davewebster | 1 Comments
Filed under: ,