Wednesday, April 14, 2010

Generic Property Merge Using Reflection

I have found this generic merge method to be very useful. Before you cut and paste it into you Silverlight application, let me explain why I created it.

  1. public virtual bool MergeValues(object oSource, bool bNotifyUI)
  2. {
  3. bool bSucess = true;
  4. foreach (var oPropInfo in oSource.GetType().GetProperties())
  5. {
  6. if (!oPropInfo.CanRead !oPropInfo.CanWrite oPropInfo.Name == "Item")
  7. continue;
  8. var oResult = oPropInfo.GetValue(oSource, null);
  9. if (oResult != oPropInfo.GetValue(this, null))
  10. try
  11. {
  12. oPropInfo.SetValue(this, oResult, null);
  13. if (bNotifyUI)
  14. NotifyOfPropertyChange(oPropInfo.Name);
  15. }
  16. catch
  17. {
  18. bSucess = false;
  19. }
  20. }
  21. return bSucess;
  22. }

Once Silverlight binds a property to a XAML element, your program will perform a lot better if you just change the value rather then rebind to a new object. I have not done any detailed timing tests, but by using this code in a before / after way you can “feel” that this is faster.

I know there is a performance cost when you access a property via reflection, but I am willing to pay that cost to have a solution that is VERY reliable.

By defining this method as virtual you are able to override to build a version that performs better, for example:

  1. public override bool MergeValues(object oSource, bool bNotifyUI)
  2. {
  3. bool bSucess = true;
  4. Person oPerson = oSource as Person;
  5. this.ID = oPerson.ID;
  6. this.FirstName = oPerson.FirstName;
  7. this.MiddleName = oPerson.MiddleName;
  8. this.LastName = oPerson.LastName;
  9. this.MostRecentFlight = oPerson.MostRecentFlight;
  10. return bSucess;
  11. }

But this solution is not as reliable and requires me to change the code every time I modify the properties in this class.

Feel free to cut, paste and modify this code to meet your own coding objectives.

Sunday, March 21, 2010

NCAA Brackets in Silverlight

The developers at a company we were working with put out a challenge -- can you write software to pick the brackets in the NCAA basketball tournament? The answer is you can and 6 of us did. Our solutions range from random number generators to multivariate stepwise regressions. We did the multivariate stepwise regression.

I created a Silverlight application to display the results; that is, Debra designed the application and I did the software. The code is posted to codeplex here, and you can see our picks at http://www.mysilverisland.com/NCAA.

The code is very object oriented and uses a direct approach to pushing the data into the view. No MV-VM was necessary, but that was because of the nature of the solution. This application simply creates a report of our picks, and the picks are shoved into the brackets using a "plug and chug" technique of matching textbox names with ID's in a collection.

I think this code may be useful for other developers who need to manage a tournament.

You can get the source code on codeplex:

http://ncaabasketball.codeplex.com/

Thursday, February 25, 2010

Another Way to Think about Code Reuse

Anyone who practices Object Oriented Programming has a lot of different ways to reuse code. The most common way is to use inheritance, but recently I have been reusing code in an unconventional way.

Whenever I create a class I follow a strict convention on naming properties. Here is an example:

  1. public class Movie
  2. {
  3.     public string Title { get; set; }
  4.     public List<People> Actors { get; set; }
  5.  
  6.     public DateTime ReleaseDate { get; set; }
  7.     public double MoneyEarnedToDate { get; set; }
  8.  
  9.     public string Producer { get; set; }
  10.     public string Genre { get; set; }
  11. }

CamelCase is the convention I use to define every property. I always use complete words and never use abbreviations. I do not use underscores in public properties. I stick to this convention because it lets me extract Meta data from the class while it is in use and can be used to simplify coding of the UI.

  1. public class CustomGrid : DataGrid
  2. {
  3.     public CustomGrid()
  4.         : base()
  5.     {
  6.         AutoGenerateColumns = true;
  7.         AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(OnAutoGeneratingColumn);
  8.     }
  9.  
  10.     void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
  11.     {
  12.         string sHeader = e.Column.Header.ToString();
  13.         e.Column.Header = CamelToTitleCase(sHeader);
  14.     }
  15.  
  16.     public string CamelToTitleCase(string Text)
  17.     {
  18.         Text = Text.Substring(0, 1).ToUpper() + Text.Substring(1);
  19.         return Regex.Replace(Text, @"(\B[A-Z])", @" $1");
  20.     }
  21.  
  22. }

Via inheritance I can customize the standard Silverlight DataGrid to automatically generate columns for whatever class is bound to it. I sign up for the OnAutoGeneratingColumn event so I can rename the column headings. The function CamelToTitleCase will automatically insert spaces before each capitol letter, so the property ReleaseDate becomes the header Release Date and the property MoneyEarnedToDate becomes Money Earned To Date



So is using a coding convention really code reuse or is it more like asset repurposing? I have learned that having a convention makes my code easier to read and debug. It also leads to even more advanced techniques I will share in later blogs.

Monday, February 15, 2010

Know Your Parents and Grandparents

In programming Silverlight I have come across situations where a control or framework element needs to access information on its parent. The code to get information off your direct parent is simple:


  1.             var oContent = this.Parent.ReadLocalValue(Content);
for example.

The real power of Silverlight is in the declarative nesting of XAML elements, and that means that the type of your direct parent may not always be known. To clarify, if you drop a control on a Page, then the Page object will be your parent. However if you then wrap your control in a ScrollViewer, the ScrollViewer becomes your parent and the Page becomes your grandparent.

To avoid all these issues I include the following code in most of my Silverlight projects:

  1.         public virtual T ParentOfType<T>() where T : FrameworkElement
  2.         {
  3.             Type oType = typeof(T);
  4.             var oParent = Parent as FrameworkElement;
  5.             while (oParent != null)
  6.             {
  7.                 if (oType.IsInstanceOfType(oParent))
  8.                     return oParent as T;
  9.  
  10.                 if (oParent.GetType() == oType)
  11.                     return oParent as T;
  12.  
  13.                 oParent = oParent.Parent as FrameworkElement;
  14.             }
  15.             return null;
  16.         }

Recently I needed to access the Navigation Service that is part of a Silverlight Page object. Using the method above I wrote this code to access the service:

  1.         void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  2.         {
  3.             var oPage = ParentOfType<Page>();
  4.  
  5.             if ( oPage != null )
  6.                 oPage.NavigationService.Navigate(new Uri(NavigateUri, UriKind.RelativeOrAbsolute));
  7.         }

Now regardless where this control is placed in the XAML, the Navigation Service will execute correctly.

Monday, January 25, 2010

What I Learned at PDC - Microsoft Tools

Visual Studio 2010 (VS210) is the latest version of the software development platform. It is also the first version to be written entirely in .NET managed code. It also uses MEF to manage extensibility and WPF to implement all the UI and code editing tools. Microsoft also offers a development environment for GUI and web designers call Expression Blend. Blend and VS2010 share the same project file format so projects can be shared between developers and designers easily.

Developers, you should know that every demo at PDC was done using VS2010 and there are lots of sessions that dive into the new features. An existing but little used VS2010 feature (that may go as far back as the very first VS) is T4 templates. These are code generation templates that developers can customize to pragmatically create code. Scott Hanselman show this technique at 20 minutes into his talk FT59: ASP.NET MVC 2: Ninjas Still on Fire Black Belt Tips.

Designers, VS2010 also includes a design surface to help developers create GUI in WPF/XAML. It works well for simple GUI composition, but is not good for real creative work. Blend is the tool of choice for creating GUI with animations or custom controls that use Virtual State Manager.

For non-developers, there are only 2 things you need to know about this tool:

1) VS2010 can generate code for any version of the .NET framework in existence; this feature is called multi-target deployment. Developers can port their projects to VS2010 without being forced to upgrade to a specific version of .NET. By simply flipping a compiler switch, you can retarget your application to take advantage of later versions of .NET. I have tried this on software I wrote for .NET 1.1 and it works great. It runs in .NET 3.5 and 4.0 without any issues.

2) In building VS2010, Microsoft’s main focus was developer productivity. I have found that I was immediately productive with VS2010 and took advantage of many of the new features, like a visual form builder for Silverlight applications, intuitively.

Bottom Line: developers should install and start working with VS 2010 right away. Simple new features, like being able to open VS2010 windows on multiple separate monitors, will improve developer productivity or at least reduce programmer fatigue. Also check out CL09: How Microsoft Visual Studio 2010 Was Built with WPF 4 to see how Microsoft uses their own technology to build their own products. This talk also shows a tool named Snoop that lets you see all the layers of the WPF tree being rendered: Snoop.

Quality Assurance, Testing, Performance and Source Code Control

These tools make the difference between hacking out code and developing software professionally. I have an interest in all these tools but they are not my primary focus, so here is a quick list of the sessions I attended or watched and my comments.

CL25: Become a Web Debugging Virtuoso with Fiddler: If you are building / testing / debugging web applications, Fiddler is a tool that can let you see communication between your web browser and the server. This talks show how that and other features of Fiddler can help you create web applications.

CL32: Developing Testable Silverlight Applications: This talks shows, in detail, how to build automated unit tests for Silverlight applications that can mimic user interaction. It also shows how you can write applications that are more testable by using the MV-VM pattern.

FT35: Microsoft Visual C# IDE Tips and Tricks: Learn some productivity tips that are new in VS2010. Learn how to get a deeper insight into your code and improve your speed to solution. DJ Park proves it by racing the clock to generate code, a must-see event 43 minutes in. Also check out CodeRush Xpress for C# . It is a free refactoring tool that lets you move around bodies of C# code while preserving the coding intent. Also check out the Architecture Explorer in VS2010, 13 minutes into the talk.

FT54: Power Tools for Debugging: Debugging is hard; VS2010 has some new debugging tools like Intellitrace to make it easier. But this talk is mainly about research into future debugging tools. They show a Holmes, a statistical debugger that can find a correlation between code paths and test failures.

Wednesday, January 20, 2010

What I Learned at PDC - .NET Platform and Extensions (continued)

Composition Manager (MEF) and Construction Manager (Prism)

The Microsoft Patterns and Practices team have built software libraries to help large teams develop large applications. It turns out that these techniques also work well in any application.

MEF stands for Managed Extensibility Framework. This is a technology designed to introduce extensibility points (like Office or web browser plug-ins) into your application. Developing with extensibility in mind lets you think of your application as a platform and can simplify your other development efforts. A well componentized application can be extended after it is deployed by third parties that have special or advanced needs. The technique can foster an ecosystem around the original application, letting others open new markets for your original solution. Glenn Block has a hand in creating MEF and Prism: FT24: Building Extensible Rich Internet Applications with the Managed Extensibility Framework . Listen to the first 5 minutes to understand the problem MEF is solving. Projects can be extended by MEF after initial development, but it is best to think about extension points as you go. Watch the demos first, then circle back to get see how it is done. I love the demo he does 45 minutes into the talk. It shows how MEF can be used to control feature access and deliver functionality on demand. At 50 minutes in you can see a series of demos that have real world application.

Extensibility can also be a competitive advantage. If you expose your application by exposing data services, you may be fostering competition from others to build their own client. Providing extensibility in your own client lets would-be competitors become partners by building extensions that use your data services client plug-ins. A step by step demo on adding MEF to your application is done my Mike Taulty, whom I also had a chance to meet.
Prism is not an acronym for anything -- it is a collection of technology services and constructs that promote loose coupling of software components by introducing a series of “management” object classes. Prism is not really a Microsoft product, so it does not get the marketing push, but anyone who was discussing a rich client application talked about using Prism.

The best guide I have heard, hands down, on Prism is from my friend Eric Mork: Prism Development Guides and Videos. If you follow this link, also sign up for his podcast where he talks technology with many of the experts in the Silverlight community. The commanding feature of Prism is now unnecessary with the addition of ICommand in Silverlight.

Friday, January 15, 2010

What I Learned at PDC - .NET Platform and Extensions

In the late 90’s, the general consensus was that the Microsoft programming model was losing ground to JAVA. At that time, every product that Microsoft offered was COM(Component Object Model) based. And every language Microsoft offered produced COM programs. The COM programming model generated machine instructions targeted at the native instruction set of the CPU. JAVA, on the other hand, provided a virtual machine environment, so compiled JAVA code targeted the instruction set of the virtual machine (VM), which is an abstract CPU. JAVA was able to use its VM implementation to create the catch phrase “write once, run anywhere”, because all that was needed to execute your JAVA program on any OS, platform or device was an implementation of the JAVA VM. There was no need to recompile your JAVA code in order to run it on a new target machine, and as a result there was no need to created install programs to set up the target machine. ‘X-COPY deployment’ become another catch phrase because all you needed to do to install and run a JAVA program was to copy the binaries to a folder on the target machine and say run!

In early 2000 Microsoft released .NET, its own VM based programming environment. At the time, Steve Balmer described .NET as a corporate strategy, programming environment and a marketing campaign. All programming languages implemented in .NET (VB, C#, C++) would emit the same instruction set and target the VM. This makes is possible to easily create applications that mix languages. .NET also makes it possible to call into programs written in the older COM technology through a process called ‘interop’.

Throughout this decade Microsoft has been improving the .NET platform. Two new technologies that emerged in .NET were WPF (Windows Presentation Foundation) and WCF (Windows Communication Foundation). These technologies are the core components used for GUI and networking.

So what is new and improved in the .NET platform? Everything, starting with .NET itself.

The latest version of .NET is .NET 4.0. It should be noted that many of the productivity frameworks come in the box as part of the .NET 4.0 platform, and have also been back-ported to .NET 3.0 and VS2080 SP1. Many are also open source.

Language and Modeling Tools
.NET Framework (POCO, LINQ, Rx, IDynamic ) : it all starts with improvements to the .NET framework. POCO is an acronym for Plain Old CLR Objects (CLR is Common Language Runtime), and although POCO has been around since .NET 1.0, Microsoft is favoring this type of detailed definition for data binding and transportation over the existing classes like DataSet, DataTable & DataRow. I think it is because they work better with LINQ (Language Integrated Query).

LINQ is a fabulous technology (Wikipedia: Language Integrated Query) for lots of reasons. One of the most important, from a developer’s point of view, is that it reduces the interaction with any .NET data source (SQL, XML, CSV…) into a single syntax.

Rx, or Reactive Framework, was one of the surprises of PDC, and I did not even discover it until after the conference, online. The LINQ model is to pull data from a data source, where the Rx model reacts to changes in the data source and sends you a notification. The session VTL04: Rx: Reactive Extensions for .NET explains how it works. Eric Meijer leads the talk and he always wears a tie-dyed shirt, always.

IDyamic is the feature / interface I have been waiting for since the PDC08 demos. Dynamic languages defer compile type checking to runtime and in many cases this is very useful. Popular languages like Ruby (on Rails) use this technique exclusively. This, in conjunction with the DLR (Dynamic Language Runtime), will make is possible to extend the syntax of any .NET language. It offers better interop with COM based software, like Office and VB6. The DLR is also a major component for languages like Iron Ruby and Iron Python. Mads Torgerson gives a solid talk on the development history: FT31: Dynamic Binding in C# 4. Luck Bolognese gives a talk that shows using the technology: FT11: Future Directions for C# and Visual Basic.

Adding dynamic characteristics to existing languages follows the theme of programming in a declarative style instead of an imperative style.

I will finish this topic in my next post on PDC, where I will talk about MEF and Prism...

Sunday, January 10, 2010

What I Learned from PDC - Server Technologies

The server is a provider of a set of services to support the client and the domain. The server is hosted on a machine that could be anywhere on the internet or on the same machine as the client. There are also a lot of applications (like Microsoft Office, video games) where the client (GUI) / server (Services) are integrated into one common executable. Think of a Server as software that is providing a set of services to many clients. Cloud computing has changed the notion that a Server as a physical machine on the internet -- that type of thinking makes it hard to grasp the ideas to come. Envision a server as a provider of a set of services -- authentication, billing, data retrieval and persistence, document management, 24/7 availability, scalability, compute power, social connection and interaction – and you will begin to understand why the industry is calling Cloud Computing the next step in the industry.

Data Services: It is about bridging data across the web between clients and servers. Data Services package data into RESTful style services that transport data to client applications via structured, parse-able text feeds in Atom (XML) or Json format. They also provide data access business logic that can be used to restrict data operations (CRUD). The foundation of all these services is called Windows Communication Foundation (WCF) and from this technology branches all the data related technologies like WCF Data Services, RIA Data Services, and OData.
Talking Points: Pablo Castro shows a Json / JQuery demo (at 20 min in) that has the browser providing the data proxy; at 34 minutes in is a data service server construction demo: FT12: ADO.NET Data Services: What’s new with the RESTful data services framework. You can also see, live, the limits of JavaScript debugging tools.

Data Abstraction: In modern .NET applications nobody programs SQL statements directly against the database. Instead, developers use tools like Entity Framework, n-hibernate or IdeaBlade to build an object based data abstraction layer. The abstraction layer simplifies the code that provides data operations CRUD and protects your applications from changes in the underlying database table and column structures (schema) that is necessary for physical storage and performance. This layer also provides metadata about the data source, which make it possible to create tooling to generate code and documentation from an empty data source. I think that all modern .NET software should take advantage of a data abstraction layer.
Talking Points: FT10: Evolving ADO.NET Entity Framework in .NET 4 and Beyond. I love this talk; it is all demos that show how Microsoft is listening to developers and tuning the Entity Framework to address real world development issues. Don Box and Chris Anderson show in Data Programming and Modeling for the Microsoft .NET Developer that you can create a database from the model or from code. It is worth watching.
Data Storage: Microsoft’s enterprise solution for relational data storage is SQL Server 2008. However data can be stored and accessed in other data providers like XML or the file system. If your application has more that one database (maybe resulting from the need to run disconnected), synchronization is going to be one of your largest problems. Luckily there is an app for that: Microsoft Sync Framework.
Talking Points: Mark Scurrell’s talk SV23: Using the Microsoft Sync Framework to Connect Apps to the Cloud is loaded with demos that show database synchronization in action, and very little code is involved.

Isolated Storage vs. Client Resource Access
Thin clients use HTTP cookies to store information on the client. This small bit of text is stored somewhere in your local hard drive, deep in the file system. Browsers are known for running their applications in a sandbox. This is used to promote secure operation of untrusted programs. The sandbox constraint is also true for rich client plug-ins . They run in a sandbox and have no access to client resources until the user gives permission. Silverlight applications have access to a larger storage area (1 MB , with the user’s permission) referred to as isolated storage. The isolated storage area can be used to store configuration information and user setting preferences. It can also be used to cache local record sets, making it possible to work in a disconnected mode.

A Silverlight application, with the user’s permission, can be installed to the desktop from the browser with a single mouse click and run in full trust or out-of-browser mode. With elevated trust, the Silverlight application can now access all your client resources and function as a thick client. Some of the more common scenarios here are to access COM software components (Microsoft Office, VB 6 Programs) and read and write to the local file system.
To really understand the ease of programming Out Of Browser (OOB) applications and the power of having the same code function as thin client and thick client, watch Joe Stegman’s talk CL20: Improving and Extending the Sandbox with Microsoft Silverlight 4.

Saturday, December 26, 2009

What I Learned from PDC - Domain Technologies (continued)

Controller Model: All the commanding and navigation instructions are implemented at this level. Think of this layer as reacting to menu clicks, hyperlinks or changes of URL address. The controller is one of the central models in ASP.NET MVC (Model View Controller) and in a good implementation will defer many of the control logic decisions to the domain model. In ASP.NET MVC, the controller is used to return a view based on an action, and will typically consult the model to do so. In other applications the controller is not as pronounced, however there are usually classes that expose functions to act as command targets.

Talking Points: Exposing ICommand for Silverlight has simplified the implementation of a control pattern. Best examples using the controller pattern are FT59: ASP.NET MVC 2: Ninjas Still on Fire Black Belt Tips by Scott Hanselman, FT22: Microsoft ASP.NET MVC 2: The New Stuff by Stephen Walther, CL22: Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight by John Papa and CL21: Building Amazing Business Applications with Microsoft Silverlight and Microsoft .NET RIA Services by Brad Abrams. None of these talks show you how to build a controller, but they all use an MVC pattern to build their application.

Data Proxy: The Data Proxy layer is a service oriented architecture (SOA) where the communication is with a data source. There is no limit to the data proxies in this layer. In fact there is no limit to the number services your domain can subscribe or publish to. Proxies can be generated automatically by querying metadata about the WCF service. Proxies are class based representations that model the WCF services API. The abstraction is so good, you are hardly aware that you are using a service on a remote server as you program. Proxies can be generated for anything that has a communication contract. The contract is typically expressed in metadata and there are tools for translating the metadata into code that implements the contract explicitly.


This layer is all about communication. The pictures above were taken from Yavor Georgiev’s talk: CL06: Networking and Web Services in Silverlight. The first picture shows the technology layers that .NET WCF provides. The programming model is built over a TCP/IP based protocol. The second picture shows the spectrum of communication applications. Yavor discusses the interaction between communication and different types of applications, from transactional data systems to multicast video systems. Generally speaking, WCF RIA services is the Microsoft technology of choice for building Silverlight rich clients and there are several talks showing this.

Talking Points: See FT12: ADO.NET Data Services: What’s new with the RESTful data services framework Pablo Castro’s client demo (at 44 min in). For an intro to RIA services: CL21: Building Amazing Business Applications with Microsoft Silverlight and Microsoft .NET RIA Services with Brad Abrams. You can tell from this talk the Microsoft is shaping this technology to create Line of Business CRUD applications. You can dive below the surface with CL07: Mastering Microsoft .NET RIA Services.

Tuesday, December 22, 2009

What I Learned from PDC - Domain Technologies

The domain is the brain or personality of the application and is usually built with the help of a Subject Matter Expert (SME).

I like to think of the domain as having the real knowledge of the application and the Client and Server components as providing input/output services. Think of the case where a text box control is doing input validation. The code in the control can be kept simple, it just needs to verify that the text typed in by the user conforms to a validation rule, and if it does not, display some type of message.

An implementation that binds the control to a text string might also execute validation logic in the On-Click code behind method. An implementation that binds the control to a property lets the code in the control stay generic, and keeps all the validation logic in the domain model where it can be easily maintained. This separation of concerns is the ‘S’ of the ‘SOLID’ design principle and you can learn about the other components (OLID) here.

When you create a domain model that uses the vocabulary of your SME, and solves problems using the processes the SME would use, then the rest of the application becomes easier to build. The Client and Server layers become tools to visualize your domain model or persist your domain model.

Domain Model: The Domain Model executes the formal business logic and should be the primary location for all the application state transition rules. Very few talks have time to develop a Domain Model, however if you watch talks that focus on language features, LINQ, Rx or parallel computing they are full of examples showing how domain modeling is becoming more declarative and less imperative. That is, software design is evolving into describing what you need the computer to do instead of traditionally telling the computer how to do it. .NET is evolving to merge dynamic, functional and object oriented programming models into the platform. The declarative slant in coding allows the .NET platform to make decisions about how to execute the code at runtime, to take advantage of system resources like multiple CPUs or resources in the Cloud.

Talking Points: Microsoft talks do not focus on the domain model at all. The only talk I found that fits the definition is Cl36: Deep Dive on Bing Maps Silverlight Control because it focuses on the domain of mapping, however the domain is so well defined it is delivered as a GUI control and a service. Instead look to the language features to help you model your domain: FT11: Future Directions for C# and Visual Basic. Developers should be aware of a new (or maybe very old if you know LISP) way of programming FT20: F# for Parallel and Asynchronous Programming , languages for Data Modeling FT34: Microsoft Project Code Name “M”: The Data and Modeling Language, Parallel Computing Platform: P09: Manycore and the Microsoft .NET Framework 4: A Match Made in Microsoft Visual Studio 2010 and Erik Meijer VTL04: Rx: Reactive Extensions for .NET. Rx technology was the language innovation of the show. Learn about Rx in 15 min here.

I will cover the Controller Model and Data Proxy in the next post.

Friday, December 18, 2009

What I Learned from PDC - Client Technologies

Client Technologies

There are many different client side technologies in the Microsoft ecosystem, and each has evolved to meet niche markets and end user needs, including video game, business apps, reports, and web page browsing. The defining technology of the client is probably how the view is rendered and the device’s ability to interact with that rendering.

View Rendering: Microsoft provides two different solutions for rendering a GUI: the thin client solution is HTML/JavaScript rendered inside a web browser, the rich client solution is XAML, which can be rendered in a web browser via a Silverlight plug-in, or as part of a thick client application using WPF. So XAML is dual purpose with the caveat that the end user must install the Silverlight plug-in (5 MB, 30 second, one time operation, just like Flash). Simple HTML has more range, because it runs in any browser, but when you start adding CSS and JQuery libraries (and other fancy things) you begin to limit yourself to a subset of browsers, IE7,IE8,Firefox,… again if you can control your target, this is not a problem. The Silverlight plug-in is designed to remove browser incompatibilities and create a UI that is “run anywhere” including Mac and Linux.

Talking Points: FT29: Microsoft AJAX Library, jQuery, and Microsoft Visual Studio 2010 Stephen Walther, shows how to build thin HTML clients with a new open source AJAX library, including 40 client controls, Open Source.

View Model: The purpose of a View Model is to shape your domain model to a view rendering technology. You must manage the interaction controls, events, value conversion, input validation, and general state of the GUI controls rendering using this model. In WPF/Silverlight, the View Model provides a site to bind the UI to the domain model. Sometimes perceived as additional work by programmers, the decoupling of the view from the domain model actually simplifies the implementation of the client GUI by providing a site for view logic that is independent of the domain. Some good examples are multi-lingual UI’s, currency conversion, hiding sections based on roles, and changing screen presentations based on task, expertise or device size. This separation also makes the application much more testable using an automated test suite.

Talking Points: Newly added ICommand support was the final step in making the view rendering and the view model truly independent and testable. Some Silverlight talks that discuss View Models are Cl19: Building Line of Business Applications with Microsoft Silverlight 4 and John Papa’s talk Cl22: Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight

Saturday, December 5, 2009

What I Learned from PDC - Service Oriented Architecture

Mapping Functionality into Abstract Software Components

Each of the presentations at PDC are designed to discuss some aspect of Microsoft’s packaged technology: ASP.NET, SQL Server, Silverlight, Entity Framework, LINQ & PLINQ, MVC, WPF, WCF Data service, Azure, … Windows 7. In every case, the presentations show code samples on how to use that technology, and in the process they casually introduce some abstract software architecture concept (View Models, Data Proxies, Domain Models…) to help illustrate the technology.

Application Depth

I have extracted the software concepts from all those talks and constructed an application depth stack that maps these functional requirements to software layers. These layers combine the “best practices” in software design from ASP.NET MVC, WPF & Silverlight applications and also include technologies that are common to all solutions like WCF Data Services, SQL Server and Entity Framework. The software component names are not official and the code boundaries between them in many cases are not precise, but they are useful in categorizing the Microsoft technologies that are used to construct and execute each layer.

Client, Domain and Server Models

I broke the sections up into Client, Domain, and Server. The Domain section can execute on the client or the server. When deployed as a thin client, the Domain logic is executed on the Server, but when deployed as a rich client the Domain executes on the Client and helps manage State. Server components are traditional data access services. Using data services is now Microsoft’s preferred way of connecting to data. Data services use simple web protocols to request and transport data even if you are consuming data on the same machine as the client. The service can be accessed just by passing a URL. Data access is provided using proxy service “wrappers” that provide an API by ingesting the META data about the service. These are the building blocks of a Service Oriented Architecture (SOA).

Best Practices? For My Purposes They Are!

I am not saying that each of these abstract software components need to physically exist in order for you to have a well designed or valid .NET application. Most CRUDS database solutions (Create, Read, Update, Delete, Search) are put together in a forms-over-data software architecture and do not implement all of these components. I am saying that during the design/development phase of a solution, I believe that the most developers should at least think about these functional areas, even if it is just to dismiss them as unnecessary.

Monday, November 30, 2009

What I Learned from PDC - Thick, Thin and Rich Clients

These three paradigms of application deployment try to optimize between application reach and application experience.


Thick Clients

Thick clients have easy access to client resources (file system, local databases, USB ports, and peripherals). They are also characterized by running their code on the local CPU. Thick clients do not need to be connected to the internet to run, but they can be connected to resources on the internet. Using local resources and memory allows them to be ‘stateful’, which means the application can easily remember the actions of the user as the user progresses. Behavior like dynamically enabling menus, progressing through a wizard dialog or cut/copy & paste are examples of statefullness. Microsoft provides 2 technologies to create thick client applications: Winforms (Win32 & GDI) and WPF.

Thin Clients

‘Thin client’ was the original name given to web browser based applications. This paradigm has all the code executing on the server, and the code is designed to deliver information to a web browser (HTML and JavaScript), and the browser will render the information as a web page. Microsoft markets ASP.NET and ASP.NET MVC as platforms that deliver thin client solutions. These applications have achieved wide popularity because of their reach -- anyone with a browser and an internet connection can access this information -- regardless of the hardware or operating system. Developing richness in these applications requires the use of Cascading Style Sheets (CSS), Ajax, JQuery and JavaScript.

Browser based applications are not really stateful on the client (with the exception of cookies and session tokens), so with each user interaction, the local HTML, stored in the browser’s in-memory Document Object Model (DOM), is modified or refreshed dynamically. Ajax and JQuery are technologies used to modify the contents of the DOM (letting it refresh the screen after the change) and can be used to create some amazing GUIs that rival thick client applications. Thin clients have two weaknesses:
1. For security reasons, they are forced to run in the browser’s “sandbox”, which limits access to local system resources.
2. Building a rich GUI is difficult, and making that GUI testable is extremely difficult.

Based on my conversations at PDC, I found that programmers who quickly adopt the Ajax / JQuery route to provide richness have spent years creating UIs by programming JavaScript or HTML in ASP.NET applications. These technologies naturally fit into their way of thinking and their existing knowledge and experience.

I have seen solutions that deploy thin client / server applications onto a single box to try and get the advantages of the thick client. This can be done by using a Web Server (like IIS) and works well in applications that do NOT need to access local machine resources. This approach has difficulty synchronizing with a data source on the web. Integrating to local resources from the browser “sandbox” eventually requires some sort of browser plug-in that the end user trusts and has given permission to access the resources.

Rich Clients

Rich client applications, and Silverlight in particular, try to blend what is best about thick and thin clients. Microsoft accomplishes this by making Silverlight a 5 MB subset of the .NET platform, optimized to run on any OS (Windows, Mac, Linux) instead of targeting any particular browser. Silverlight is delivered to the browser as a plug-in (similar to Flash or Adobe Reader) and can use the browser’s resources and DOM.

Applications written using Silverlight can also be installed on the desktop and access local machine resources. So, like thick client solutions, rich clients run code locally and offer GUI features like drag/drop, animation, threading, and statefulness. They can also run connected or disconnected and can access local resources. Like thin client solutions, rich clients are accessible via a web browser, deliverable without a separate install, can detect newer versions and update automatically. Silverlight has the advantage of using the same programming environment as the server. This is VERY important.

As a developer, what I really like about Silverlight is that you can use the same code regardless if it is running in a browser or on the desktop. All the development can be done in WPF (XAML) and C#, so I do not need to be expert in a lot of different authoring technologies. Having the common .NET platform on both the client and the server makes it easier for me to optimize the solution’s performance just by moving code between the client project and the server project. Silverlight is aware of where it is running, which makes it easier to add and remove application features at runtime by querying the environment dynamically and not having to trust that the user installed the correct version. Lastly, the entire solution, from GUI to database access, can have a built-in automated test suite to assure quality and performance.

Asynchronous vs. Synchronous Communication

Asynchronous and synchronous communications are shown in boxes on the diagram. Silverlight enforces an asynchronous communications model when communicating with the server. That is to say that GUI interaction is not blocked when you are loading data or web pages. So while the user is performing tasks like navigation or mouse over, in the background Silverlight can be running calculations, doing analysis, loading data or any other programming task. Thin client solutions, including ASP.NET MVC, tend to run in a synchronous manner, which is where the user performs some action, the request is passed to the server, then the server sends a page of information back to the client, and the browser re-renders the page. Ajax and JQuery allow the application to send requests to the server that re-render sections of the page, but you cannot interact with those sections while they are ‘waiting’ for information. Microsoft introduced GUI controls that allow the Silverlight UI to behave synchronously by showing a progress bar and blocking user interaction. Blocking has it uses, but to me this feels like a step backward.

The challenge is to design UIs that are still functional while waiting for data. Think of iTunes - while songs are downloading, iTunes does not prevent you from accessing all of its features. Building a good GUI that blends the menu / work-area paradigm of the desktop with the hyperlink / URL navigation of the web is very tricky. Users can get focused on the details so quickly (colors and styles) that the things that make a very useable GUI, (layout, workflow, transitions and statefulness) do not get detailed consideration until after deployment.

Wednesday, November 25, 2009

What I Learned from PDC - An Overview

I attended MIX07, PDC07, MIX08, PDC08, and MIX09 online, so I have been following the Microsoft technical narrative for the last 3 years. I attended PDC09 live. One of my goals was to organize the technical narrative, which is normally presented product / technology centric into the components of a single application centric model.

For the past decade, my customers were looking for applications that offered the best of all experiences. Because they were unconstrained by technology in their thinking, they asked for features that were an amalgam of Web, Phone and Desktop applications, their ‘ideal’ application. I have been looking for a set of technologies that can deliver all these features from a single code base. I could see Microsoft was approaching such a solution, and at PDC09 many of these pieces came together. I created a diagram to help navigate the changing face of Microsoft technology in the light of customers’ Web/Desktop visions.


If you find this diagram hard to read, don't worry -- it will be broken down into readable pieces in the blog posts that follow.

The ‘ideal’ application in my customers’ eyes can run over the web, or run disconnected on a laptop without changing the GUI or user experience. Being connected to the internet should only be necessary to read or share data, but not a requirement to complete work. It should also be able to run on nearly any device with any screen size, a server, desktop, laptop, or a phone. Software components must be agnostic of where they are running (client or server) and cannot duplicate logic. The software community describes this style of application as Line of Business (LOB) apps; I do not like the term but it looks like it is getting a lot of traction on the web. Two archetypes for this LOB style of application are a traveling salesman and a soldier deployed in Afghanistan.

The diagram above is used to map the Microsoft technologies to support the LOB application. Not everything discussed at PDC09 has a place in this mapping, but I think you can get more out of the talks if you keep this diagram in mind while you pick and choose among the talks. The diagram shows, on the left side, the breath and depth of an application, on the right side, the technology and tooling available to construct, maintain and deploy the application. The functional layer (vertically down the center) was extracted from and reinforced by many of the PDC talks.

A well designed end-to-end .NET application will account for all of these functional layers in each of the technology stacks. As developers (and users), we can see the value in a software architecture that includes GUI, Client/Server side validation, Logic and Rules, Command/Navigation control, Data services, Networking, Object Relation Mapping, and Persistence.

Vertically the diagram shows a progression from End User to Application Hosting, via a set of functional requirements (Functional Layer). Horizontally, there is a set of four technology stacks, each with a unique perspective on building software.
Horizontally I have juxtaposed 4 diagrams each focusing on a different aspect of the software development process -- breadth, depth, platform, and tooling. Here are some working definitions:
•Breadth: who is the audience and how do I reach them, how do they plan to access my solution?
•Depth: what tasks do my users do and under what conditions, how do I make the application easy to use?
•Platform: what are the technologies I can use to build a deployable, maintainable, extensible solution, successfully using the skills of my development staff?
•Tooling: what are the tools available to assure that I am producing the solution efficiently and correctly?

My goal is to explore the subset of the Microsoft technologies presented at PDC in the context of building a solution that can run thinly over the web, or disconnected as a thick client reusing as much code and common technologies / tooling as possible. The result should be a road map of the essential Microsoft technologies you should be aware of in order to build a modern .NET client/server application.

Monday, August 31, 2009

M-V-VM Product Configuration

Deb and I have created many solutions that support sales or engineering efforts. Each application is a little different, driven by the unique aspects of the product we are selling/designing. We have built systems to sell cars, to quote multi-million dollar communications infrastructure projects, to design chemical plants and gear boxes.



You do enough of these applications and you start to see a software design pattern. You also realize just how important the role of the subject matter expert is in helping you create a successful application.


Our first Silverlight product configuration solution is a Cookie Designer. With a lifetime of experience eating cookies and a trip to the store to read the packaging, I now consider myself a subject matter expert. You can test drive the program HERE.

The Cookie Designer is an entry in the Summer Silverlight Coding Competition -- please try it and vote for our solution. Community points are an important part of the judging in this contest.

Our cookie product configuration solution is composed of a set of ingredients that can be combined without any mutually exclusive constraints. Anyone for cinnamon oatmeal dark chocolate chunk?

The secret to creating a convincing picture is to have each ingredient on its own separate layer and to make visible the layers that are involved -- enter the M-V-VM pattern, and in this case used as an adapter / translator between the composition of the model and what is shown.


<Canvas x:Name="CookieRoot" Height="400" HorizontalAlignment="Center" VerticalAlignment="Center" Width="400" Clip="M0,0L400,0 400,400 0,400z" RenderTransformOrigin="0.5,0.5">



<Image Height="381" Width="404" Canvas.Left="-9" Canvas.Top="8" Source="Cookie_Images/Base Cookie.png"/>

<Image x:Name="Cinnamon" Height="382" Width="390" Opacity="0.651" Canvas.Left="6" Canvas.Top="13" Source="Cookie_Images/Cinnamon.png" Visibility="Collapsed">

</Image>

<Image x:Name="PeanutButter" Height="379" Width="385" Opacity="0.478" Canvas.Left="7" Canvas.Top="9" Source="Cookie_Images/Peanut Butter.png" Visibility="Collapsed"/>

<Image x:Name="ReesesPeanutButter" Height="379" Width="385" Opacity="0.478" Canvas.Left="7" Canvas.Top="9" Source="Cookie_Images/Peanut Butter.png" Visibility="Collapsed"/>

<Image x:Name="Cocoa" Height="387" Width="389" Opacity="0.678" Canvas.Left="5" Canvas.Top="5" Source="Cookie_Images/Cocoa.png" Visibility="Collapsed">

</Image>

<Image x:Name="Oatmeal" Height="380" Width="387" Opacity="0.412" Canvas.Left="6" Canvas.Top="7" Source="Cookie_Images/Oatmeal.png" Visibility="Collapsed"/>

<Image x:Name="Peanuts" Height="377" Width="381" Canvas.Left="9" Canvas.Top="10" Source="Cookie_Images/Peanuts.png" Visibility="Collapsed"/>

<Image x:Name="Raisins" Height="373" Width="370" Canvas.Left="15" Canvas.Top="10" Source="Cookie_Images/Raisins.png" Visibility="Collapsed"/>

<Image x:Name="Pecans" Height="313" Width="302" Canvas.Left="56" Canvas.Top="56" Source="Cookie_Images/Pecans.png" Visibility="Collapsed"/>

<Image x:Name="Almonds" Height="286" Width="333" Canvas.Left="14" Canvas.Top="59" Source="Cookie_Images/Almonds.png" Visibility="Collapsed"/>

<Image x:Name="WhiteChocolateChips" Height="351" Width="353" Canvas.Left="18" Canvas.Top="45" Source="Cookie_Images/White Chocolate Chips.png" Visibility="Collapsed"/>

<Image x:Name="SemisweetChocolateChips" Height="400" Width="400" Canvas.Left="0" Canvas.Top="0" Source="Cookie_Images/Dark Chocolate Chips.png" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">

</Image>

<Image x:Name="MilkChocolateChips" Height="351" Width="380" Canvas.Left="7" Canvas.Top="45" Source="Cookie_Images/Milk Chocolate Chips.png" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">

</Image>

<Image x:Name="MacadamiaNuts" Height="377" Width="354" Canvas.Left="38" Canvas.Top="12" Source="Cookie_Images/Macadamia Nuts.png" Visibility="Collapsed"/>

<Image x:Name="DarkChocolateChunks" Height="546" Width="456" Canvas.Left="-27" Canvas.Top="-88" Source="Cookie_Images/Dark Chocolate Chunks.png" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">

</Image>

<Image x:Name="MilkChocolateChunks" Height="546" Width="456" Canvas.Left="-27" Canvas.Top="-88" Source="Cookie_Images/Milk Chocolate Chunks.png" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">

</Image>

<Image x:Name="WhiteChocolateChunks" Height="546" Width="456" Canvas.Left="-27" Canvas.Top="-88" Source="Cookie_Images/White Chocolate Chunks.png" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed">

</Image>

<Image x:Name="HersheyMiniKisses" Height="134" Width="134" Canvas.Left="134" Canvas.Top="126" Source="Cookie_Images/Hershey Kiss.png" Visibility="Collapsed"/>

</Canvas>





We were careful to name the XAML elements so they could be controlled through an automated binding statement that is generated when the picture is loaded.


void CookieCanvas_Loaded(object sender, RoutedEventArgs e)
{
foreach (Image oItem in CookieRoot.Children)
{
string sName = oItem.Name;
if (string.IsNullOrEmpty(sName))
continue;
var oBinding = new Binding(sName);
oBinding.Mode = BindingMode.OneWay;
oItem.SetBinding(Button.VisibilityProperty, oBinding);
}
}

With all this binding now in place the final step is the view model.

public class CookieVM : ViewModel

{

public CookieVM(Instance oSource)

: base(oSource)

{

}

public override void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)

{

if (e.NewItems.IsNotNull())

foreach (Component oNote in e.NewItems.OfType<Component>())

NotifyPropertyChange(oNote.ClassName);



if (e.OldItems.IsNotNull())

foreach (Component oNote in e.OldItems.OfType<Component>())

NotifyPropertyChange(oNote.ClassName);

}

public Visibility Cinnamon

{

get { return DoesChildOfClassExist("Cinnamon") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility PeanutButter

{

get { return DoesChildOfClassExist("PeanutButter") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility ReesesPeanutButter

{

get { return DoesChildOfClassExist("ReesesPeanutButter") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Cocoa

{

get { return DoesChildOfClassExist("Cocoa") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Oatmeal

{

get { return DoesChildOfClassExist("Oatmeal") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Peanuts

{

get { return DoesChildOfClassExist("Peanuts") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Raisins

{

get { return DoesChildOfClassExist("Raisins") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility HersheyMiniKisses

{

get { return DoesChildOfClassExist("HersheyMiniKisses") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Pecans

{

get { return DoesChildOfClassExist("Pecans") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility Almonds

{

get { return DoesChildOfClassExist("Almonds") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility DarkChocolateChunks

{

get { return DoesChildOfClassExist("DarkChocolateChunks") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility MilkChocolateChunks

{

get { return DoesChildOfClassExist("MilkChocolateChunks") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility WhiteChocolateChunks

{

get { return DoesChildOfClassExist("WhiteChocolateChunks") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility WhiteChocolateChips

{

get { return DoesChildOfClassExist("WhiteChocolateChips") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility SemisweetChocolateChips

{

get { return DoesChildOfClassExist("SemisweetChocolateChips") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility MilkChocolateChips

{

get { return DoesChildOfClassExist("MilkChocolateChips") ? Visibility.Visible : Visibility.Collapsed; }

}

public Visibility MacadamiaNuts

{

get { return DoesChildOfClassExist("MacadamiaNuts") ? Visibility.Visible : Visibility.Collapsed; }

}
}

Saturday, August 1, 2009

Converting SketchFlow to Production

Deb: I was really excited to start working with Blend 3 with SketchFlow! I had seen videos from MIX 09 demoing SketchFlow and was disappointed it wasn't in the first release of Blend 3. Finally I was going to get a chance to try it myself.

I had a few learning pains, working with the SketchFlow Map - the documentation was a little sketchy (pardon the pun). I also had a problem getting the navigation to work right until I learned about right-clicking on the button and going to the bottom of the menu to tell it where to navigate to. Once I learned that, it was amazingly easy to setup a prototype project. I was really pleased with the overall tool; I was able to build a nice prototype in a relatively short period of time.

My disappointment has come as I try to convert this prototype to production. I hadn't read ahead in the help documentation about how to do this because I assumed it would be relatively straight-forward. Imagine my surprise when I found a series of 16 steps that had me deleting files, navigating to obscure folders in the SDK to include references, and editing code in Notepad! The best advice I received in this series of steps was Step One: backup your project. After an hour of tedious effort, I got nothing. The project wouldn't run.

So I googled 'converting sketchflow to production' and tapped into a conversation within the Silverlight community about just how ready for primetime SketchFlow really is. Some people are happy to have such a powerful prototyping tool at their disposal, but say that when you are ready to build the application for real you will need to build it from scratch. Others range from disappointment to outrage, feeling Microsoft rushed Sketchflow out before it was really finished, not taking it through the final, critical step of conversion to production.

Me, I've turned my prototype project over to Steve, the Developer, to see how much he can convert and how much effort is required to convert it. We will let you know in a later post what we learn.

Meanwhile, I will be rebuilding the prototype from scratch, as a new project. I will also investigate getting access to the 'sketchy styles' from a normal Silverlight project. It seems to me that much of the value of SketchFlow would be delivered by the styles alone. Now if creating navigation was only as easy in a regular Silverlight project..........

Thursday, July 16, 2009

Autosizing of Grids, Canvasses and StackPanels

Deb: Moving from a relatively static environment, like Photoshop, to a dynamic environment like Silverlight/Blend, requires learning about autosizing and how visuals will behave when the browser is resized. One of the most challenging things for me to learn was the differences in behaviors between grids, canvasses and stackpanels.

I started with grids, the workhorse of the layout panels, and I got comfortable with setting the height and width to 'auto', and the alignment to stretch, and setting the margins to achieve the effect I was looking for. I learned how to set column and row sizes, locking certain ones and leaving others to size dynamically as the space changed.

I moved on to canvasses, learning how to place objects on the panel in a different way, but the autosizing aspect of the layout panel worked the same as the grid. I figured I had this dynamic sizing thing figured out. Then I got cocky and started sticking stackpanels into my grids, and suddenly things weren't working the way I expected. This video explains why:

I am not a developer, but I do have a strong intuitive understanding of hierarchies and trees. I had developed a mental model that said that if I picked 'auto' and 'stretch', my object would size to match the parent it was embedded in. Working with stackpanels forced me to reevaluate my mental model, to acknowledge that sometimes the sizing was driven by the children embedded in the object, and margins - as seen in the video - seem to be able to refer to both (in the example, the top and left margins are relative to the parent canvas but the right and bottom margins are relative to the 'children' buttons).

This is where trial and error has led me. If there is an explanation for these behaviors, a simplifying principle that can be applied in all cases, I would love to learn it -- I really like to understand why things are the way they are. Post a comment and let me know what you think!

Tuesday, July 14, 2009

The Designer's Perspective: Working with Silverlight and Expression Blend

Deb: For too long now, I've been sitting on the sidelines, content to edit Steve's posts. But it's time to start representing the designer's viewpoint when it comes to using Silverlight 3 and Expression Blend 3.

I was first attracted to Silverlight for two reasons: 1) visualization is very important to me and Silverlight lets me design some very compelling visualizations, and 2) Expression Blend promised me significantly more autonomy, and the ability to do whatever I could imagine without relying on a developer to translate my vision for me.

While I haven't become as autonomous as I would like, Blend keeps improving and for the most part, Blend 3 is a joy to work with. I have my moments of frustration, sure, but they are more than offset by the power and independence I've been given. The goal of my posts will be to reduce the frustration factor even further for fellow designers.

I can summarize my attitude toward XAML by saying this: in general, the only legitimate reason for me to go to the XAML is to finetune the sizing of rows and columns. Other than that, I shouldn't need to even look at it. I think this should be the ultimate test of Blend's ability to meet the needs of designers: no XAML coding required.

The point of view I represent is that of someone who has graphic arts training, who is adept at Adobe tools such as Photoshop, who is an extremely heavy user of the Internet, but who knows nothing about C# or .NET. Perhaps it may be difficult for some readers to understand someone with this background, but there are a lot of us out here. There are many things that may be obvious to a developer that can only be painfully learned through trial and error by a designer. Given the relative 'youth' of the Silverlight tools and their accompanying documentation (sparse), only the Internet, powerful search engines and the sharing of the Silverlight community make solving the problems we confront relatively painless. And it always helps to know that the pain of being an early adopter of Silverlight will be compensated for by the advantages that come from being among the first to learn these skills.

Saturday, July 4, 2009

Learning RIA Services: It's Great to be a Silverlight Developer

I have built WCF integrations to SQL Server as part of building Silverlight applications. Having created the basic elements of a CRUD (Create, Read, Update, Delete) using WCF (see Tim Heuer's blog on how to do this ), I had to ask myself if there wasn't a way to achieve the same result that required less code.

During MIX09 I saw Brad Adams' talks on .NET RIA Services (watch Brad Adams talk). On 3 separate occasions I worked through these examples until I began to understand how all the parts fit together. My basic feeling was that although these services are very powerful, they made a lot of assumptions about how I wanted to collect and consume the data. Too much magic going on behind the scenes for my purposes. Using the beta release of RIA Services, according to all the demos I could find on line, there was no way to loop through the returned records without binding it to the control.

The Problem Statement

I wanted to find out what I was doing wrong. Is there a way to just loop over the records returned from RIA services without binding to a control? I asked the question on Stack Overflow and in the Silverlight forums.




The Community to the Rescue

If I knew the answer, I would have asked a better question. Isn't that always the case? The members of the developer community offered answers to my ill-formed question:



No one gave me the exact answer. There was no code provided that I could just cut and paste, but I got great response in hours and their insight led me to the answer I was looking for:



Not long after I starting working on this problem, Silverlight 3 was released. RIA services have changed and I have not had time to investigate, but once I do I will add a new post.

It is Great to be a Silverlight Developer

I have been writing software since I was 18; I would have started sooner if I had access to a computer. Looking back over my 30+ years of programming, I am now having more fun than ever, and I think it is because of the times we live in -- Silverlight, the Internet, and the community of people who use them both. Silverlight has turned web applications into a rich and now, with OOB, sometimes even unconnected experience. Today's development culture is one of generosity and sharing. I am in contact with people around the world, Silverlight gurus and novices alike, and they all love to share. You get the sense that we are all looking to see how much we can accomplish together with Silverlight.

Friday, July 3, 2009

Bing Maps Silverlight Control Part 5: Calculating Distance

My dad was the first person to show me how to measure distances on a map using a pair of dividers and the scale printed on the map key. There is a much better way to do this using the Bing Maps Silverlight control -- it just takes a little programming and finding the right equation.



Here is the Bobcat Video I told you about:



Back to Programming...

Here is how you calculate the distance between points on the earth. You also need to know EarthRadiusInMiles = 3956.0;


/// <summary>
/// Calculate the distance between two geocodes. Defaults to using Miles.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2)
{
return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
}
/// <summary>
/// Calculate the distance between two geocodes.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m)
{
double radius = GeoCodeCalc.EarthRadiusInMiles;
if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
return radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0)))));
}

I created a Marker class to mark the end points of the distance calculation. To show the user that they are in distance calculation mode, I have also changed the cursor on the map control. In this case, I alternate between the arrow and the pointing finger.

PointsOfInterest m_oMarkers = new PointsOfInterest();

void cbMeasure_Checked(object sender, RoutedEventArgs e)
{
Map1.Cursor = Cursors.Hand;
m_oMarkers.Clear();
}
void cbMeasure_Unchecked(object sender, RoutedEventArgs e)
{
Map1.Cursor = Cursors.Arrow;
if ( m_oMarkers.Count > 1 )
AddLine(m_oMarkers,.5);
}

The code for collecting the user's selection of points is here:


void Map1_MouseClick(object sender, MapMouseEventArgs e)
{
var oLocation = Map1.ViewportPointToLocation(e.ViewportPoint);

PointOfInterest oPOI = null;
if (cbMeasure.IsChecked == true)
{
oPOI = new Marker() { Loc = oLocation };
m_oMarkers.Add(oPOI);
}
else
{
oPOI = new PointOfInterest() { Loc = oLocation };
m_oList.Add(oPOI);
}

RenderPoint(oPOI);

if (cbDraw.IsChecked == true)
try
{
double dRadius = double.Parse(txtRadius.Text);
AddCircle(oLocation, dRadius, .5);
}
catch( Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Using a polyline and a tool tip is great way to report the distance:


double DistanceInMiles(LocationCollection oLocs)
{
double dDistance = 0.0;
for (int i = 0; i < oLocs.Count() - 1; i++)
dDistance += DistanceInMiles(oLocs[i], oLocs[i + 1]);

return dDistance;
}

double DistanceInMiles(Location Loc1, Location Loc2)
{
double dMiles = GeoCodeCalc.CalcDistance(Loc1.Latitude, Loc1.Longitude, Loc2.Latitude, Loc2.Longitude);
return dMiles;
}

LocationCollection RenderLine(List<PointOfInterest> oList)
{

var oPOIs = (from oPOI in oList
where oPOI is Marker
select oPOI).ToList<PointOfInterest>();

var oLocs = new LocationCollection();
foreach (var oPOI in oPOIs)
oLocs.Add(oPOI.Loc);

return oLocs;
}


void AddLine(List<PointOfInterest> oList, double dOpacity)
{
MapPolyline polyline = new MapPolyline();
polyline.Stroke = new SolidColorBrush(Colors.Red);
polyline.StrokeThickness = 1;
polyline.Opacity = dOpacity;

//this works in miles
LocationCollection oLocs = RenderLine(oList);
polyline.Locations = oLocs;
Map1.AddChild(polyline);

double dDist = DistanceInMiles(oLocs);

ToolTipService.SetToolTip(polyline, string.Format("{0:0.0} mi \n {1:0.00} yd", dDist, dDist * 5280.0 / 3.0));
}