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

Bayesian Probability (Quick Bit)

Added a Quick Bit today on Baysian Probability.

Posted in z Silverlight Archives | Comments Off on Bayesian Probability (Quick Bit)

AgOpenSource Project Turing

 

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

ProjectTuringLogo

I’m very pleased to announce the launch of a new AgOpenSource project, code named: project Turing.

The Turing project will prototype a fully automated web service and Silverlight Front End for the display of any blog entry* that discuss Silverlight programming skills.

*Current design constraint is Microsoft employees only.

 

 

Functional Design

There will be three core modules

1. Data Entry

The goal is to lower the barrier to data entry. Eventually we’ll want to support all of the following (and more) for sending in the information required to be listed

  • Email using a fast simple syntax or a template
  • A web site
  • A plugin for LiveWriter
  • etc.

 

EmailDataEntry

 

2. DataBase and Web Service

The second part of the design calls for the storage of the information in a SQL Database and the retrieval of that information through a WCF Web Service.

 

3. Silverilght Application For Display

The front end to the application is a Silverlight data grid that allows the user to sort and otherwise customize the display.

 

BlogProject

 

 

[updated 8/4/2009]

 

Next: Turing Project Levels

Posted in z Silverlight Archives | Tagged | 1 Comment