Works on My Machine

Scott Hanselman used an icon in one of his presentations that I will rip off, steal, borrow (?) take/use/modify/…  to provide critical information about my code samples:

WorksOnMyComputer

Note that this seal is not just intended to be humorous; is a link to a page that lets you know what computer the associated code was tested on and what version of Silverlight it was compiled with. My hope is that this will be useful as we move forward.

Posted in z Silverlight Archives | Comments Off on Works on My Machine

The Expander – Part 2

 

 

I recently examined the Expander control and in that entry I promised to return and show how templating can add value to the user experience of this Silverlight Toolkit control.

You will remember that when we left the expander, it was able to display its contents with a bit of color, but opening it was a bit abrupt:

— Start of streaming example —

— End of streaming example —

We will modify the example by templating the control so that the contents fade in and out gently,

— Start of streaming example —

— End of streaming example —

Templating the Toolkit control

All controls, whether created by Microsoft as core controls, or as Toolkit controls, or by third party vendors, or by developers, are “lookless.”  that is, the developer of the control provides a default appearance, but you are always free to modify that appearance, as shown in this video

TemplateVideoImage

Blend makes templating a control straightforward, but you need to make a decision. Do you want to create a templated version from scratch, or from a copy of the existing control? 

In may of our demos on templating we choose to create the template from scratch to demonstrate creating a whole new appearance. In this case, however, we don’t want to change the appearance of the control, nor its logic; we just want to modify, slightly, what it does as it transitions between its collapsed and expanded visual states.

Editing The Template

Thus, the process is to open Blend, right click on the Expander control in the Objects and Timeline window and create a template, starting with a copy of the existing control

EditACopy

Within the template editor, you’ll modify only the Expand and Collapse states. For Expand, you’ll add animation that sets the visibility to visible at time zero, and changes the opacity from 0 to 100 over 1 second.

ExpandAnimation

 

 

For the collapse visual state you’ll animate the opacity from 100 to 0 over one second and then set the visibility to collapsed.

AnimatingCollapsedState

Almost, but not quite

This almost works, but if you do only this, when you start the application you’ll see the content (which should be hidden) is visible and rapidly fading.  Unfortunately, as the page is loaded, the control moves to the collapsed state, and you don’t (and can’t!) set the control to invisible (collapsed) until after it fades out.

One solution to this is to entirely remove the visibility settings at time 0 and 1 second and leave only the collapsed visibility at time 1.5 seconds. You can do this in Blend by turning down the expand site and deleting the white ovals at the appropriate time line entries…

ModifyVisibility

Alternatively, you can open the Xaml file (preferably in Visual Studio) and pluck out the lines that set the visibility in the collapsed state.

<DiscreteObjectKeyFrame KeyTime="00:00:00">
    <DiscreteObjectKeyFrame.Value>
        <Visibility>Visible</Visibility>
    </DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:01">
    <DiscreteObjectKeyFrame.Value>
        <Visibility>Visible</Visibility>
    </DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>

That done, you can set the initial visibility to collapsed, and the application will work as intended

Previous Expander Control Part I


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on The Expander – Part 2

New Look?

The new look is explained here, but was launched in anticipation of Mix and the advent of Silverlight 3, which I believe will open a whole new chapter for Silverlight and Microsoft.

Renew. Refocus. Respond.

Posted in z Silverlight Archives | Comments Off on New Look?

Expander Control Part 1

 

 

I recently described the HeaderControl from the Silverlight Toolkit.  Derived from the HeaderControl (and thus, to be thought of as a specialized version of the HeaderControl) is the Expander.

In its simplest form, the Expander has two properties that do all the work: the Header property and the Content property.  Put text into each, and hey! presto! you have a working expander.

<UserControl xmlns:controls="clr-namespace:Microsoft.Windows.Controls;
    assembly=Microsoft.Windows.Controls"  
    x:Class="Expnder.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <controls:Expander x:Name="Expander1"
                           ExpandDirection="Down"
                           Header="Q: Why did the chicken cross the road?"
                           Content="To Get To The Other Side. Wanka Wanka.">
        </controls:Expander>
    </Grid>
</UserControl>

— Streaming Example Start —

— Streaming Example End —

You can enhance the appearance of the expander in numerous ways a couple of which are shown in the next variation:

<UserControl xmlns:controls="clr-namespace:Microsoft.Windows.Controls;
    assembly=Microsoft.Windows.Controls"  
    x:Class="Expnder.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <controls:Expander x:Name="Expander2" 
                           HorizontalAlignment="Left" FontSize="14"
                           ExpandDirection="Down"
                           Header="Q: Why did the chicken cross the road?"  >
            <ContentControl FontSize="24" HorizontalAlignment="Center"
                            Foreground="Blue"
                            Content="To get to the other side" />
        </controls:Expander>
    </Grid>
</UserControl>

WorksOnMyComputer In this second version I’ve added a FontSize property, but more important I’ve broken out the Content property using a ContentConrol to take over how the content is rendered. 

(click on image for information on how and where the code was tested)

— Streaming Example Start —

— Streaming Example End —

In the next entry I’ll review how you can use templating to make the content fade in and out as you toggle the button.

                                                         Next: Expander Control Part II


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on Expander Control Part 1

The Tree View Control

 

 

The Tree View control is ideal for displaying hierarchical data. While there is a great deal you can do with this control, in its simplest form it is fairly straightforward to work with, once you grok the essential recursiveness it demands (well, requests strongly).

We’ll look at two examples: the TreeView raw, and then using DataBinding with a tiny bit of customization. Here’s what we’re building:

— Top of Streaming Application —

— End of Streaming Application —

Everything that follows is based on the work of Stephen R Strong who contributed his efforts in support of this blog, and whose work is very much appreciated.

To create the application shown above, we need to a hierarchical data source and we need a pair of treeview controls.

The easiest way to obtain the data is to just create it in memory (though of course, your source might be an xml file, retrieved from a database, etc.).

Hierarchical Data

The Data class I created for this example is defined like this:

public class Data
{
   public string Name { get; set; }
   public Data Parent { get; set; }
   public List<Data> Children;
   public int Depth  { get { return Parent == null ? 0 : Parent.Depth +1; } }
   

I opted to provide a default constructor, though it does so little, I could have let the compiler create one for me. The CreateChild method adds a new child to the current Data object.

public Data()
{
   Name=string.Empty;
   Parent = null;
   Children = new List<Data>();
}

public Data CreateChild( string name )
{
   Data child = new Data() { Name = name, Parent = this};
   Children.Add(child);
   return child;
}

Finally, the Data class provides a static method that returns a hierarchical collection of information about the United States,

public static Data CreateDataSample()
{
   Data root = new Data() { Name = "United States" };
   Data states = root.CreateChild( "States" );
   states.CreateChild( "Alabama" ).CreateChild( "Montgomery" );
   states.CreateChild( "Alaska" ).CreateChild( "Juneau" );
   states.CreateChild( "Arizona" ).CreateChild( "Phoenix" );
   states.CreateChild( "Arkansas" ).CreateChild( "Little Rock" );
   Data presidents = root.CreateChild( "Presidents" );
   Data W = presidents.CreateChild( "Washington" );
   Data WTerm = W.CreateChild( "Took office" );
   WTerm.CreateChild( "1789" );
   WTerm.CreateChild( "1793" );
   Data A = presidents.CreateChild( "Adams" ).CreateChild( "Took office" ).CreateChild( "1797" );
   Data J = presidents.CreateChild( "Jefferson" );
   Data JTerm = J.CreateChild( "Took office" );
   JTerm.CreateChild( "1801" );
   JTerm.CreateChild( "1805" );
   return root;
}

Note that CreateChild returns a Data object, and we take advantage of that in the third line where we create a Child of states whose Name field is Alabama, and then give that Data object a child whose name field is Montgomery (the capital of Alabama).

Ultimately, we return just the root Data object; but the structure we’ve created looks like this:

USOutline 

Here’s the complete Xaml for the page that displays this data,

<UserControl x:Class="TreeView.TreeViewPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:control="clr-namespace:Microsoft.Windows.Controls;
assembly=Microsoft.Windows.Controls" Width="600" Height="600"> <Grid x:Name="LayoutRoot" Background="White"> <control:TreeView x:Name="LeftTreeView" HorizontalAlignment="Left" Background="Wheat" /> <control:TreeView x:Name="RightTreeView" HorizontalAlignment="Right" Background="Beige" /> </Grid> </UserControl>

The interesting work, of course, is done in the code behind.  L

public partial class TreeViewPage : UserControl
{
   public TreeViewPage()
   {
      InitializeComponent();
      Data root = Data.CreateDataSample();
      FillTree( LeftTreeView.Items, root );
      FillBoundTree( RightTreeView.Items, root );
   }

Recursion

After the call to InitializeComponent we call our static method that returns the root node (United States) which is pregnant with the entire data structure. We pass two arguments to a private helper method named FillTree:

  1. The Items Collection of the TreeView control declared in the Xaml
  2. The Data instance that serves as the root of the tree

The helper method is created to provide a place for recursion, because the process of adding nodes to the tree is (almost) inherently recursive.

I wrote almost inherently recursive because of course you can do this without recursion, even without data binding, but there are some things that just lend themselves to recursion and this is surely one.
 private void FillTree( ItemCollection itemColl, Data dataNode )
 {
    TreeViewItem tvi = new TreeViewItem();
    itemColl.Add( tvi );
    tvi.Header = dataNode.Name;
    //….

FillTree creates an instance of a TreeViewItem (a node in a TreeView) and adds it to the collection that is passed in (in this first case, to the items collection of the TreeView control).

It then sets the tree view item’s header property to the Name property of the Data object it received.  At this point we can conceive of things as looking like this:

TreeViewFirstStep

It is important to note that the TreeViewItem does not hold a copy of the Data object, but rather the Header property of the TreeViewItem gets its string from the DataObject.

The FillTree method then iterates through each child in the current Data object’s Children property (which you will remember is a List<Data>.

    foreach ( Data childDataNode in dataNode.Children )
    {
       FillTree( tvi.Items, childDataNode ); // dang. dang. (curse, recurse)
    }
 }  // end method

For each child it finds, it recurses, passing in the Items collection of the new TreeView Item and, one by one, the children of the current Data object,

Recurse

Thus, the first time the method recurses, the parameters are now the Items collection of the TreeViewItem whose header is United States, and the Data object States.

In this way each data object’s name is added to a TreeViewItem in the appropriate “level” of the tree.

Final line of the constructor of TreeViewPage calls FillBoundTree

public TreeViewPage()
{
   InitializeComponent();
   Data root = Data.CreateDataSample();
   FillTree( LeftTreeView.Items, root );
   FillBoundTree( RightTreeView.Items, root );
}

 

Data Binding

This second method looks a lot like FillTree but works quite differently.

private void FillBoundTree( ItemCollection itemColl, Data dataNode )
{
   TreeViewItem tvi = new TreeViewItem();
   itemColl.Add( tvi );
   tvi.DataContext = dataNode;
   tvi.Header = new TreeViewNode();
   foreach ( Data childDataNode in dataNode.Children )
   {
      FillBoundTree( tvi.Items, childDataNode ); 
   }
}

The key is found in the two lines I’ve shown in red.  In this case, rather than copying the text of the Name field to the Header, we set the DataContext (which signals right away that we’re doing some kind of data binding) and we set the Header to an instance of a TreeViewNode.

TreeViewNode is a user control. Here is the complete Xaml for TreeViewNode,

<UserControl x:Class="TreeView.TreeViewNode"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="300" >
    <Grid x:Name="LayoutRoot" Background="Bisque">
    <Border BorderBrush="Black"
            BorderThickness="4">
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}"
                   Margin="3" />
        <TextBlock Text="{Binding Depth}"
                   Margin="3"/>
      </StackPanel>
    </Border>
  </Grid>
</UserControl>

(No work is done in TreeViewNode.cs)

You can see that the heart of this user control is a pair of TextBlock objects, one of which is bound to the Name property and the other to the Depth property of the Data object. As each Data object is passed in to the FillBoundTree method it serves as the DataContext from which these properties are extracted.


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Tagged | 6 Comments

Toolkit: Header Controls Video Posted

Navigate to previous blog entry

MORE Blog entry on HeaderContentControl

I’m happy to say that my latest video on the Silverlight Toolkit, covering the HeaderContentControl and the HeaderItemsControl is now available for download.

HeaderContentControl


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on Toolkit: Header Controls Video Posted

How Do I Video Series on Hyper-video released

 

HyperVideo3aI’m pleased to say that the third and final part of my series on Hyper-video is now available (just click on the image or click here).

In this last video I demonstrate how to respond to embedded markers by displaying a button and, if you click on the button by pausing the playing video and starting up a related video.

 

More: Start of thread on hyper-video 
(Note: This link jumps to the start of the thread rather than the most recent entry)

 


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on How Do I Video Series on Hyper-video released

Why I’m Going To MIX

I confess, if I didn’t work for Microsoft I probably would go to fewer conferences than most folks.  I never did well in school, I just don’t learn well in classrooms, and while the networking in the hallways is incredibly valuable, the overall cost that I was paying as an independent was high.  So I picked carefully; especially in hard times.

Mixes But MIX is different, and more so if you are interested in RIA and Silverlight. 

While PDC is a great place to see where Microsoft is going and TechEd is fantastic for deep technical information, Mix could almost be renamed “Silverlight Neonatal Unit” (though I admit I may have a skewed perception). 

It was at MIX07 that I switched from being a general .NET  programmer to being a Silverlight Programmer (before joining Microsoft) and it was at MIX08 that we revealed Silverlight 2, a upgrade that I thought was about as big as that from Win 3.1 to Windows 95.

Now, without saying anything out of school, let’s put together just two public facts:

  • On November 16, Scott Guthrie posted a glimpse of Silverlight 3 indicating it will ship in 2009.
  • On Jan 14 the Mix 09 site posted a page called Silverlight 3 Sessions including
    • What’s new in Silverlight 3
    • What’s new in Silverlight 3 Media
    • Deep Dive into Silverlight 3 Graphics

So it is fair to speculate that Silverlight 3 will play an important role in this year’s Mix. And that is pretty exciting news indeed.

I’ll say more as soon as I can, but what I will say right now is this: I’m at least as excited about Silverlight 3 as I was about Silverlight 2.

{ Update – There is a $400 discount until Feb 13 and be sure to check out the MIX site for details about keynote speakers, the agenda and the new Mix Online pages. Also be sure to signup for MIX’s Twitter feed and keep an eye on the MIX tweme [1] }

[1] See Meme


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on Why I’m Going To MIX

Report From MDC – NY & Boston

I had a blast speaking at the MSDN Developer’s Conference (MDC) in both NY (January 20) and Boston (January 22). 

Each was a total blast and as promised, here are the links from that presentation.

 

Okay, favorite thing to geek out on: the elevators in the hotel: you push the button on a panel and it instantly lights up with a letter of the alphabet: that is your elevator, whose doors are open by the time you get there. Step in and off you go. No buttons inside, straight to your chosen floor. Zow!

Posted in z Silverlight Archives | Comments Off on Report From MDC – NY & Boston

.NET Rocks & RIA Panel

.NETRocksCodeMashAs promised, here is the  .NET Rocks recorded panel on RIA at Code Mash. It was a blast and got a great reception.

Participants in the panel included myself, Carl and Richard, Josh Holmes (Microsoft RIA Architect Evangelist), Leon Gersing (Teligent), and James Ward (Flex Tech.  Evangelist).

Takes a few minutes to get going, but then it gets quite interesting.

 

 

Previous Article

More: Report on CodeMash 2009


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on .NET Rocks & RIA Panel

The Header Content Control

 

This quick introduction to the HeaderContentControl of the Silverlight Toolkit will lay the ground work for future entries on the Expander control.

To see the HeaderContentControl with as little fuss as possible, create a new Silverlight application and add a reference to the Microsoft.Windows.Controls.dll from the toolkit.

Page.xaml

 

Begin by adding a reference to the Microsoft.Windows.Controls.dll to your application and then declare an XML Name Space at the top of Page.xaml,

xmlns:control="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls" 

The HeaderControl consists of two parts: the header part and the contents part,

<Grid x:Name="LayoutRoot" Background="White">

<control:HeaderedContentControl 
x:Name="SimpleHeaderContent" Grid.Row="0"> <control:HeaderedContentControl.Header> <TextBlock x:Name="HeaderContentControlHeader" Text="Header for simple Header Content Control" FontSize="16" FontFamily="Georgia" FontWeight="Bold" /> </control:HeaderedContentControl.Header> <control:HeaderedContentControl.Content> <TextBlock x:Name="Message" Text="Content for the content control." TextWrapping="Wrap" FontFamily="Comic Sans MS" FontSize="24" Margin="10" /> </control:HeaderedContentControl.Content> </control:HeaderedContentControl> </Grid>

In the code shown above we are using text for both the header and the content portions,

HeaderInFF

Not Just Text

An interesting thing happens if you put a page with a  HeaderContentControl into Expression Blend, and then template the control…

ContentPresenters

The control consists of a pair of ContentPresenter objects within a stack panel.  If, however, the Header (e.g.,) is a ContentPresenter, then it is in no way restricted to text. 

(Close Blend and don’t save the changes)

Let’s add an image to Page.xaml’s directory and then make that image a compiled resource by adding it to the project

AddExisting

Make sure the Build Action (in the properties window) is set to Resource,

BuildAction

 

Now we can return to Page.xaml and remove the text and substitute the Image,

<control:HeaderedContentControl.Header>
   <!--   <TextBlock x:Name="HeaderContentControlHeader"
             Text="Header for simple Header Content Control"
             FontSize="16"
             FontFamily="Georgia"
             FontWeight="Bold" /> -->
  
  <Image Source="LogoSmall.jpg"
         Stretch="UniformToFill"
         VerticalAlignment="Stretch"
         HorizontalAlignment="Stretch"
         MaxHeight="100"
         MaxWidth="100" /> 
</control:HeaderedContentControl.Header>
The result is immediately obvious,
ContentControlHeaderlWithImage 

 

The HeaderContentControl makes a powerful building block, especially when combined with, e.g., the Expander, as we’ll see very soon.

 

 

MORE Header Controls Video


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Tagged | 1 Comment

Hyper-video videos posted

I’m very pleased to say that the first two of the four-part series of videos on HyperVideo are now available (clicking on the images will bring you to the videos)

Links to Part 1

Links to Part 2

You can also find a blog thread on Hypervideo beginning here.  If you find it interesting, just follow the arrows at the end of each article.

Thanks.


This work is licensed under a Creative Commons Attribution By license.
Posted in z Silverlight Archives | Comments Off on Hyper-video videos posted