March 2008 - Posts

Keeping track of open windows in WPF

Hopeful by now, everybody has seen the Lawson Smart Client created by Frog Design? If not, have a look here:

Read more about it here

I love the look and feel of this application, the part that looked trick to me thou was the list of open windows at the top. This created the feel of a MDI application but just so much nicer!!!

So, how difficult is it to reproduce this?

I initially had 3 plans to reproduce this:

First I tried binding to Application.Current.Windows but this did not work! Next thing that came to mind for me was to create a new Window class derived from the standard Window. Each window created based on this Window can then register and de-register itself from a ObservableCollection somewhere! This will work but come on, this is WPF... their must be some cool way of doing this!

My Solution #3

If you are not familiar with Attached Properties first read this article

I created a attached property called WindowViewState.IsManaged? Just set this to true and the window will automatically be registered and de-registered! Sounds great but show me the code!

First I needed to create a WindowViewStateInstance, all this does is remember the friendly name of window (to be showed in the ListBox) and a VisualBrush to show a icon of the current window (Similar to vista's bottom preview).

public class WindowViewStateInstance
{
    public string Title { get; set; }
    public VisualBrush Icon { get; set; }
}

Next step is to create a WindowViewStateManager that stores all the instances

public class WindowViewStateManager
{
    static private WindowViewStateManager instance;
    static public WindowViewStateManager Instance
    {
        get
        {
            if (instance == null)
                instance = new WindowViewStateManager();

            return instance;
        }
    }

    ObservableCollection<WindowViewStateInstance> windowViewStates;
    public ObservableCollection<WindowViewStateInstance> WindowViewStates
    {
        get { return windowViewStates ?? (windowViewStates = new ObservableCollection<WindowViewStateInstance>()); }
    }

    public bool RemoveWindowViewState(string Title)
    {
        var view = (from v in windowViewStates
                    where v.Title == Title
                    select v).First();

        if (view != null)
        {
            windowViewStates.Remove(view);
            return true;
        }
        return false;
    }
}

These two classes are very simple but thy form the backbone of this application!

Disclaimer: I currently use the Window.Title as my key to remove the window from my list... I know this is not great, but it works!

Update: I added a Identifier property that gets set automatically to a unique Guid. This is now used to identify each window!

Next is the Attached Properties... I highly recommend downloading Dr WPF's snippets to create DPs and APs! It makes your live so much simpler! Here is my AP

public class WindowViewState
{
    public static readonly DependencyProperty IsManagedProperty =
        DependencyProperty.RegisterAttached("IsManaged", typeof(bool), typeof(WindowViewState),
            new FrameworkPropertyMetadata((bool)false,
                new PropertyChangedCallback(OnIsManagedChanged)));
    
    public static bool GetIsManaged(DependencyObject d)
    {
        return (bool)d.GetValue(IsManagedProperty);
    }

    public static void SetIsManaged(DependencyObject d, bool value)
    {
        d.SetValue(IsManagedProperty, value);
    }

    private static void OnIsManagedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Window target = (Window)d;
        if (target != null)
        {
            target.Loaded += new RoutedEventHandler(target_Loaded);
            target.Closed += new EventHandler(target_Closed);  
        }
    }

    static void target_Closed(object sender, EventArgs e)
    {
        Window target = (Window)sender;
        if (target != null)
        {
            WindowViewStateManager.Instance.RemoveWindowViewState(target.Title);
        }
    }

    static void target_Loaded(object sender, RoutedEventArgs e)
    {
        Window target = (Window)sender;
        if (target != null)
        {
            WindowViewStateInstance instance = new WindowViewStateInstance();
            instance.Title = target.Title;
            instance.Icon = new VisualBrush(target);

            WindowViewStateManager.Instance.WindowViewStates.Add(instance);
        }
    }   
}

And that is it! My attached property creates a Loaded and Closed event handler for the window that adds or removes the window instance from my list!

The attached properties makes adding this type of management of windows very easy

local:WindowViewState.IsManaged="true"

All that is now left to do is restyle my ListBox slightly and here is the result

Disclaimer: My windows that I open is just jpgs downloaded from the net of various WPF applications!

OK, so my design skills suck... but it is functional and it is a great way to keep track of all your windows currently open!

I still have loads of work to make it better but this is at least a very good starting point!

Posted by rudi | 3 comment(s)

ReMix South Africa

Now that MIX is over, the presentation goes on the road and it's coming to to South Africa soon... So, keep 24 June 2008 open!!!

Mix 08's sessions are also available for download here

"MIX Essentials and ReMIX events bring you the latest news from MIX08 held in Las Vegas. See global and local best practices and engage with key players and designers.
MIX Essentials are concise events. MIX distilled to its essence.
ReMIX events scale to larger audiences."

Posted by rudi | with no comments

WPF Bootcamp 2008

Does anybody still remember WPF Bootcamp 2007... Well, IT'S BACK!

The new videos for the WPF Bootcamp is now available for download here

Tracks include:

What a line-up!!!

kick it on DotNetKicks.com
Posted by rudi | 1 comment(s)

10 things I didn't know about WPF data binding

I am busy creating a nTier WPF app that rely very heavy on binding... here are some of the less obvious things I have learned about data binding in WPF

1) Binding path "(TextBox.Text)" vs "Text"?

If you bind to a path called Text, WPF uses reflection to resolve the name. If you use the class-qualified name, binding avoids the reflection performance hit. Class-qualified names also allows binding to attached properties!

2) WPF doesn't raise exceptions to notify you about data binding problems

All binding errors are output as trace information and NOT exceptions!

Beatriz Costa (Who else) has a excellent article about this

3) Why use OneWayToSource binding mode?

Well, the target object must always be a DP! The most common use of OneWayToSource mode is to by-pass this restriction! The source doesn't need to be a DP and effectively using OneWayToSource reverses the binding direction.

A perfect example is Run, it's text property is not backed by a DP!

4) Default binding mode?

Not all DP's have the same default binding mode!!!

If the binding mode is two-way, but the CLR property that it is bound to is read-only... will cause problems! just keep in mind that you can't assume what the binding mode is!!!

It is always a good idea to explicitly specify your binding mode. Also remember that OneWay is slightly lighter than TwoWay!

5) RelativeSourceMode.PreviousData

If you bind to a collection of prices and need to show the change from the previous price to the current price then this little trick can be very useful... Pass the current item and the following binding into a IMultiValueConverter converter

{Binding RelativeSource={RelativeSource PreviousData}}

The multi value converter now just need to work out what the difference is!

6) RelativeSourceMode.FindAncestor

This is a very cool hack I found... Lets assume that you have a ListBox showing data. Normally if you have a TextBlock inside your DataTemplate and you don't supply it with a foreground color, then it would inherit the parents Foreground property. What is cool about this is that then when you click on the item, the font color would change from black to white! Now assume that your DataTemplate also contains a custom control that do not rely on the Foreground property to determine its color (As a example, I will use a Ellipse which has a Fill and not a Foreground/Background). If I add a Ellipse to this DataTemplate and  I do not set its fill, it would stay blank. Even if I give it a Fill color, it will fill with this color but if I now select this ListBox item, it will stay the provided color!

So how do I make my ellipse inherit the Foreground color and more importantly, how do I make it change to white once selected? Binding its Fill with the following

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=Foreground}

Now, it will inherit the parents Foreground and also change once selected...

7) Binding a ListBox to a custom object, What gets displayed in the ListBox?

When binding to a custom object, determining what is displayed in the ListBox can be one of 3 options

  1. Set the DisplayMemberPath on the ListBox to a path
  2. Create a DataTemplate
  3. Override the ToString() on the custom object. If no DisplayMemberPath or DataTemplate is found, the ToString() is called on the custom object.

8) {Binding Path=/}

Bind to the current item in the view! Just remember to set IsSynchronizedWithCurrentItem to true

[UPDATE] While reading Ian Griffiths blog, I found a entry detailing this behaviour in WPF databinding

9) Binding has a constructor that take Path as a parameter

This is just a small shortcut

{Binding Path=Name}

Can be written like this

{Binding Name}

10) {Binding}

This looks a little weird but all this means is that the source is defined somewhere up the tree... common place is Window.DataContext. By setting the DataContext to a collection, I can now add a ListBox to the visual tree and then binding this ListBox's ItemsSource to {Binding}. This will tell the ListBox that its ItemsSource is the DataContext of the Window!

Posted by rudi | 10 comment(s)

Aggregating Feeds using CompositeCollection

While reading Adam Nathan's WPF Unleashed, I noticed a interesting collection class called CompositeCollection. This effectively allows you to make multiple collections appear as a single collection. To try it out, RSS immediately came to mind. Image I have multiple RSS feeds but want to show all of them in my main view...

A while back I mentioned some WPF blogs I read... I will take each of these blogs feeds and composite it into a single collection (All from XAML)

Here is the separate feeds for Josh Smith, Karl Shifflet, Sacha Barber & Dr WPF

<XmlDataProvider x:Key="DrWPFFeeds" d:IsDataSource="True" Source="http://www.drwpf.com/blog/Home/tabid/36/rssid/1/Default.aspx">
    <XmlDataProvider.XmlNamespaceManager>
        <XmlNamespaceMappingCollection>
            <XmlNamespaceMapping Prefix="trackback" Uri="http://madskills.com/public/xml/rss/module/trackback/"/>
            <XmlNamespaceMapping Prefix="slash" Uri="http://purl.org/rss/1.0/modules/slash/"/>
        </XmlNamespaceMappingCollection>
    </XmlDataProvider.XmlNamespaceManager>
</XmlDataProvider>
<XmlDataProvider x:Key="JoshSmithFeeds" d:IsDataSource="True" Source="http://joshsmithonwpf.wordpress.com/feed/">
    <XmlDataProvider.XmlNamespaceManager>
        <XmlNamespaceMappingCollection>
            <XmlNamespaceMapping Prefix="dc" Uri="http://purl.org/dc/elements/1.1/"/>
            <XmlNamespaceMapping Prefix="atom" Uri="http://www.w3.org/2005/Atom"/>
            <XmlNamespaceMapping Prefix="media" Uri="http://search.yahoo.com/mrss"/>
            <XmlNamespaceMapping Prefix="wfw" Uri="http://wellformedweb.org/CommentAPI/"/>
            <XmlNamespaceMapping Prefix="content" Uri="http://purl.org/rss/1.0/modules/content/"/>
        </XmlNamespaceMappingCollection>
    </XmlDataProvider.XmlNamespaceManager>
</XmlDataProvider>
<XmlDataProvider x:Key="KarlShiffletFeeds" d:IsDataSource="True" Source="http://karlshifflett.wordpress.com/feed/">
    <XmlDataProvider.XmlNamespaceManager>
        <XmlNamespaceMappingCollection>
            <XmlNamespaceMapping Prefix="dc" Uri="http://purl.org/dc/elements/1.1/"/>
            <XmlNamespaceMapping Prefix="atom" Uri="http://www.w3.org/2005/Atom"/>
            <XmlNamespaceMapping Prefix="media" Uri="http://search.yahoo.com/mrss"/>
            <XmlNamespaceMapping Prefix="wfw" Uri="http://wellformedweb.org/CommentAPI/"/>
            <XmlNamespaceMapping Prefix="content" Uri="http://purl.org/rss/1.0/modules/content/"/>
        </XmlNamespaceMappingCollection>
    </XmlDataProvider.XmlNamespaceManager>
</XmlDataProvider>
<XmlDataProvider x:Key="SachaBarberFeeds" d:IsDataSource="True" Source="http://sachabarber.net/?feed=rss2">
    <XmlDataProvider.XmlNamespaceManager>
        <XmlNamespaceMappingCollection>
            <XmlNamespaceMapping Prefix="wfw" Uri="http://wellformedweb.org/CommentAPI/"/>
            <XmlNamespaceMapping Prefix="content" Uri="http://purl.org/rss/1.0/modules/content/"/>
            <XmlNamespaceMapping Prefix="dc" Uri="http://purl.org/dc/elements/1.1/"/>
        </XmlNamespaceMappingCollection>
    </XmlDataProvider.XmlNamespaceManager>
</XmlDataProvider>

PS. These blogs provide excellent material... If you are interested in WPF content you have to subscribe to them!

Next step is to take each of these feeds and composite it into a single collection

<CompositeCollection x:Key="Feeds">
    <CollectionContainer Collection="{Binding Source={StaticResource DrWPFFeeds}, XPath=/rss/channel/item}"/>
    <CollectionContainer Collection="{Binding Source={StaticResource JoshSmithFeeds}, XPath=/rss/channel/item}"/>
    <CollectionContainer Collection="{Binding Source={StaticResource KarlShiffletFeeds}, XPath=/rss/channel/item}"/>
    <CollectionContainer Collection="{Binding Source={StaticResource SachaBarberFeeds}, XPath=/rss/channel/item}"/>
</CompositeCollection>

Now my ListBox can bind to the data source Feeds and all of the separate blogs feeds will appear in one collection!!!

kick it on DotNetKicks.com
Posted by rudi | 7 comment(s)

Hosting agDotNetKicks using Silverlight Streaming

I had some request to host agDotNetKicks. I found Tim Sneath's article about hosting Silverlight 2.0 content using Silverlight Streaming and decided to try it!

To host a Silverlight 2.0 application is very easy...

1) Create a manifest file (Here is mine)

<SilverlightApp>
  <version>2.0</version>
  <source>agDotNetKicks.xap</source>
  <width>800</width>
  <height>600</height>
  <background>white</background>
  <isWindowless>false</isWindowless>
</SilverlightApp>

2) Take the previously create agDotNetKicks.xap and the manifest file (created in step 1) and zip it into 1 archive

3) Go to the Silverlight Streaming website and log in using Live ID

4) Click on Manage Applications and then Upload a Application

5) Give your application a name (I used agDotNetKicks)

6) Now upload the zip file created in step 2

That is all!!!

Very easy, now launch the Test Window to just test that everything worked!

To embedded your application you have 2 choices

1) Use the IFRAME (That is what I used)

2) Use a Live control

To see my application running, click here

PS. Please remember that the RSS feed doesn't provide all the rich data I need... As soon as I have the JSON stuff working, I will update this application!

kick it on DotNetKicks.com
Posted by rudi | 2 comment(s)

agDOTNETKICKS

I have to get my feet wet using Silverlight 2.0. What better way than creating a simple application? I decided to create a very simple dotnetkicks reader!

First things first:

1) Create a new silverlight 2.0 project using VS2008 (Blend 2.5 should also work)

2) Add a ItemsControl to the main page

<ItemsControl x:Name="ArticlesItemsControl" />

NOTE: I added a ItemsControl here because I don't need the selecting provided by the ListBox

3) Create a very basic RSS-like data structure to bind too for each article posted on DotNetKicks

public class Article
{
    public string Title { get; set; }
    public string Description { get; set; }
    public Uri Link { get; set; }
    public Uri KickUri { get; set; }
    public int Kicks { get; set; }
}

4) Asynchronously fetch the RSS feed from the DotNetKicks site

List<Article> _articles = new List<Article>();
const string feedUrl = @"http://feeds.feedburner.com/dotnetkicks?format=xml";

private void GetArticles(string url)
{
    WebClient wc = new WebClient();
    wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(articles_DownloadStringCompleted);
    wc.DownloadStringAsync(new Uri(url));
}

5) Parse the retrieved XML data

void articles_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    XDocument doc = XDocument.Parse(e.Result);

    foreach (XElement article in doc.Descendants("item"))
    {
        Article a = new Article();
           
        a.Title = (string)article.Element("title");
        // The rest of the parsing is removed to reduce complexity

        _articles.Add(a);
    }
    ArticlesItemsControl.ItemsSource = _articles;
}

Once the RSS feed has been parsed and all the articles are added to the List, set the ItemsSource on the ItemsControl!

6) All that is now left to do is to replace the ItemTemplate with our own custom DataTemplate

<ItemsControl x:Name="ArticlesItemsControl">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="10,0,10,10">
                <StackPanel>
                    <Border Background="Aqua" Width="50" Height="50" CornerRadius="5,0,5,0">
                        <StackPanel>
                            <TextBlock Text="0" FontSize="22" HorizontalAlignment="Center"/>
                            <TextBlock Text="Kicks" FontSize="10" HorizontalAlignment="Center" Foreground="#80000000"/>
                        </StackPanel>
                    </Border>
                    <Border Background="White" Width="50" Height="20" Margin="0,5,0,0" BorderBrush="Black" BorderThickness="1">
                        <HyperlinkButton Content="Kick It" NavigateUri="{Binding KickUri}" HorizontalAlignment="Center" VerticalAlignment="Center" />
                    </Border>
                </StackPanel>
                <StackPanel Margin="10,0,0,10">
                    <HyperlinkButton Content="{Binding Title}" NavigateUri="{Binding Link}" FontFamily="Trebuchet MS" FontSize="12" />
                    <TextBlock Text="{Binding Description}" TextWrapping="Wrap" FontFamily="Arial" FontSize="8.5" Height="Auto" />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

And here is the final result:

I am busy updating the example to use the JSON service provided... this will allow me to get a richer set of data back... As soon as I have it working, I will post it!

UPDATE: The app is now hosted using Silverlight Streaming, have a look here

kick it on DotNetKicks.com
Posted by rudi | 8 comment(s)

Easy Easing...

While watching Rick Barraza's Mix '08 session (T30), he showed "The Helvetica of Easing Equations™"

bob.X += (mouse.X - bob.X)  * 0.12

And this worked great for his scenario... I wanted to do something similar (but slightly simpler). I needed to move some buttons from off the screen to where thy need to be placed in my main window. I started by just doing a simple DoubleAnimationUsingKeyFrames. Just a side note, to reduce the code complexity, I replaced my menu bar with a single ellipse. Here is my ellipse (somewhere off screen)

<Ellipse Width="50" Height="50" Fill="#FFFF0000" Stroke="#FF000000" Canvas.Left="700" Canvas.Top="70" x:Name="ellipse" RenderTransformOrigin="0.5,0.5">
    <Ellipse.RenderTransform>
        <TransformGroup>
            <TranslateTransform X="0" Y="0"/>
        </TransformGroup>
    </Ellipse.RenderTransform>
</Ellipse>

And here is my animation to change the TranslateTransform's X property

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)">
    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="-500"/>
</DoubleAnimationUsingKeyFrames> 

This double animation will move the ellipse into view at a constant speed.

What if I need it to move in quick but slow down at the end (Easing)?

Their are 2 ways this can be achieved! Blend helps with the first method. Blend makes it easy to customize timelines. Open your time line and then right click on the second key frame. A new context menu appears that allow you to easily ease in or out!

I selected 75% easing in. Here is the spline graph

PS. You can also manually adjust the easing by manipulating the spline graph! (Here is a article on the Expression Teams blog about manually adjusting the easing)

Here is the code generated

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)">
    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="-500" KeySpline="0,0,0.625,1"/>
</DoubleAnimationUsingKeyFrames> 

All that changed is the addition of the KeySpline info generated!!!

The second but little more restrictive method is to use the AccelerationRatio and DecelerationRatio.

Here is a similar easing using the second method

<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" DecelerationRatio="0.75" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)">
    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    <SplineDoubleKeyFrame KeyTime="00:00:01" Value="-500"/>
</DoubleAnimationUsingKeyFrames> 

Easing is a very subtle effect but very usefully!!!

Posted by rudi | 1 comment(s)

Hosting a WCF Syndication Service in a Console

With the release of .NET Framework 3.5, WCF has been improved to include the creation of a Syndication Service. This effectively allow you to expose a service as a Plain-Old-XML (POX) service! I am currently developing a RESTful application that make use of this. I needed to host this service in a consol application... I could not find a easy solution on the internet. Let me start by just quickly showing how to create a syndication Library:

1) Create a new Project in VS 2008

2) Select WCF in the Project type and Syndication Service Library in the template and click on OK

This will will create a very basic service that exposes some dummy RSS data. To show the power of POX, I will make 1 change to this application

Replace that default created CreateFeed in the service contract with with the following:

[OperationContract]
[WebGet(UriTemplate = "*", BodyStyle = WebMessageBodyStyle.Bare)]
DateTime GetDate();

And here is the implementation

public DateTime GetDate()
{
    return DateTime.Now;
}

This was all that was required... the service takes care of the serialization of the object that I return! Run this and here is the result

That was easy... and the possibilities are now endless!!!

All I need to do now is host this service in a Console Application. Here is the code:

Uri address = new Uri("http://localhost:8000/");

WebHttpBinding binding = new WebHttpBinding();
ServiceHost svc = new ServiceHost(typeof(Feed1),new Uri("http://localhost:8000/"));
ServiceEndpoint ep = svc.AddServiceEndpoint(typeof(IFeed1), binding, "Feed");


ep.Behaviors.Add(new WebHttpBehavior()); 
svc.Open();

Console.WriteLine("Waiting for connections...");
Console.ReadLine();

svc.Close();

To make this work you must add a WebHttpBehavior to the end point's behaviours!!!

Now my service is hosted in a normal console application...

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

WPF Snippets

Snippets is one of the coolest features of VS. To increase productivity using WPF, the following 2 snippets must be in your collection:

Dr WPF's Dependency Properties

Dr WPF has a excellent collection of snippets to create various dependency properties and attached properties. This is a very complete set including creating DP's with default values, framework property options, property changed events, etc...

Available from here

IdentityMine's Nerd+Art

IdentityMine, creators of blendables, released 10 very cool snippets (Nerd+Art)... including creating custom controls, adding sounds, creating custom panels, modifying storyboards, etc...

Available from here

kick it on DotNetKicks.com
Posted by rudi | 7 comment(s)
Filed under:

CodeProject Article

I just released another CodeProject article. This article describes how to restyle a standard WPF TabControl to look like the Navigation Pane from Outlook 2007!

2 of my articles is also published on WindowsClient.net

Posted by rudi | 1 comment(s)

Information Overload

I don't know about you but today has been a total information overload for me...

Ok, so let start at the beginning... Mix '08 started yesterday and with it came loads of new releases:

  • Internet Explorer 8 Beta 1
  • Silverlight 2 Beta 1 Runtime
  • Silverlight 2 Tools for Visual Studio 2008 and SDK
  • Source Code / Unit Tests for Silverlight 2 Controls
  • Expression Studio 2 Beta (contains Blend, Design, Encoder, Media and Web)
  • Expression Blend 2.5 March 2008 Preview

Here are all the links

Want to see what Silverlight 2.0 can do? Have a look at the awesome demo by AOL. Thy made a Silverlight 2.0 client for their mail service. It is skinnable (Cool Halo 3 skin), super fast (uses isolated storage for local caching) and much more...

It is available here

What is DeepZoom? a new Silverlight feature based on the Seadragon research project that provides scalable image zooming - you can take a 2 billion pixel image, and zoom right into it without downloading gigabytes of pixel data locally. You can also use this to filter many images and navigate around them. Showing how this is used for the Hard Rock website to navigate throughout their memorabilia. This Silverlight 2 site is live right now, here: http://memorabilia.hardrock.com/.

Their is also a video interview with the developers of this site available here

What's new in IE 8?

  • CSS 2.1
  • CSS Certification
  • Performance
  • HTML 5 early support
  • Developer tools
  • Activities
  • WebSlices

Here is a video that demos the activities and WebSlices!

Also keep an I on this website, all the sessions will be posted here 24 hours after it happened... The first should be posted later today!

And it doesn't stop at mix, Josh Smith has released the much anticipated Podder V2 (Including a great skin created by visual designer Grant Hinkson)

Here is the official notice on Josh and Grant's websites and here is the CodeProject article. The article also include a video demo of Podder. I have to say I absolutely love the new skin... The coolest feature is the dynamic changing of the background color based on the average color of the current selected podcast's image!!! Very cool stuff... The article also talks about structural skinning, dynamic loading skins, etc...

[UPDATE] IdentityMine has also released 2 new products: Blendables Layout Mix and Blendables 3D Mix!

kick it on DotNetKicks.com
Posted by rudi | 3 comment(s)

Review: Blendables Layout Mix

The Blendables team has done it again... Thy released two new packages just as mix is about to start (Talk about perfect timing). I decided to start by reviewing the Blendables Layout Mix package first...

As the name suggest, this is a collection of layout panels...

RadialCanvas

RadialCanvas lays all its items out in a radial pattern. The center point is configurable.

<bl:RadialCanvas Center="0.5,0.5">

</bl:RadialCanvas> 

Each item in the panel's angle and radius can also be set using attached properties.

RandomPanel

RandomPanel lays all the items out in a random pattern. Each item's width and height is also set randomly. The minimum and maximum width or height can be restricted.

<bl:RandomPanel MinimumHeight="50" MinimumWidth="50">

</bl:RandomPanel> 

PerspectivePanel

PerspectivePanel lays each child item out in perspective to each other. Every subsequent child will be scaled based on the provided ScaleFactorX and ScaleFactorY

<bl:PerspectivePanel ShiftX="100" ShiftY="100" ScaleFactorX="0.9" ScaleFactorY="0.9">

</bl:PerspectivePanel>

AutoStrectchStackPanel

AutoStrectchStackPanel is similar to the normal StackPanel, but each item in the stack panel's size is calculated based on the space available. A AutoStrectStackPanel will always show all its items in the allowed space!

<bl:AutoStretchStackPanel>
    
</bl:AutoStretchStackPanel>

I only had time to test some of the layout panels but their are more... I haven't even started with the SwitchPanel yet! From what I can understand, SwitchPanel allows changing the layout of a panel on the fly and even animating between layout?

This is very cool stuff from them... Next, I will review the Blendables 3D Mix...

Other Reviews:

kick it on DotNetKicks.com
Posted by rudi | 9 comment(s)
Filed under:

Control Authoring for dummies

Charles Petzold don't always use nice pictures to illustrate his WPF code (If you missed it look here) but he sure can explain! Lately I have been practicing create custom controls. When creating custom controls, you are sure to wonder: "from what should I derive?" The two top choices are Control vs FrameworkElement. What is the difference? Well, here is Mr Petzolds take on it:

"First, the Control class adds a collection of very handy properties to the FrameworkElement class, including Foreground, Background, and five font-related properties. Control doesn't use these properties directly—they're for the convenience of classes that derive from Control.

Second, the Control class adds IsTabStop and TabIndex properties, implying that controls often need to be stops in the tab-key navigation chain, while elements do not. In short, elements are for looking and controls are for interaction (but elements can still obtain focus and respond to keyboard, mouse, and stylus input).

Third, the Control class defines the Template property of type ControlTemplate. This template is mostly a visual tree of elemen