I had problems with the way skins were being referenced in Witty. To solve it, I moved the skins into their own project and needed to load them dynamically. To reference the resources, I use the Pack URI scheme.
Typical you can load the skin resource dictionary with the following pack syntax.
// Load the Resource Dictionary from an external referenced DLL
Uri uri = new Uri("pack://application:,,,/SkinResources;Component/RedSkin.xaml");
Application.Current.Resources.Source = uri;
However, I had problems with the previous code in Witty and changed it to:
// Alternate way to load the resource dictionary from an external referenced DLL
Uri resourceLocator = new Uri("SkinResources;Component/GreenSkin.xaml", UriKind.RelativeOrAbsolute);
Application.Current.Resources = Application.LoadComponent(resourceLocator) as ResourceDictionary;
Here's how to refer to the skin resource from XAML.
Here's simple solution demonstrating the code above:
Encapsulate Resources source
Sometimes when you download WPF demo source code off the net and try to build it, you'll get the error "cannot locate resource window1.xaml". You can also get this error when converting a VS2005 project to a VS2008 project. Several people have asked me about this issue, which can be easily remedied by:
- Right-clicking on the Solution or project file in Visual Studio and selecting "Clean"
- Or, add a space in App.xaml which will cause Visual Studio to clean and rebuild the whole project.
Hope this helps,
Here's a simple example that I created to show how to make a ListBox control that has many items more manageable. As you type into the filter TextBox, the ListBox will only show the items that matches the filter. You can give the sample a try by clicking the XBAP link below.
The magic happens in code by retrieving the default view for the ListBox's ItemsSource and applying a filter against it.
private void FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
//Use collection view to filter the listbox
ObjectDataProvider peopleDS = (ObjectDataProvider)this.Resources["PeopleDS"];
ICollectionView collectionView = CollectionViewSource.GetDefaultView(peopleDS.ObjectInstance);
collectionView.Filter = new Predicate<object>(NameFilter);
public bool NameFilter(object item)
Person person = item as Person;
Here is the full source code:
Last week, I gave a presentation at the Microsoft's WPF Bootcamp in Redmond. My presentation, titled "WPF in Style", covered styling, templates, and User Experience in WPF. I describe my role as a Creative Developer at Vertigo and how we went about coming up with the design for Family.Show. I gave quick demos using Blend to set brushes and resources. I used that demo to build up to my approaches on styling a button control and building an app that supports skinning. I also talked a little bit about Witty, my WPF twitter client.
It was one of the rare times that I spoke to a crowd of attendees, but it seem to have went well even with my nervousness. I got the chance to meet and hang out with some really cool people in the WPF world, including Josh Smith, Karsten Januszewski, and Jaime Rodriquez. I also took the opportunity to meet many of the attendees and share my experiences on being a creative developer and building real-world WPF applications. It's great to see the enthusiasms around WPF!
The WPF Bootcamp was fun. It was good hear how Family.Show helped people with understanding the potentials of WPF as well as pushing WPF as a technology to use in their projects.
You can get my slides from Karsten's blog:
If you missed it, Vertigo released two cool new samples last week for Microsoft.
First up we have Slide.Show. Use this sample to show off your photos. I think that Silverlight is a great way to display interactive slide shows. I even submitted some photos to the Slide.Show project to include it in the sample.
The slide show page on Vertigo has a pre-configured running live demo. Definitely check it out. Look for more info on how to use it and other documentation to come on the sample codeplex project site.
I gave Slide.Show a test run and configured it to access my Flickr feed.
An update to Video.Show is out. Video.Show is great if you want to have a solid base for building your own video community using .NET technologies. On top of Silverlight, this sample uses several other great technologies like the AJAX Control Toolkit, Expression Encoder, Linq, Silverlight Streaming Service, and more.
New to this version, there is also a live site to play with.
One of the early goals we had we Family.Show was to make the XAML files easy to read and understandable. I want to share the list of some of the little things that we did to keep our XAML clean. I will be using the MainWindow.xaml page as an example.
Clean <Window> Tag
We placed the xmlns (xml namespace references) attributes first and in separate lines. Like the "using" section in .cs files, this keeps them organized.
Title="Family.Show" Height="728" Width="960"
Almost every code section will have a corresponding comment above it. We did this for two reasons. Visual Studio display comments as green text, which makes it really easy to scan the XAML for the tag that we want to modify. People new to the code will have an easier time understanding the XAML structure from looking the comments instead of the XAML tags.
Although we will not reference all of the controls in our code behind, we would still name all of our controls. We always use x:Name instead of the Name attribute for consistency as not all controls support the Name property. We keep the x:Name as the first attribute again for consistency.
The naming help describes their function and why the control is there. This is especially helpful when it comes to picking the right controls to style in Expression Blend using the Objects and Timeline panel with the Property panel.
Use User Controls
User Controls are not only great for code-reuse; They are a great organization tool. With User Controls, we abstracted functionality into their own XAML file. It's like refactoring code into methods.
<!-- New User Control -->
<local:NewUserControl x:Name="NewUserControl" ... />
<!-- Welcome User Control -->
<local:Welcome x:Name="WelcomeUserControl" ... />
<!-- Person Info Control -->
<local:PersonInfo x:Name="PersonInfoControl" ... />
<!-- Family Data Control -->
<local:FamilyData x:Name="FamilyDataControl" .. />
We kept brushes, styles, and templates in separate resource dictionary files. Think of it as using a separate cascading style sheet in HTML. The look and feel is separated from the content. We could've done a little better by removing all inline styling in Family.Show.
By using Resource Dictionaries we were also able to implement the Skinning functionality by simply replacing the Resource Dictionary in code.
Structured indents and spacing
Like HTML and code, indents and spacing are a great way to keep XAML clean. The auto-format feature in Visual Studio really helps with this.
Well, that about sums it up
Hope this helps,
Witty is one of the few Twitter clients that has a built-in spell checker. How hard was it to implement? What if I told you that in WPF, spell-checking is just a checkbox?
Here's the Xaml.
<TextBox x:Name="TweetTextBox" SpellCheck.IsEnabled="True" />
Geni.com is a great way to build your family tree collaboratively with other family members. Since both Geni.com and Family.Show support the Gedcom 5.5 format, we can easily take the family trees built on Geni.com and display it in Family.Show. This post will show you how.
- Build your family tree with Geni.com, get other family members to help
- Use the Geni.com export feature and download your family Gedcom file.
- Goto the GEDCOM export wiki.
- Click on Gedcom 5.5, the gedcom file will be sent to your email in a zip file.
- Expand the zip file
- Run Family.Show
- Click on "Import..." on the Welcome Screen
- Browse to the expanded zip folder and select "export-geni.ged" file.
- Click open and voila
Why would you want to import to Family.Show?
Find out additional information about your family
With the family statistics feature of Family.Show, you can gain new insight about your family that you can't get with on Geni.com.
For example, take a look at the last names Tag Cloud for the House of Black from Harry Potter. I can quickly glimpse that ere are a few Burkes, Crouch, and Longbottom in the tree. I didn't know that the Black family also have a Weasley and a Potter as in-laws in there tree! If the tree also included the Potters and Weaslys, we could've probably browsed the tree until we reached Harry or Ron.
The Age Distribution is another high level report that can be useful. You can quickly find the age range for the living members of a particular family.
Different visualization of the family tree
Geni.com is great for it's viral/social way of building family trees. It however presents family trees in a standard flat view. Family.Show takes a different approach in visualizing the family tree. The tree shape and size changes based on the selected person in the tree. Viewing a tree from your grandfather's perspective is very different from viewing it from your perspective. In a way, you're navigating the family tree instead of simply viewing it. Try clicking around the provided sample trees to test it out.
Bellatrix Black's Tree
Here is the same tree from Cygnus Black's perspective
A different way to view a person.
With the Photo and Stories feature, Family.Show provide a different perspective on a person.
In the process of developing Family.Show, I noticed that we were starting to create lots of XAML resources such as brushes, styles, and data templates. My thinking at the time was to separate the resources into separate files organized by functional type to make them easier to find. For example, all SolidColorBrushes and LinearGradientBrushes would go into BrushResources.xaml. To use the resources as a group, we simply use the WPF Merged Resource Dictionaries feature. (At the time, Paul Stovell also recommended separating resources into the own files. http://paulstovell.net/blog/index.php/xaml-and-wpf-coding-guidelines/)
Separating the resources made a lot of sense from a developer perspective. It keep any particular resource dictionary small and simple. By using the solution explorer in Visual Studio, I can quickly find and edit the resources that I want.
Separate Files Added Complexity To Skinning
I started running into issues when we adding the skinning feature to Family.Show. For the new Silver skin, we needed to replicate the the same resource dictionary files for each skin. This added complexity as the number of files was doubled. In Visual Studio, it was still clear and easy to find resources as they are organized by folder.
The problem was that many of the skin changes were typical easier to modify in Expression Blend using the Resources panel. However, Blend displays the resources like the screenshot below. This made it really difficult to find the right resource for the right skin to change it.
Another problem was that any change made to the skin would take awhile to be displayed in the Blend designer, slowing down the skinning process.
Single Resource Dictionary for Skin
In developing Witty, I went a different route with resource organization by keeping all resources in a single file, in a similar fashion as cascading style sheets mostly being single files. This really simplified the resources. In addition any resource changes were quickly displayed in the designer. Although the number of resources in Witty is smaller, I think Blend is just more performant with less Merged Dictionaries.
Based on my WPF project experiences, I would advocate placing resource dictionaries into a single resource dictionary, especially if skinning is involved.
What do you think? Should XAML resources be organized into separate files or a main single file? I would love to hear your thoughts on this.