April 2008 - Posts

Podder Skinning Competition

Have you ever heard of Podder, the excellent podcast player created by WPF expert Josh Smith? Seen the cooooool skin created by Grant Hinkson?

If no... look at this:

Here is your opportunity to show off your design skills! Josh is hosting a competition seeing who can create the best skin for his application!

Read more about this here!

Posted by rudi | 2 comment(s)
Filed under: , ,

Pimp my ListView

The ListView in WPF is a very powerfull control! While we wait patiently for the DataGrid to be released... lets see what we can do with a ListView

The Basics

Before we start pimping the control... lets look at the basics! I created a very simple data object to be displayed in the ListView

public class Disciple
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Website { get; set; }
}

and I also populate it with some data

List<Disciple> Disciples = new List<Disciple>()
     {
        new Disciple() { Name = "Andrew", Surname = "Smith", Website = "http://agsmith.wordpress.com/" },
        new Disciple() { Name = "Beatriz", Surname = "Costa", Website = "http://www.beacosta.com/blog/" }, 
        new Disciple() { Name = "Corrado", Surname = "Cavalli", Website = "http://blogs.ugidotnet.org/corrado" }, 
        new Disciple() { Name = "Dr. WPF", Surname = "", Website = "http://www.drwpf.com/" }, 
        new Disciple() { Name = "Ian", Surname = "Griffiths", Website = "http://www.interact-sw.co.uk/iangblog/" }, 
        new Disciple() { Name = "Jeremiah", Surname = "Morrill", Website = "http://jmorrill.hjtcentral.com/Home/tabid/428/Default.aspx" }, 
        new Disciple() { Name = "Josh", Surname = "Smith", Website = "http://joshsmithonwpf.wordpress.com/" }, 
        new Disciple() { Name = "Karl", Surname = "Shifflett", Website = "http://karlshifflett.wordpress.com/" }, 
        new Disciple() { Name = "Lester", Surname = "Lobo", Website = "http://blogs.msdn.com/llobo/default.aspx" },
        new Disciple() { Name = "Marlon", Surname = "Grech", Website = "http://marlongrech.wordpress.com/" }, 
        new Disciple() { Name = "Mike", Surname = "Brown", Website = "http://blog.planetwpf.com/" }, 
        new Disciple() { Name = "Pavan", Surname = "Podila", Website = "http://blog.pixelingene.com/" }, 
        new Disciple() { Name = "Rudi", Surname = "Grobler", Website = "http://dotnet.org.za/rudi/" }, 
        new Disciple() { Name = "Sacha", Surname = "Barber", Website = "http://sachabarber.net/" }, 
        new Disciple() { Name = "Zhou", Surname = "Yong", Website = "http://shevaspace.spaces.live.com/default.aspx" }
     };

Next, I set my Window's DataContext to this list

DataContext = Disciples;

and lastly, add the ListView to my Window

<ListView ItemsSource="{Binding}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}"/>
            <GridViewColumn Header="Website" DisplayMemberBinding="{Binding Website}"/>
        </GridView>
    </ListView.View>
</ListView>

Great, now we have a beautiful ListView!!

OK, maybe not beautiful but at least functional! What can be change now?

Column Header Style

To pimp the column headers, we need to create a new style for the GridViewColumnHeader. Here is the skeleton markup

<Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GridViewColumnHeader">
                <Grid>
                    <Border>
                        <ContentPresenter />
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Alternating background colors for each row

Another popular UI trend is to alternate the background colors for each row... Their are 2 components needed to achieve this... First we need to create a new value converter

public sealed class BackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ListView listView = ItemsControl.ItemsControlFromItemContainer((DependencyObject)value) as ListView;
        int index = listView.ItemContainerGenerator.IndexFromContainer(value);
        if (index % 2 == 0)
            return Brushes.LightBlue;
        return Brushes.White;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

All this value converter does is check if the item is on a odd or even line...

<local:BackgroundConverter x:Key="backgroundConverter" />

The next part is to bind the Background of every ListViewItem using the value converter (Read more about how this actually work here)

<Style x:Key="{x:Type ListViewItem}" TargetType="ListViewItem">
    <Setter Property="Background">
        <Setter.Value>
            <Binding RelativeSource="{RelativeSource Self}" Converter="{StaticResource backgroundConverter}"/>
        </Setter.Value>
    </Setter>
</Style>

The template for the ListViewItem is also where you can add mouse over effects, change the selection behaviour, etc!

More Information

Sorting and editing a ListView

MSDN ListView ControlTemplate Example

If you found this article useful, please kick it on DotNetKicks.com

Posted by rudi | 13 comment(s)
Filed under: , ,

Windows Embedded

Well, it's official...

Windows Embedded CE is now Windows Embedded Compact

Windows XP Embedded is now Windows Embedded Standard

Why is this important?

Well, unofficially the XP code base will now be supported for another 10 years!

Read more about this on Mike Hall's blog

Posted by rudi | with no comments
Filed under: , ,

Why WPF Rocks (Custom Layout Panel Showcase)

Another enhancement in WPF that makes it stand out above the rest is the excellent layout system. In WinForms, a button has a Top and Left property. Now you can move the button around on the form. What if you want to dock the button to the top? Lets add a property Dock! This works... but what if I want to randomly scatter the buttons over the screen? Or if I want to automatically scale the buttons in equal sizes, even if I maximize my window? You can't keep adding properties to accommodate the layout! WPF has taken a new approach, every control in WPF has no concept of layout... Check a button in WPF, it has no Left or Top property! Well, this is crazy, how do you lay it out then? Easy, WPF introduced Layout Panels... The layout panel controls how its children is layed out on the screen.

WPF ships with loads off layout panels (StackPanel, WrapPanel, Grid, DockPanel, Canvas, etc). The layout system also use a new concept called attached properties to then position the element in the panel...

Lets look at a example that closely resemble WinForms... We add a Canvas and add a button to this canvas.

<Canvas>
    <Button />
</Canvas>

To now position the Button at Left=100 and Top=100, we use attached properties

<Button Canvas.Top="100" Canvas.Left="100"/>

This is very flexible... Now you can extend the layout system!!!

To create layout panels, have been covered extensively on the net, I will just quickly show the basics

public class MyCoolPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        // Size...
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        // Position
    }
}

[Tip] Use the Nerd + Art snippets here...

Derive from Panel and override MeasureOverride and ArrangeOverride! Now you have great control over how big the items can/should be and where thy will be positioned!!!

Here is a collection of the best custom layout panels I found on the internet:

PS. All of these panels source is also available!

FishEyePanel

Created by Paul Tallett

AnimatingStackPanel

Released as part of Mike Mars and Joe Stegman's talk at Mix '08 (Including the absolutely brilliant AnimatingPanelBase created by Robby Ingebretsen)

[NOTE] This panel has animation so I will not post a screen cap of this... run the attached application to see this panel in action!

FanPanel

Also by Paul Tallett

The FanPanel, as the name suggests, fans the items out into their position... all the items are fanned out into a wrap panel!

[NOTE] This panel has animation so I will not post a screen cap of this... run the attached application to see this panel in action!

LayeredStackPanel

Created by Nick Thuesen

RadialPanel

Created by Henry Hahn

[UPDATE] also check out this excellent article by Jobi about radial panels!!!

Panel3D

Created by Josh Smith

DiagonalPanel

Created by

 

TimelinePanel

Originally created by Rob Zelt (Part 1 & Part 2). Later released as part of blendables layout mix

PS. The blog only had a partial implementation and no source code so I implemented the rest...

ElementFlow

Created by Pavan Podila and released as part of the FluidKit

AnimatingCOSPanel

Created by Rudi Grobler

 

ColumnedPanel

Created by Sacha Barber

SpanningStackPanel

Created by Nick Thuesen

AnimatedWrapPanel

Created by Paranoid Ferret Productions

[NOTE] This panel has animation so I will not post a screen cap of this... run the attached application to see this panel in action!

AnimatingRadomCanvas

Created by Rudi Grobler (Based on AnimatingPanelBase)

[NOTE] This panel has animation so I will not post a screen cap of this... run the attached application to see this panel in action!

Here is the showcase application (including source)

[UPDATE] the link is now fixed Embarrassed

If you found the article useful, please kick it on DotNetKicks.com

Cool style/themes for controls

If you haven't seen the excellent control skins released by Corrina Barer (A designer on the Silverlight team), have a look here:

Bubbly

Red

Flat

Rough (This one is very cool)

I converted the rough skin to WPF without any major issues!

I will convert the others also and then post the source (Hopefully with permission from Corrina?)

If you are in the market to buy some control themes for WPF, here are some:

Infragistics Theme Packs

Reuxables

Posted by rudi | 4 comment(s)
Filed under: , ,

The Code Project articles update

The Code Project is arguably the biggest source of developer-focused content... Thy have just crossed the 5,000,000 registered users mile stone!

I recently released 2 new CP articles:

OpenXML + FlowDocument = OpenFlowDocument-

AdventureWorks.WPF (Part 1)

Here is a list of other WPF related articles recently released

Dr WPF

Conceptual Children- A powerful new concept in WPF

Sacha Barber

Fun With Physics

Karl Shifflett

WPF Business Application Series Part 3 of n - Business Object Declarative Programming

Josh Smith

Animating Interactive 2D Elements in a 3D Panel

Markus (not sukram)

WPF Diagram Designer - Part 3

More information about The Code Project:

The Code Project is hosted on 15 web servers running Windows 2003 R2. Each box has between 1 and 2 Gb RAM and runs standard hyperthreaded P4s. The web servers connect to 2 dual-proc, dual-core SQL servers running SQL 2005 and Win 2003. Networking is via dual gigabit NICs. We have 3 email servers, a couple of Active Directory servers, a big backup monstrosity, a handful of switches and about 10km of cabling. The server rack is warm to the touch.

  • 99.9% of site visitors (about 4.1 million) are currently, actively engaged in development projects
  • 98% (about 4.0 million) download products for evaluation
  • 71% (about 2.9 million) use C#
  • 54% (about 2.2 million) use ASP.NET
  • 37% (about 1.5 million) use VB.NET ***
  • 99.5% (about 4.1 million) develop for Windows
  • 26% (about 1.1 million) use Linux, Apache, MySQL, PSP, et al
  • 66% (about 2.7 million) have a developer/senior developer title
  • 30% (about 1.2 million) have an architect title
  • With 5,000,000 registered users and over 20,000,000 page views per month... The Code Project is still growing strong!!!

    Posted by rudi | 1 comment(s)
    Filed under:

    Why WPF Rock... (The content model)

    For the last week I was back in WinForms land... There is nothing making you appreciate the new stuff in WPF more than living without it for a week!!!

    Let me start by giving you some background... I had to make a fairly simple data logger for a client... the only problem is that I only had WinForms to use... I constantly found myself wondering why the hell thy don't have a content model!!!

    So, what is this content model and why should I care? In WinForms you have a button... very simple control with a specific purpose... Allow people to press it and perform a action based on this click! As you would expect, the button has a text property. This represents the text on the buttons face... Ok, now I need a picture inside the button... Ok, so lets add a image property... That will work... but what if I need to add a circle to this button... or even better, another button (To create a split button)... now the wheels start coming off!!! Yes, some of this is possible in WinForms, but it just feels like a afterthought! WPF is designed with this type of scenarios in mind! This is were the content model start coming in...

    Any control derived from ContentControl has a property called Content. Content is of the type object which implies that the content can be of any type... This is huge... You can potentially place anything inside a ContentControl! So, lets look at a few examples, lets create a button

    <Button />

    This just creates a very basic button, lets start slow:

    <Button Content="Hallo World!" />

    As expected, this creates a button with a string inside "Hallo World!". We will come back to this example because their are more underneath the surface... Have a look at the following button

    <Button>
        Hallo World
    </Button> 

    Ok, so this creates exactly the same results as the previous button! What can we deduct from this? We added the content here as if it was the child of the button... how does it know that it is content and not a child? The button's source code possible looks something like this:

    [ContentProperty("Content")]
    public class Button : ButtonBase
    {
        ...
    }

    Ok, so what's next... Let's try adding a visual element as my content

    <Button>
        <Ellipse Width="20" Height="20" Fill="Black" />
    </Button> 
    

    This is nice... now I can add shapes to my button... or can I? We have now hit one of the "limitations" of ContentControl... Content can only be a single object! This is easy to bypass... just add a panel and you object as children. Lets try adding 2 circles

    <Button>
        <StackPanel>
            <Ellipse Width="20" Height="20" Fill="Black" />
            <Ellipse Width="20" Height="20" Fill="Black" />
        </StackPanel>
    </Button> 
    

    So now we can add endless objects inside a ContentControl... (Remember that this is not "free" and their is a performance hit if you add to many controls). Lets look at the string example again. We added a object of type string as my content... how did it know how to display it? We will look at the rules of how this gets resolved in more detail later... but for now, all I will say is that if it is not a visual element, then it calls the ToString() of this object to render it!

    Lets make it a little more complicated, here is my button

    <Button x:Name="MyButton" />

    All I did is give my button a name... the next step will happen in the code behind... I created a very simple Person class

    public class Person
    {
        public string Name { get; set; }
        public string Surname { get; set; }
    }

    And then add the following in the Loaded event

    Person me = new Person() { Name = "Rudi", Surname = "Grobler" };
    MyButton.Content = me;

    What will be displayed now? Same rules still apply... ToString() returned WpfApplication1.Person. Ok, lets override the ToString()

    public override string ToString()
    {
        return Name + " " + Surname;
    }

    Now my button shows "Rudi Grobler". Great, so if it is not a visual element, then it uses the ToString() of the object!

    For what ever reason, I want a circle in between the name and surname (Try this with WinForms?).

    <Button x:Name="MyButton">
        <Button.ContentTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}" />
                    <Ellipse Width="15" Height="15" Fill="Black" />
                    <TextBlock Text="{Binding Surname}" />
                </StackPanel>
            </DataTemplate>
        </Button.ContentTemplate>
    </Button>
    

    WOW!!!

    Lets break this down... Now the ToString() gets ignored, why? DataTemplate!!!

    What is a DataTemplate?

    A data template is a piece of UI that you'd like to apply to a arbitrary .NET object when it is rendered.

    Ok, what have we learned about the ContentControl so far?

    1) If the ContentControl has a DataTemplate defined, use it

    2) If the content is a visual element (derived from UIElement), render it using UIElement.OnRender()!

    3) DataTemplate with matching DataType found (up the visual tree), use it

    4) Use the objects ToString()

    ContentControl is amazing...

    So, what else does a ContentControl have? It has a property called HasContent... Why does it have a property called HasContent, if I can just as easily check by using Content == null?

    This is the WPF way... This allows easily checking for content from XAML... Now you can animate based on if a control has content, etc?

    What if my Content is a collection of .NET managed objects? Have a look at the ItemsControl... Dr WPF has a excellent series covering the ItemsControl in detail (or has he put it, from A to Z)

    ItemsControl - 'A' is for Abundance

    ItemsControl - 'B' is for Bet You Can't Find Them All

    ItemsControl - 'C' is for Collection

    ItemsControl- 'D' is for DataTemplate

    ItemsControl- 'P' is for Panel

    ItemsControl- 'I' is for Item Container

    ItemsControl- 'R' is for Rob has a Customer

    If you need to see the power of the content model, read 'R' is for rob has a Customer and check out the split button he created!

    Posted by rudi | 6 comment(s)

    My embedded blog

    Well, I finally had a chance to get my embedded blog up and running...

     If you have any intrest in Windows CE or Windows XP Embedded please visit my new blog here:

     http://rudigrobler.wordpress.com/

     

    Posted by rudi | with no comments
    Filed under: