In Response To DNR 476

dotnetrocks

Dot Net Rocks is certainly one of the most influential and valuable podcasts for .NET developers and their recent show (#476) was a compelling discussion about whether software development has become too complex. Recorded at DevLink in Nashville, the panel members included Billy Hollis, Kathleen Dollard, Jim Holmes and Josh Holmes (bios on the DNR page).

I found myself frustrated listening to this discussion, however because the consensus appeared to be that as an industry we were letting things get too complex for the hobbyist user* to get started programming in the way that was much easier a generation earlier. In fact, it seemed that many felt that Microsoft in particular has befuddled many a professional programmer by having so many technologies.

*Hobbyist was defined as a person whose first job is not programming, e.g., a doctor writing a program to make his practice run more smoothly.

[As an aside, I can’t imagine a company like Microsoft making everyone happy about this. There appear to be 3 possible paths:

  1. if you don’t advance you are neglecting the needs of developers
  2. if you advance and deprecate the old technology you are abandoning people
  3. if you advance and don’t deprecate, you end up with a lot of concurrent technologies. 

It was argued that Microsoft (and others) are pushing new technology for revenue, but my question is: would you rather write your next product using Silverlight/WPF and C# or using C and your original copy of Petzold?  For me, the question you have to ask is whether the new technology is better enough to overcome the cost of learning the new technology. For me the answer has been ‘yes’ but I know a whole lot of folks who have started to say ‘no – I’ll stick with what I know.’ ]

How Can We Reduce The Cost Of Entry?

My frustration was not with the panel; I think they covered the issue extremely well, especially with the corners filled in by the extraordinary comments from the audience. My frustration was that there seemed to be a consensus that it was very hard to find what you need and learn how to use it. Clearly we need to be doing a lot more to direct folks to the available material; and we need to broaden the material.

This is an issue I’ve been struggling with for a very long time.  A number of my books (e.g., Programming .NET 3.5), my Getting Started posts, were attempts to create a “drop line” approach to learning the newest technologies. (By drop-line, I mean the most direct and least complex approach.)

I think we can agree that we do prefer the new technologies (e.g., Silverlight, .NET, etc) to the old (COM?!). On the other hand, I certainly understand why a programmer trying to get started with .NET may well be overwhelmed by the plethora of choices (data access being the canonical example). 

Now, clearly Microsoft is working on this problem on a dozen levels: redesigning our sites, providing Getting Started pages, videos, tutorials, seminars, white papers, etc. etc. And while this is working in many ways, you can’t listen to the panel and not think more has to be done.

So, I offer four ideas of things we (as an industry) need:

  1. A gizmo to help developers figure out what technology they need to accomplish their task. As a start, that gizmo could easily be a Silverlight application that not only asks you questions and makes recommendations, but tells you why it has recommended that technology as opposed to another: “For your data retrieval we recommend you use Entity Frameworks because your project needs yada yada yada.  The realistic alternatives include LinqToSql which can do blah but won’t meet your need to do yada yada. You could also use Data Services which will provide blah blah, but won’t give you yada yada.”  [This might be a good project for AgOpenSource]
  2. An index of all the learning material that is highly searchable
  3. The ability to go to one web page that has everything you need to get started with your technologies of choice.  This goes back to the first idea. Once the user reviews the recommendations she picks the technologies (check boxes?) and then clicks a button that assembles a web page that has links to the latest version of each of the required tools.
  4. Examples of creating applications from design to delivery that discuss these choices, and demonstrate every aspect from obtaining the tools to implementing the application. As a first attempt, I offer the Turing Project. Many others have done this, many more will, and we’re learning more and more about how to do it in a way that greases the skids.

There is much more to say on this topic, but I’m very grateful to DNR for starting the discussion. I look forward to reading your comments.

Posted in z Silverlight Archives | Comments Off on In Response To DNR 476

Pie Chart Easy AS….

I wanted to add an animated pie chart to my previous post.  The samples from the Toolkit are terrific, but sometimes it is difficult to find the easiest, most cookbook like process; so for those of you who might want to do the same, here is an annotated walk-through of creating this animated pie chart:

I began by opening Visual Studio and creating a new Silverlight Application, and saying no to the offer to create a Web application.

The UI, created in Page.xaml consists of the header and the Chart, placed in a Grid. You can easily do this in Blend or, in this case the layout is so simple, I hard-coded it in Xaml:

<UserControl 
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;
assembly=System.Windows.Controls.DataVisualization.Toolkit"

x:Class="Pi.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="350" Height="350">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>



<TextBlock Text="Division of Effort Among Activities"
Margin="20,10,0,0"
Grid.Row="0"
FontFamily="Georgia"
FontSize="18"
Foreground="Blue" />

<chartingToolkit:Chart x:Name="ActivityChart"
Margin="20"
Grid.Row="1">
<chartingToolkit:Chart.Series>
<chartingToolkit:PieSeries Title="Fall Activity"
IndependentValueBinding="{Binding Name}"
DependentValueBinding="{Binding Value}" />
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>

    </Grid>
</UserControl>

The key Xaml here is the Chart control which contains a Series which in turn contains a PieSeries. The PieSeries has an Independent and a Dependent set of values, as explained in some detail here.

To have a set of values to bind to, I created a data class that I named Activity. The Activity class has three properties of interest:

  • Name – used to hold the independent value
  • Value – used to hold the dependent value
  • Activities – returns a list of Activity objects
   1: using System;

   2: using System.Collections.Generic;

   3:  

   4: namespace Pi

   5: {

   6:   public class Activity

   7:   {

   8:     public string Name { get; set; }

   9:     public double Value { get; set; }

  10:     

  11:     // static property to retrieve 

  12:     // List of Activity objects

  13:     public static List<Activity> Activities

  14:     {

  15:       get

  16:       {

  17:         // value of 5 and names of activities are hard coded

  18:         // Generalizing is left as an exercise for the ambitious

  19:         var percentages = FillPercentages(5);  

  20:         var activitiesList = new List<Activity>()

  21:              {

  22:                new Activity() {Name = "RiaServices", Value = percentages[0]},

  23:                new Activity() {Name = "DataGrid", Value = percentages[1]},

  24:                new Activity() {Name = "Behaviors", Value = percentages[2]},

  25:                new Activity() {Name = "VSM", Value = percentages[3]},

  26:                new Activity() {Name = "SampleData", Value = percentages[4]}

  27:              };

  28:         return activitiesList;

  29:       }

  30:     }

  31:  

  32:     // fill List<Double> with n doubles that sum to 1.0

  33:     // where n = numDoubles

  34:     private static List<Double> FillPercentages(int numDoubles)

  35:     {

  36:       var pctgs = new List< Double >();

  37:       var r = new Random();

  38:       double total = 0.0;

  39:       

  40:       for (int i = 0; i < numDoubles-1;)

  41:       {

  42:  

  43:         double val = r.NextDouble();

  44:         if ( val + total < 1.0)

  45:         {

  46:           pctgs.Add(val);

  47:           ++i;

  48:         }

  49:       }

  50:       pctgs.Add( 1.0 - total );  // final value

  51:       return pctgs;

  52:     } 

  53:  

  54:   }   // end class

  55: }     // end namespace

On line 13 we start the definition of the Activities property (only a get accessor is implemented)

On line 19 we delegate to a helper method generating 5 random values between 0 and 1 that together sum to 1. These will be treated as the relative percentages reflected in the pie chart.

Lines 20-27 fill our five hard-coded activities with the generated percentages and on line 28 we return the List of Activity objects we just created.

The code-behind for MainPage uses a dispatch timer to call a helper method FillPie every 4 seconds.

The helper method sets the ItemSource property on the PieSeries to whatever is returned by the static Activities property of the Activity class. Retrieving that property causes the percentages to be regenerated, and the chart is redrawn.

 

   1: using System;

   2: using System.Windows.Controls;

   3: using System.Windows.Controls.DataVisualization.Charting;

   4: using System.Windows.Threading;

   5:  

   6: namespace Pi

   7: {

   8:   public partial class MainPage : UserControl

   9:   {

  10:     public MainPage()

  11:     {

  12:       InitializeComponent();

  13:       Animate();

  14:     }

  15:  

  16:     private void Animate()

  17:     {

  18:       var timer = new DispatcherTimer();

  19:       timer.Start();  // Run once for display

  20:       // lambda syntax - same as

  21:       // timer.Tick +=new EventHandler(FillPie);

  22:       // but then you'd need FillPie to take an object and event args

  23:       timer.Tick +=

  24:           ( ( s, args ) => FillPie() );  // every tick call FillPie

  25:  

  26:       // http://msdn.microsoft.com/en-us/library/cc316852.aspx

  27:       timer.Interval = new TimeSpan( 0, 0, 4 ); // 4 seconds

  28:       timer.Start();

  29:     }

  30:  

  31:  

  32:     private void FillPie()

  33:     {

  34:       var cs = ActivityChart.Series[0] as PieSeries;

  35:       if ( cs != null )

  36:       {

  37:         // generating the data is handled by the static property

  38:         cs.ItemsSource = Activity.Activities;

  39:       }

  40:       else

  41:       {

  42:         throw new InvalidCastException( "Expected Series[0] to be a column" );

  43:       }  // end else

  44:     }    // end method

  45:   }      // end class

  46: }        // end namespace

Notice that on lines 23 and 24 we register the FillPie method with the event using lambda notation; this makes short work of using a method that does not happen to need the standard arguments (object, eventArgs).

Timer.Start is called on line 19 to cause an immediate drawing of the pie, and then again on line 28 to implement the new time interval.

Posted in z Silverlight Archives | Comments Off on Pie Chart Easy AS….

OK, So Now Where’s Jesse??

Like many other developers before me, I’ve been hit with a pretty bad case of Carpal Tunnel.  Expected recovery is 7-10 days (we hope, we hope), so I won’t be blogging a lot or creating many videos until the end of the month. (Carpal Tip: while a track ball is not much better than a mouse for the affected hand, it is much easier to control with your non-dominant (submissive??) hand.)

I do have a few things to let you know about, however…

Turing Project Focus for September

During the next six weeks the Turing Project will provide the focus and opportunity to explore a number of technologies, from data to UX. Exploring these topics will spin out a number of stand-alone (but related) videos. The principal topics for the coming weeks include:

  • Data Entity Framework
  • RIA Services Framework
  • DataGrid Control
  • Behaviors
  • Visual State Manager
  • Sample Data

Though, the amount of time spent on each technology will vary as the project evolves, as shown in this full color sophisticated predictive simulation:

[ A walkthrough of this very simple Silverlight application can be found here

Brief Interlude As We Change Topics…

Blog Audience Targeting – Your Opinion Requested.

I was told recently that my blog seems to target the novice and intermediate Silverlight programmer. That sounds right to me, but the question is whether I should broaden my approach or solidify behind that definition of what this blog is all about.

Silverlight Geek (More Signal : Less Noise)
Vital Information For Novice and Intermediate Silverlight Programmers

What do you think? 

Note, I would define intermediate vs. advanced as follows: in the bullet list of topics I’ll be focusing on (above), there would be at least one or two topics an intermediate Silverlight programmer hasn’t fully explored yet.

Do You Subscribe?

Let’s assume for the moment that when a developer subscribes to a blog that developer is saying “yes, the information here is valuable enough to subscribe to and at least scan the feed on a regular basis…” If you don’t subscribe to this blog, or know Silverlight developers who don’t, what do you think I might change to enhance its utility?  Please reply in the comments and note that I do take that kind of feedback extremely seriously. [Or, save time, and click here to subscribe!]

Twitter

Expect a surge in Tweets in coming weeks as a number of projects kick into gear.  To follow me on Twitter, click here. To learn about Twitter, click here.

Posted in z Silverlight Archives | Comments Off on OK, So Now Where’s Jesse??

3 New Podcasts on Silverlight 3

 

SparklingClientLogo

This month I had the opportunity to be on Sparkling Client three times to talk about Silverlight 3 features

Posted in z Silverlight Archives | Comments Off on 3 New Podcasts on Silverlight 3

Hey! Where’s Jesse?

I will be on vacation starting today, and returning on Monday, August 24. During that time I will be in Maine but I will be writing Programming Silverlight 4, studying RIA Services in depth and otherwise having a geek vacation. Project Turing, the Mini-Tutorials and a series of videos are slated for the weeks following my return (though I will be on vacation again August 28-31).

To bring you up to date on project status:

 

September

 

September should be very exciting as I’ll be in Redmond from September 14 through the 17th, with Silverlight Firestarter slated for September 17th and a presentation at the .NET Developers Association of Redmond on Monday September 14th (registration free, but required).

FireStarter NETRedmond

Posted in z Silverlight Archives | Comments Off on Hey! Where’s Jesse?

Linq For Silverlight Developers

 

MiniTutorialLogo

 

ProjectTuringLogo

 Turing Project Page: [Novice: 7]    FAQ    Table of Contents

  What is this and where do I start?

Special Note: This posting introduces a new element in the series: definitions for terms that may not be familiar. Clicking on the link will bring you to the definition page where I will provide a very short explanation of the term and refer you to other postings, videos or books.  In the first sentence under The Blog Class, below, I use the term automatic properties and it is shown as a link. Clicking the link will ring you  to the Definition page, where you will find an entry for automatic properties.

Linq – More Powerful Than A Locomotive

Linq was introduced into .NET with .NET 3.5, and is fully supported in C# 3 and VB9.  It has rapidly become the database language of choice among .NET developers, providing an efficient and “natural” alternative to making calls out to stored procedures or to T-SQL.

You can use Linq for retrieving, updating, removing or adding data to and from SQL-server or any database or from any other collection such as a list<T>, an XML file, etc. An important benefit of this is that the same logic used to retrieve specified data from an in-memory collection may be applied to your data storage layer. That is, rather than using an enumerator on your list but ADO.NET on your database, you can use a Linq query against both.

The following example violates my normal practice of keeping things as simple as possible; I’m doing so consciously to illustrate a fully developed in-memory Linq example that I will walk through in detail. The next posting will demonstrate Linq To SQL, and will give us an opportunity to explore a bit more of Linq.

Let’s start by declaring a class that we can then create a collection of:

   1: using System.Collections.Generic;

   2:  

   3: namespace Linq1

   4: {

   5:   public class Blog

   6:   {

   7:     public string BlogName { get; private set; }

   8:     public string BlogOwner { get; private set; }

   9:     public string BlogUrl { get; private set; }

  10:     public int BlogRanking { get; private set; }

  11:  

  12:     public override string ToString()

  13:     {

  14:       return string.Format(

  15:         "{0} ( {1} ), ranked {2} is owned by {3}",

  16:         BlogName, BlogUrl, BlogRanking, BlogOwner );

  17:     }

  18:   } // end class

  19: }   // end namespace

  20:  

(full source code will be available, so I’m going to indulge in using line numbers)

The Blog Class

The class consists of just four properties (using C#’s automatic properties) and an override of ToString to make it easy to examine what we have. Each instance (blog)  is assigned a ranking so that I can order the blogs in favorite to least favorite.

I will want to generate a collection of these objects, and since I’ll only want to do so for debugging and testing, I’ll incorporate a method to generate that data as a static member of the class (the following code is inserted after the override of ToString and before the brace closing the class:

   1: public static List<Blog> GenerateBlogs()

   2: {

   3:   var blogs = new List<Blog>

   4:               {

   5:                 new Blog

   6:                 {

   7:                   BlogName = "Silverlight Geek",

   8:                   BlogOwner = "Jesse Liberty",

   9:                   BlogUrl = "http://www.SilverlightGeek.me",

  10:                   BlogRanking = 5

  11:                 },

  12:                 new Blog

  13:                 {

  14:                   BlogName = "Mike Harsh's Blog",

  15:                   BlogOwner = "Mike Harsh",

  16:                   BlogUrl = "http://blogs.msdn.com/mharsh/",

  17:                   BlogRanking = 4

  18:                 },

  19:                 new Blog

  20:                 {

  21:                   BlogName = "Brad Abrams",

  22:                   BlogOwner = "Brad Abrams",

  23:                   BlogUrl = "http://blogs.msdn.com/brada",

  24:                   BlogRanking = 3

  25:                 },

  26:                 new Blog

  27:                 {

  28:                   BlogName = "Computer Zen",

  29:                   BlogOwner = "Scott Hanselman",

  30:                   BlogUrl = "http://blogs.msdn.com/hanselman.com/",

  31:                   BlogRanking = 2

  32:                 },

  33:                 new Blog

  34:                 {

  35:                   BlogName = "Scott Gu's Blog",

  36:                   BlogOwner = "Scott Guthrie",

  37:                   BlogUrl = "http://weblogs.asp.net/scottgu",

  38:                   BlogRanking = 1

  39:                 }

  40:               }; // end initialization of collection

  41:   return blogs;

  42: } // end static method

On line 3 we declare blogs using the new var keyword (implicit type) and assign to blogs a new List<Blog>, which we proceed to initialize using object initialization  The net effect is that we end with a list of five blogs, fully initialized, which we can return to any method that needs such a list.

Let’s look at the UI now, which will serve as a spec for building the (simple) application, allowing us to take a look at how Linq can make querying for a subset of the blogs easier (this is a posting about Linq!)

— live demo —

— end live demo —

The rankings used are entirely arbitrary and used only as examples; your mileage may vary, packed by weight not volume.

Notice that you can use the spinner to choose to list between 1 and 5 blogs and as you’ll see they are listed in “rank” order.

The Xaml Behind the Display

The data is of course hard wired, but let’s look at how the data gets from the Blogs class into the data grid.

Step 1 is to create the data grid, the prompt and the spinner.

The trick to using a datagrid is to drag it from the toolbox onto the markup so that Visual Studio will include the right libraries and create the right namespace for you. You can of course, add the reference yourself,

ReferencesForLinq

and then add a namespace/alias at the top of your file

xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

In any case, with that in place, you are ready to add the DataGrid which you can do in the mark up or programmatically. I’ll do so in the markup, telling the DataGrid not to generate the columns, but rather to use the columns I’ll describe:

   1: <data:DataGrid AutoGenerateColumns="False"

   2:                x:Name="BlogGrid"

   3:                Grid.Column="0"

   4:                Grid.Row="1"

   5:                Grid.ColumnSpan="3"

   6:                RowBackground="AntiqueWhite"

   7:                AlternatingRowBackground="LightGreen"

   8:                >

   9:     <data:DataGrid.Columns>

  10:         <data:DataGridTextColumn Header="Blog"

  11:                                  Width="SizeToCells"

  12:                                  Binding="{Binding BlogName}"

  13:                                  FontFamily="Georgia"

  14:                                  FontSize="18" />

  15:         <data:DataGridTextColumn Header="Owner"

  16:                                  Width="SizeToCells"

  17:                                  Binding="{Binding BlogOwner}"

  18:                                  FontFamily="Georgia"

  19:                                  FontSize="18" />

  20:         <data:DataGridTextColumn Header="URL"

  21:                                  Width="Auto"

  22:                                  Binding="{Binding BlogUrl}"

  23:                                  FontFamily="Georgia"

  24:                                  FontSize="18" /> 

  25:     </data:DataGrid.Columns>

  26: </data:DataGrid>

Note that each column is bound to a property in the Blog object; we’ll get the collection of Blog objects in the code behind. Before we do, though, let’s be sure to add the prompt and spinner for the top row:

   1: <TextBlock Text="How many?"

   2:            Grid.Column="0"

   3:            Grid.Row="0"

   4:            FontSize="14"

   5:            FontFamily="Georgia"

   6:            VerticalAlignment="Bottom"

   7:            HorizontalAlignment="Right"

   8:            Margin="5"/>

   9: <inputToolkit:NumericUpDown x:Name="num"

  10:      VerticalAlignment="Bottom"

  11:      HorizontalAlignment="Left"

  12:      Margin="5"

  13:      Width="50"

  14:      DecimalPlaces="0"

  15:      Minimum="1"

  16:      Value="1"

  17:      Grid.Row="0"

  18:      Grid.Column="1" />

Notice that the NumericUpDown comes from the Toolkit. You can read all about the Silverlight Toolkit here, and we have videos on Toolkit controls here.  The NumericUpDown control is handsomely demonstrated in the Toolkit Samples

We make fairly simple use of it, setting its minimum value and its current value to 1.

Implementing The Event Handlers

Turning to the code behind we begin by creating a private member, blogs of type List<Blog>.

In the constructor, we assign to that member variable the result of calling the static method we created in the Blog class. Being extremely careful to make sure that we have data to work with, we then check to ensure that the member variable blogs is no longer null. (lines 8-11)

   1: public partial class MainPage

   2:  {

   3:    private readonly List< Blog > blogs;

   4:    public MainPage()

   5:    {

   6:      InitializeComponent();

   7:      blogs = Blog.GenerateBlogs();

   8:      if ( blogs == null)

   9:      {

  10:        throw new ArgumentNullException( "GenerateBlogs returned null!" );

  11:      }

  12:      num.Maximum = blogs.Count;

  13:      num.ValueChanged += ( (sender, e) => NumValueChanged(sender, e) );

  14:      SetGrid();

  15:    }

  On line 12 we examine how many entries there are in the List<Blog> and set the Maximum value for the NumericUpDown to that number.

We set an event handler for when the user clicks on the NumericUpDown. The syntax may strike you as a bit odd; this is a Lamda Expression (an integral part of Linq as it turns out) and says that we are registering an event whose delegate will match a method that takes two objects and given those two objects will return the result of invoking NumValueChanged and passing in those objects.

Finally, we call the private method SetGrid, which would normally be the contents of the method NumValueChanged, but is factored out so that we can also call it from the constructor.

   1: void NumValueChanged( object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e )

   2: {

   3:   SetGrid();

   4: }

The incredibly astute reader will have noticed that we’ve not assigned an ItemsSource for the DataGrid. That is done on purpose as we’re going to create the ItemsSource out of a selected subset of the member collection blogs.  All of that work happens in SetGrid:

Linq (At Last!)

The job of SetGrid is to retrieve the value from the NumericUpDown and to retrieve that many Blog entries from the collection blogs, based on the BlogRanking that we previously assigned to each entry.

   1: private void SetGrid() 

   2: {

   3:   var result =

   4:     from eachBlog in blogs

   5:     where eachBlog.BlogRanking <= num.Value

   6:     select eachBlog;

   7:  

   8:   BlogGrid.ItemsSource = result;

   9: }

It accomplishes this task by using a Linq query against blogs, the result of which is placed in the anonymous type variable result.  The actual type of that variable, however, is determined by what the Linq statement returns, and that is an object of type IEnumerable<Blog>. 

A quick check of the documentation will show that the ItemsSource property for the DataGrid is looking for an IEnumerable,

ItemsSource

And the last line of SetGrid assigns the variable result to the ItemsSource property, causing the DataGrid to be populated.

Parsing The Linq Query

The Linq query will be quite familiar to anyone who has worked with SQL; the most noticeable difference is that the select statement comes at the end rather than the beginning.

We begin with from eachBlog in blogs  — blogs of course is our collection obtained in the constructor, and eachBlog is a temporary variable of type Blog that is created implicitly just by using it in this way (there is no earlier statement such as

Blog eachBlog;   // not needed

The where statement filters for all the entries where the BlogRanking property of the Blog is less than or equal to the Value currently stored in the NumericUpDown. Thus, if the user sets the NumericUpDown to 3, we’ll get the entries whose ranking (that is, whose property BlogRanking) is 1,2 and 3, as set in the initialization of the Blog entries in the static method.

The select statement adds each of these entries to the IEnumerable result and then, finally result is set as the ItemsSource for the DataGrid. 

The select clause is known by database cognoscenti as the projection.  

In order to get into more advanced aspects of Linq it will be helpful to have a more complex data source; the next posting will take a look at Linq to Sql.

Novice Previous: Database Design Next: Linq To Sql
Advanced Previous: Database Design Next: Linq To Sql
Posted in z Silverlight Archives | Tagged | 2 Comments

From DB to DataGrid – So Many Choices!

MiniTutorialLogo

ProjectTuringLogo

 Turing Project Page: [Novice: 6, Advanced: 4]    FAQ    Table of Contents

  What is this and where do I start?

In the previous entry, we created the design for the database. Over the next few postings, we’ll be working with that Data in five distinct ways:

  1. Gather data from the bloggers about themselves, their blog and each entry
  2. Store that data in a database
  3. Extract that data as needed from the database
  4. Transmit the data to a Silverlight application
  5. Display the data in a Silverlight application

Of these five, we’ve made simplifying interim decisions about numbers 1,2 and 5:

Gathering Data

We’ve decided, for now, to gather the data from the bloggers by using a form, though over time we’ll want to migrate to other, better options.

My longer term plan for data entry is to have the blogger “register,” providing us with all the necessary one-time information (e.g., Blog name, URL, etc.) and choose a tag that will indicate that an entry should be in the database. We will then watch the rss feed for that blog, looking for the chosen tag, and we’ll list each tagged entry.

Storing Data

We’ve also decided for now to use SQL Server as our database, though the truth is we can use almost any data store.

Displaying The Data

Finally, we’ve decided to hold off on the Display decisions for now, making do with a very simple data grid  just to check that we’re getting the data we think we’re getting.

Extracting and Transmitting Data – Too Many Choices?

Amadeus

 

Emperor Joseph II: My dear young man, don’t take it too hard.
Your work is ingenious. It’s quality work.
And there are simply too many notes, that’s all.
Just cut a few and it will be perfect.

Mozart: Which few did you have in mind, Majesty?
Amadeus 1984

 

It is possible to complain that Microsoft has provided too many choices for retrieving and transmitting data. Over the past decade we’ve seen RDO, DAO, ADO, COM, DCOM,  ADO.Net, ADO.NET Data Services, Entity Framework, LINQ, ASMX, WCF, RIA Services…

But that would be querulous; after all, each new option (with the possible exception of COM!) has achieved a higher level of abstraction for the programmer; handling more of the plumbing and requiring less repeated, error prone and annoying code in our application.  But yes, it is hard to keep up.

One suggestion that I’ve found helpful,  is to separate the Data Access Layer (DAL), the transport layer and the Business layer, when deciding on which technologies to employ.  That doesn’t necessarily mean three separate sets of classes, but it does mean three distinct concepts. The picture I keep in my head looks (crudely) like this:

WorkFlow

Data Access Layer

For the DAL layer your realistic choices today are

  • ADO.NET
  • Linq to Sql
  • Entity Frameworks

 

ADO.NET Is Not ADO

ADO at one time stood for ActiveX Data Objects, and the original ADOwas the successor to Remote Data Objects (RDO) and Data Access Objects (DAO).  All of this is back in the 20th Century, and is of interest only to those of us who lived through the Dark Ages (the time of COM).

ADO.NET is not named thus because it is the illegitimate child of ADO in any real technical evolutionary sense, but rather to send the message that it is the .NET replacement for ADO; and it has been a hearty replacement indeed.

Impedance Mismatch

When electrical engineers refer to an Impedance Mismatch they mean the need to match up the input impedance of an electrical load to a fixed impedance (most often, the signal they are working with).  This became an irresistible analogy for the problem that object oriented programmers have trying to match up their object model with the relational model most often used in successful databases. (This metaphor has become so entrenched that Wikipedia’s page for Impedance mismatch lists both meanings!)

The key problem, in short, is that relational databases are very (very!) good at storing, updating and retrieving data, but they achieve their terrifying performance at the cost of insisting of thinking about data as consisting of records and fields (rows and columns). 

Entries

 blogs

 Bloggers 

While programmers have had enormous success thinking about objects and their relationships

Objects

In the case shown, the mapping from object to table appears deceptively straight forward, but as your application grows the complexity transcends the fact that properties of an object may not map to a single table: with many applications there simply isn’t an obvious way to build a given object from the provided tables without serious manipulation or compromise.

ADO.NET As A First Layer of Abstraction

ADO.NET was a great first attempt at solving this problem and made life significantly easier. That said, ADO.NET does stay pretty close to the relational model, and the objects in ADO.NET include

  • DataReader
  • DataSet
  • Connection
  • Command
  • DataAdapter
  • DataTable

and so forth.  You certainly can accomplish everything you want; and there may be times you’ll go to ADO.NET specifically because it maps so cleanly to your database, but there are alternatives today that do much of the drudge work of ADO.NET for you. 

In  a future posting, I’ll come back to this exercise and implement it with ADO.NET.

Linq To SQL

LINQ was one of the most significant additions to .NET 3.5. 

Linq to Sql is specifically designed to use LINQ to interact with SQL Server. That is both its power and its Achilles Heel as it is very coupled to the particulars of SQL Server technology.  While Linq To Sql would certainly do the job for us, I’d prefer to use something more flexible, and a bit more decoupled from the database and frankly, something with a bit more object encapsulation

On To Entity Framework

This brings us to Entity Framework; a topic worthy of a full posting, and that will be next in this series on the Advanced track; the Novice track will take a short digression to review Linq, which we’ll be using quite a bit in this project.

Novice Previous:  Data Forms Next: Linq Reviewed
Advanced Previous:  Data Forms Next: LinqToSQL
Posted in z Silverlight Archives | Tagged | Comments Off on From DB to DataGrid – So Many Choices!

DataBase Design & Creation

MiniTutorialLogo
(click on the image to see other Mini-tutorials)

ProjectTuringLogo

[Novice: Page 5, Advanced: Page 3]  FAQ  Table of Contents

 

 

 

 

This project will explore, among other things, getting data into and out of a SQL Database. In fact, we’ll explore a number of ways of doing so. To get started, however, we need to create a database that is sufficient for the project and sufficiently illustrative of working with relational databases, without being overly complex.

Fortunately, the project requirements are of about the right complexity.  Returning to the spec, (such as it is) we can see that we need to capture the following information each time an entry is made in a participating blog:

  • The name of the blog
  • The title of the entry
  • The URL of the entry
  • Info about the blogger (first name, last name, email & phone)

It would also be good to know when the blog entry was first created and when it was last modified.

Flat or Normalized?

You certainly could create a flat file that has all the information we need:

FlatFileDB

The advantage to this approach is that it is quick, easy, simple to understand. Putting in a few records, however, quickly reveals why this kind of flat-file database is now reserved for non-programmers creating simple projects such as an inventory of their music:

Even with just a few records, you can see that a great deal of data is duplicated in every record,

FlatFileDBOutput

 

This duplication can make the database very hard to maintain and subject to corruption. To prevent this, databases are ‘normalized’ – a complex subject that boils down to eliminating the duplication by factoring out common elements into separate tables and then reaching into those tables by using unique values (foreign keys).  Thus, without bogging ourselves down in db theory, we can quickly redesign this flat database into three tables:

ThreeTableDiagram

In this normalized database, each entry has only the information that is unique to the particular BlogEntry:

  • Title
  • URL
  • Date Created
  • Date Modified
  • Short Description

The entry also has the ID of the Blogger who wrote the entry and the ID of the Blog that the entry belongs to. 

A second table holds the information about each Blog, and a third table holds the information about each Blogger.  Thus, a given Bloggers first and last name, alias (email address at Microsoft.com) and phone number are entered only once for each blogger, and referenced in each entry by ID (known as a foreign key). 

The diagram also shows that the two foreign-key relationships are named

  • FK_Blog_Entries_Blogs
  • FK_BlogEntries_Bloggers

These simple names indicate that there is a foreign key relationship from BlogEntries to Blogs and another from BlogEntries to Bloggers.  The data is now much cleaner:

selectStarFromBlogs

 Bloggers

Entries

Notice that the BlogEntries table now does not duplicate the first and last name and phone number for each Blogger, but rather just refers to that Blogger’s ID. For example, entry #3

Entry3

was written by Blogger 4 (see ID in the middle image) and was placed in Blog 3 (see ID  in the top image)

Creating A Join Query (T-SQL)

You can easily write a query that recreates the complete set of information by “joining” the tables:

select BlogName, FirstName, LastName, Title, Description from BlogEntries be

join Bloggers bb on be.Blogger = bb.ID

join Blogs b on be.Blog = b.ID

This statement says to select the listed fields (it isn’t necessary to identify the table explicitly as there is no duplication). It then tells SqlServer where to find them in the “from” clause. The first table is BlogEntries which we assign a short-name of be.

We then we join to that tables the Bloggers table, but we match up the rows in BlogEntries with the Rows in Blogger where the value in BlogEtries.Blogger is equal to the ID in the table Bloggers.

You can imagine that SQL Server thus looks at the two tables and joins the matching rows, making a new (temporary) wider table:

Joined

It then looks at the Blog table and joins the Blog value to the ID in that table:

3tableJoin

Giving us the ability to create a virtual flat table without the duplicated values.

Novice Previous: Forms
Advanced Previous: Two Levels
Posted in z Silverlight Archives | Tagged | 1 Comment

Quick Bit on Turing Project

“I can’t stop smiling. This approach is great.” Happy quote of the day.   New entry today in Quick Bits about the Turing Project.

Posted in z Silverlight Archives | Comments Off on Quick Bit on Turing Project

Creating A Form – Level 100

MiniTutorialLogo
(click on the image to see other Mini-tutorials)

 

ProjectTuringLogo

Turing Page [Novice: 4]  FAQ  Table of Contents

 

 

 

 

In Novice Page 3 we were about to create a form.  Here is  the form we’ll create:

TuringBlogEntryForm

Layout Is Easiest In Expression Blend

To create this form, I’ll begin by opening Expression Blend 3 and creating a new Silverlight Application,

NewBlendProject

If you’ve not reconfigured Blend it will open with numerous panels, some tabbed, some open as shown here:

BlendDesignSurfaceSquashed

A Quick Tour of Expression Blend

BlendToolboxClosedOn the far left is the toolbar a small piece of which is shown here. Notice that some of the controls have a tiny white triangle next to them. Clicking on the triangle opens up related tools.

BlendToolboxOpen

In the second image I’ve clicked on the triangle next to button and opened a panel with controls related to button.

Next to the toolbox are a number of tabbed panels including  Projects, Assets, States and Parts, below which is the Objects and Timeline Panel 

Note that the files in the Blend project are identical to the files in a Visual Studio project and you can and will have these files open in both applications at the same time.

BlendProjectsWindow

In the center of the screen is the Design Surface otherwise known as the Art board

Also note the tiny control in the upper left corner of the Art-board that lets you switch between a grid and a canvas. Also note that surrounding the grid area (white) is a border (blue). You can use the border area to create rows and columns very quickly, as you’ll see in just a moment.

BlendGridWindow

Expression Blend allows you to work in a WYSIWYG environment, but it also produces Xaml that corresponds to everything you do on the design surface. You can switch to split mode to see both the design and the Xaml.

In fact, every visible object in Silverlight is a CLR object that can be created in three ways:

1. In Code (as you’ll see much later in the book)

2. In Xaml (the markup language that we’ll be talking about quite a bit in this chapter)

3. By Drag and Drop into the design surface.

The design surface and the Xaml are two reflections of the exact same information. Dragging a control onto the design surface generates Xaml, and modifying the Xaml will be reflected on the Design surface.

The far upper right has three tabs:  the properties window where you set the properties of any object on the design surface,  Resources and  Data.

BlendPropertiesWindow

Xaml

XAML is the markup language for Silverlight. Think of it as HTML on steroids.

Xaml is an XML markup language (and thus is highly toolable; that is, it works very well with tools like Expression Blend and Visual Studio).

Xaml is highly expressive and can be used to describe not only layout (where to place controls) and standard forms-based controls (buttons, etc.) as well as graphics (ellipses, rectangles, etc.) but can also be used to declare transformations and animations of those objects, and much more.

Creating a Form for Data Input

Our goal is to create a simple form for data input, in which users will enter information about their favorite book.

We’ll build the form using the methodology of successive approximation also known by the technical term Get it working and keep it working. To tackle this, we’ll divide the work into three stages: laying out the controls, wiring up the events, and then, in subsequent chapters, connecting the data to data objects.

Layout Panels

There are quite a number of layout panels available, though the most common are

· Panel – the abstract base class for other, more specialized panels

· Canvas – Used for absolute positioning

· Stack Panel – For stacking objects on top of or next to one another

· Tab Panel – for tabbed layouts

· Docking Panel – for docking objects to the top, bottom or sides of your panel

· Grid – Probably the most frequently used panel. The grid allows you to create rows and columns and fill each “cell” with other controls.

Visual Studio and Expression Blend create a Grid panel for you by default. A grid is very much like an HTML Table, but a bit more powerful.

Creating Rows And Columns

Let’s start in the art board in Expression. To ensure that we have a grid, first hover over the small button at the top left corner. It will tell you if you are in Grid or Canvas mode; you want Grid.

clip_image002[4]

You can now designate where you want your rows and columns. While hovering over the border a yellow line is drawn to show where your row will be created.

clip_image003

If you click, the line turns blue and the row is written to the Xaml.

clip_image004

The small open-lock symbol indicates that the rows are using relative spacing rather than absolute.

 

Looking At The Xaml Produced

To see the markup produced by drawing these lines, click on the “split” option on the small bar to the right of the art-board

clip_image005

Split mode can be a big help in relating the Xaml to the design.

SplitMode no arrows
(click on image to see larger version)

 

Creating The Rows and Putting In The Prompts

Looking at the image of the form at the top of this entry, you can see that you’ll need 11 rows. Go ahead and click on the left margin about 10 or 11 times, creating somewhat evenly spaced rows. Then move to the border on top, and click to create a pair of columns. 

As you add controls you can adjust the relative heights of each row (or the width of each column) to fit.

Start filling in the cells by adding the prompts for each row. Begin on the second row and reserve the first row for the title.

Adding Prompts

Click on TextBlock in the toolbox

PickingATextBlock

Then drag with the mouse down to create a TextBlock in the left cell of the second row. Don’t worry about size or placement, you’ll fix that in the properties window.

DraggingTextBlock

With that in place, click next to it and then turn to the Properties window.  Name the TextBlock FullNamePrompt and set the alignments, margins and font size as shown here:

LayoutForPrompts

Once this is set, copy the control in the Objects and Timeline panel and then paste half a dozen copies,

copyTextBlocks

The advantage of making these copies, and then editing each in the properties window is that you preserve the Alignments and Margins, font and font size; you then only have to set the name, text and row for each.

(A better solution is to use a style, which we’ll get to later in this series, and which you can read about now here or see a video about styles here).

Adding the Input Controls

When you’ve set all your prompts on the left side, it is time to add the input controls on the right.  The first five entry rows are TextBoxes,

[Note that entry is done with a TextBox and the prompts are TextBlocks – the two words are very similar but the controls are quite different]

Drag the first TextBox into place, and set its alignment to right and bottom), set the left margin to 5 and the other three to zero, and finally, set its with to 150 and its height to 25.

Next make four copies, and adjust their name and row for the next four data entry fields.

TextBoxes

Date Picker

The sixth entry row, DateOfEntry) will get a DatePicker. To create one, click on the Chevron, which opens the advanced controls, and click on DatePicker,

DatePicker

This control has a lot of flexibility in its display; much of which can be set in the properties window,

DatePickerProps

For now, though, we’ll go with the defaults as shown.

Radio Buttons, Check Boxes and Stack Panels

The input for Level is three Radio Buttons. You can find a complete write up of using Radio Buttons here, but the key things to know are that you want all the Radio Buttons to share the same GroupName (so that they are mutually exclusive), you want one to have IsChecked clicked and, most important, you’ll want to put all the radio buttons into a stack panel. The stack panel will have its alignment set to stretch with no margins and its orientation set to horizontal.

RadioButtons

Similarly the versions input is a pair of check boxes, and they too sit in a stack panel.

ListBox and ListBoxItems

Finally, the Tags are chosen from a ListBox (for now). To add the ListBox open the Chevron and drag the ListBox into place, and for now you can hardwire the choices by clicking on the Items collection and adding ListBoxItems.

ItemsCollectionEditor
(Click on the image to see a larger version)

Save everything. Keep Blend open, but also open this same project in Visual Studio

Take a look at the markup  in MainPage.xaml, you should find that the structure and syntax of Xaml is pretty easy to pick up when you compare the Xaml to the WYSIWYG design. 

Pretty Xaml

I find it much easier to read the Xaml if each property is on a line by itself. To accomplish that, open Tools->Options and click on the arrow next to Text Editor. Then open up Xaml and Formatting and click on General to set the rule that formatting should be done when you paste from clipboard or complete a tag and click on Spacing to set the rule that each attribute should be on a line of its own; as shown in the following composite image:

OptionsComposite

The Xaml that is produced becomes easier to handle, though it takes up a lot more room, as shown in the following small excerpt:

   1: <TextBox x:Name="Topic"

   2:          Height="25"

   3:          HorizontalAlignment="Left"

   4:          Margin="5,0,0,0"

   5:          VerticalAlignment="Bottom"

   6:          Width="150"

   7:          Grid.Column="1"

   8:          Grid.Row="7"

   9:          TextWrapping="Wrap" />

  10: <ListBox x:Name="Tags"

  11:          HorizontalAlignment="Left"

  12:          Margin="8,0,0,0"

  13:          Width="125"

  14:          Grid.Column="1"

  15:          Grid.Row="9"

  16:          BorderThickness="1,5">

  17:     <ListBoxItem  x:Name="Silverlight"

  18:                   VerticalAlignment="Bottom"

  19:                   FontFamily="Georgia"

  20:                   Content="Silverlight" />

  21:     <ListBoxItem x:Name="Expression"

  22:                  Content="Expression" />

  23:     <ListBoxItem x:Name="VisualStudio"

  24:                  Content="Visual Studio"

  25:                  IsSelected="True" />

  26:     <ListBoxItem x:Name="Blogs"

  27:                  Content="Blogs" />

  28: </ListBox>

  29: <StackPanel x:Name="ButtonsStack"

  30:             Margin="0"

  31:             Grid.Column="1"

  32:             Grid.Row="8"

  33:             Orientation="Horizontal">

  34:     <RadioButton x:Name="Level100"

  35:                  Margin="5,0,0,0"

  36:                  VerticalAlignment="Bottom"

  37:                  Content="100"

  38:                  GroupName="Levels"

  39:                  HorizontalAlignment="Left" />

  40:     <RadioButton x:Name="Level300"

  41:                  Height="17"

  42:                  Margin="5,0,0,0"

  43:                  Width="40"

  44:                  Content="300"

  45:                  d:LayoutOverrides="Height"

  46:                  HorizontalAlignment="Left"

  47:                  VerticalAlignment="Bottom"

  48:                  IsChecked="True"

  49:                  GroupName="Levels" />

  50:     <RadioButton x:Name="Level400"

  51:                  Height="17"

  52:                  HorizontalAlignment="Left"

  53:                  Margin="5,0,0,0"

  54:                  VerticalAlignment="Bottom"

  55:                  Width="40"

  56:                  Content="400"

  57:                  d:LayoutOverrides="Height"

  58:                  GroupName="Levels" />

  59: </StackPanel>

Your form is ready to go. Click Control-F5 to test it.

 

Novice Previous:  Data Entry Next Data
Advanced Previous: Two Levels Next: Data
Posted in z Silverlight Archives | Tagged , | Comments Off on Creating A Form – Level 100

Project Turing – Data Entry (a mini-tutorial)

MiniTutorialLogo
(click on the image to see other Mini-tutorials)

 

ProjectTuringLogo

 

 Turing Entry: [Novice: 3]      FAQ     Table of Contents    

The Turing Project design calls for a four component system:

  • Data Entry
  • Data Storage
  • Data Service
  • Data Display

Eventually Data Entry will be via email or web, Data Storage will probably be SqlServer, Data Service will probably be a WCF application and Data Display will be an increasingly spectacular Silverlight application.

 

Corpus omne perseverare in statu suo quiescendi

Expanding the Spec – Reports

In discussion of this project, one feature that surfaced right away was the desire to have a module that displays statistics about blogs, authors and topics in various ways.  I imagine that we would certainly want to have a treemap for topics and other charts that show, for example, the pace of blogging for a given contributor.

A treemap is an increasingly popular control for displaying trends in data because you can put a lot of information in a small space and still make it relatively easily understood. There are nice write-ups of the treemap here and here

TreeMap

(Colors indicate categories, saturation of color indicates quantity)

Successive Approximation

One of the difficulties in the “get it working and keep it working/ successive approximation” approach to coding is that you have to be able to see a hut and imagine a mansion.  The advantage is that it is easier to build a hovel and turn it into a hut and from there to a ranch, to a tudor, to a center-hall colonial and on to a mansion (at least it is for me; others disagree).

The second big obstacle many of us face is Newton’s First Law: “Every body persists in its state of being at rest… except insofar as it is compelled to change its state by force impressed.”  That is, it is hard to get started.

Overcoming Inertia

I find that the best way to  overcome inertia is to start coding. (I also find that the best way to spend my day).  Let’s begin with Data Entry (it happens to be first on the list). 

In time, I imagine that adding a blog entry to the db will be very low-friction; the user will be able to send an email or, even better, we’ll write a plug-in for LiveWriter that takes care of the notification automagically.  For now, however, we’ll get 90% of the functionality by writing a small application that gathers the data in a form and prepares the data for distribution to Data Storage.

Form

To create the form, we first need to know what data we need.  As a first cut I’ve identified the following useful data:

Datum Type Control Type Notes
Full Name String Autocomplete  
Alias String Autocomplete (email)
URL of blog string Autocomplete  
URL of entry string TextBox  
ShortURL string TextBlock we generate
Date of Entry DateTime DatePicker  
Topic string TextBox  
Tags strings Listbox optional
Level enum radio button optional
SL version Compatibility enums check boxes optional

Once again, in time we’ll divide these into those fields which we only need to collect once (e.g., Full Name, URL of Blog) and those which are specific to a given blog entry. 

Novice Previous:  Project Levels Next:  Creating a form
Advanced Previous: Project Levels Next: Data
Posted in z Silverlight Archives | Tagged | Comments Off on Project Turing – Data Entry (a mini-tutorial)

Turing Project: Two Levels

Turing Entry: [Novice: 2]  [Advanced: 2]    FAQ     Table of Contents    

 

In a previous post I described Project Turing. This is the second entry for that project and will describe how I hope to meet the needs of two audiences: 

Novice: programmers who may or may not have experience with other languages, may not know C# (or advanced C#), .NET or the fundamentals of Silverlight (e.g., what Xaml is)

Advanced: programmers who have worked with Silverlight and want to go beyond the basiscs; who want to see a design-to-delivery walk through that touches on more advanced topics.

You Can’t Get There From Here

In traditional publishing, I couldn’t possibly address both audiences in the same documentation. Either I would lose the novice by assuming to much, or I would make the advanced  programmer crazy by explaining too much.

But the web is different. I believe that I can document the entire process of design-through-delivery of Project Turing for both audiences independently, but in a single set of posts

(I don’t think anyone has tried this, but I do think it can be done and if done well, would be valuable. In any case, it will be fun to try.)

Follow the Yellow Brick Road

I was in a very large hospital not long ago. At the information desk you could look up and see 8 colored tubes. You told the desk person where you wanted to go and they handed you a piece of paper with one of the 8 colors.   Just follow your color.  As you walked along, the different colors would branch off… sometimes they’d rejoin for a while. If you kept an eye on your color, the tubes took you where you wanted to go.

This project will be documented with two tubes, er, threads: Novice and advanced. You just follow your thread

iStock_ 3 elevators Large

Every entry will have a pointer to the next and previous entry for both threads. If you follow a single thread it should read like a continuous story,but of course you are free to switch back and forth as your interest dictates.

 

Not Sidebars, Not Asides; A threaded Whole

What you end up reading should not be a set of side-notes, but rather a coherent set of posts and tutorials, targeted at your level of experience.

Let me be very clear about my objective as it is unusual:  If you choose to follow the Novice path , you should experience that you are reading a Novice-targeted  set of posts, not an advanced set of posts with asides for beginners.

Headers, Footers and “Page numbers”

Beginning with this post, and for the rest of this project, each blog posting on Project Turing will bear a header much like this:

 Turing Entry: [Novice: 7]  [Advanced: 3]    FAQ     Table of Contents    

You read the header shown as follows: “This is the 7th entry for the Novice thread and the 3rd entry for the Advanced thread.  

[What you are reading right now, however, is the second post for both]

At the bottom of each page you’ll find a footer like this:

[Novice]       Previous    Next
[Advanced]  Previous    Next

by following the Next for your thread you should find that the entries are numbered consecutively. Thus you can think of the series as looking like this:

 

TuringPageNumbers

 

[This posting was updated and clarified on 8/6]

——————

[Novice]       Previous    Next
[Advanced]  Previous   

 

Posted in z Silverlight Archives | Comments Off on Turing Project: Two Levels