Rants Tagged with “WPF”
1 2 3 > >> (Total Pages: 3/Total Results: 24)
I've been digging into some of the open source and 3rd party controls that are becoming available for Silverlight 2. While running into some odd issues with some of them it occurred to me that there are some design guidelines that haven't been well communicated. Back in the early days of WPF I learned (though exactly where is unclear) that every control should support an empty constructor and that all properties (e.g. XAML Attributes) should have a default value. I knew this to be true but I couldn't document where it came from.
So as usual when I am stuck, I contacted Chris Sells as he was my mentor in early XAML usage. He was at MSDN at the time gathering content and helped me get the Data Binding articles as well into the Software Design Review for WPF (then Avalon). If anyone could help me figure out where I learned this, he'd know. He reminded me of the language they use internally: "Create-Set-Use". Essentially this means that the design pattern for controls is that they should work without requiring any properties:
<Grid ...>
<Rectangle />
</Grid>
You can see that the Rectangle doesn't require any properties to be valid. Of course this Rectangle has no fill brush and no stroke brush which means it will likely not be visible. But that's OK because it is valid XAML and doesn't break. The XAML for a control doesn't have to read the mind of the user, but should behave (e.g. not throw exceptions). One of the most egregious was a control that threw an exception if I failed to set the Width and Height. Worse yet, when it did throw these exceptions, it didn't tell me what *all* the properties I needed therefore it was painful to use. Width and Height are particularly problematic in this way in that by not defaulting to "Auto", showing the control in a non-Canvas container meant I needed to set "Auto" to the values which is what they should *always* be defaulted to.
Create-Set-Use happens during parsing of the XAML. This comes back to thinking of XAML as a serialization format for in-memory objects. XAML is simply a way to define what the structure of a particular document should be when its de-serialized. If you keep in mind that an Element becomes an object construction and that properties become SetValue calls, it makes it fairly clear what is happening during the parsing of the XAML itself.
As you write your own Silverlight or WPF classes that you expect to be used in XAML (this includes controls but also may be types that can be created as resources), try to keep these design ideas in mind. It will make life easier for your users.
On Ian Griffiths blog (a must for any WPF developer), he shows a way to bind to the Length of the column in the template of the ListView's Grid to make the columns look right. Check it out here:
http://www.interact-sw.co.uk/iangblog/2007/05/30/fill-wpf-listview-columns
If you are doing any WPF development, get this new *free* (as in beer) tool from Chris Sells (with help from Ian Griffiths) that allows you to see the template of the built-in controls. It lets you see what the template is and what the control looks like across different themes. If you are writing your own controls (or just templating a built-in control) its a great way to 'borrow' from their ideas and make them better.
I use ListBox's and DataTemplates a lot to show data in different ways in WPF. One of the problems I've faced is how to change the look of the "Selected" element. All the examples I could find assumed you were not using a DataTemplate. Luckily Chris Sells came to my rescue and pointed me at the ItemContainerStyle. Using a Template for the ListBoxItem in the ItemContainerStyle let me control the look and feel of the Selected element (or disabled items) easily.
What I wanted was a nice glow effect instead of the default blue background:

This worked fine, but I was still getting the default behavor (of coloring the background blue) when I selected an item. To fix it, I added a Style that overrode the ListItemBox's template and replaced it with a simple border. I added a Trigger to this template on the IsSelected to add a nice bitmap affect of a red glow. Here's the entire XAML example:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.Resources>
<!-- The Data Source -->
<XmlDataProvider x:Key="FolderListData">
<x:XData>
<People xmlns="">
<Person Name="Chris"
Picture="http://www.sellsbrothers.com/services/me.jpg" />
<Person Name="Shawn"
Picture="http://wildermuth.com/images/headshot.jpg" />
<Person Name="Ian"
Picture="http://tinyurl.com/2szrbm" />
</People >
</x:XData>
</XmlDataProvider>
<!-- ItemContainerStyle with the Trigger for Selected -->
<Style x:Key="RedGlowItemContainer" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Background="LightGray"
CornerRadius="8"
BorderThickness="3"
x:Name="IconBorder"
Margin="8,4,8,4" >
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="IconBorder" Property="BitmapEffect">
<Setter.Value>
<OuterGlowBitmapEffect GlowColor="Red" GlowSize="5" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource FolderListData}, XPath=//Person}"
HorizontalAlignment="Center"
ItemContainerStyle="{StaticResource RedGlowItemContainer}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,10,10,10"
HorizontalAlignment="Center"
VerticalAlignment="Center" >
<Image Width="90"
Source="{Binding XPath=@Picture}" />
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Height="20"
Text="{Binding XPath=@Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Let me know what you think...
My new article in MSDN Magazine is now online. I walk through several customization schemes for
WPF including styles, templates, user controls and custom controls. Check it out!
I've worked up a simple example of how to use Commands in WPF. This example includes:
- Creating custom Commands
- Using built-in and custom Commands in XAML
- Shows how to use Commands in menus, toolbars, buttons and context menus
- Shows how the CanExecute call back is used to enable/disable multiple XAML elements that are tied to the same Command
- Shows how to use Parameterized Commands
Please let me know what you think of the sample.

I've been digging into the Command infrastructure in WPF lately and I really like the way it works. Essentially it is a way to separate the idea that you have commands that a particular applciation can execute and the ways you start a command (e.g. menu, toolbar button, context menu, hotkey, pen gesture). WPF comes a standard set of commands that are commonly used (e.g. New, Close, Copy, Paste, Cut, etc.). You can define your own commands fairly easily as well.
In the XAML you can declaratively specify the commands like so:
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New"
Executed="OnNew" />
<CommandBinding Command="ApplicationCommands.Close"
Executed="OnClose"
CanExecute="OnCanClose"/>
<CommandBinding Command="local:Window1.ImportFileCommand"
Executed="OnImportFile" />
<CommandBinding Command="local:Window1.ExportFileCommand"
Executed="OnExportFile" />
<CommandBinding Command="local:Window1.ChangeViewCommand"
Executed="OnChangeView" />
</Window.CommandBindings>`
Finally, you can specify the command on XAML elements (with an optional CommandParameter) like so:
<Menu DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="New" Command="ApplicationCommands.New" />
<Separator/>
...
</Menu>
<ToolBar DockPanel.Dock="Top">
<Button Command="ApplicationCommands.New">New File</Button>
...
</ToolBar>
Then you can create a single event to handle whichever way the commands are executed (see the Executed attribute on the CommandBinding above).
Lastly, I really like the CanExecute facility which allows you to have a callback that can determine whether a particular command is enabled or not. This callback is executed by WPF to see whether to disable any controls that are tied to that command. If one is disabled (like in a Menu and in a toolbar) they both get disabled.
I hope to have a good example to share with you in the next couple of days.
I've been digging a bit into how themes work for a new article. In doing that I wanted to see how WPF used their theme files. Their theme files are stored as BAML in the PresentationUI assembly. As usual reflector came to the rescue with a BamlViewer plugin (available as part of the ReflectorAddIn's CodePlex Project).
I downloaded it and started to look at the generic.xaml file that WPF uses. Unfortunately the XAML window in the add-in was hard to navigate and didn't support searching. What I really wanted was a way to support select/copy in the XAML viewer and a way to actually save the XAML files so I could do more in depth investigating. Since the add-in didn't support, I volunteered to add it:

I am not sure if the latest version that I have linked to above includes my changes yet or not. If it doesn't, you can download the sources and they definitely have my changes.
Now...back to that generic.xaml file...interesting...but you'll have to read my upcoming article to see what I found!
Come and get it. The newest drop of the Visual Studio Tools for .NET 3.0. Make sure you get the .NET 3.0 Runtime (and SDK) and the Visual Studio Workflow Tools RC5 while you're at it!
NOTE: No WCF Designer in this drop and Cider (the WPF designer) doesn't work in VS Express.
I have built a test-vista machine to do some WinFX stuff on and it got me wondering...why do I need to run the WinFX runtime installation on Vista? Isn't this supposed to be pre-installed? Aren't some built-in Vista apps already using WinFX? I am so confused. Anyone know?