November 2006 - Posts

Anonymous Comments Enabled

I didn't notice that when I set up the blog, anonymous comments were disabled!

I just enabled them, and I hope this won't lead to a spam attack. Maybe I should add a captcha, though I don't care much for that method.

Anyway, now you can feel free to comment on my posts. :P

 

Update: Comment spam was unbearable... Added this captcha. Still have hundreds of junk comments to delete :-|

Posted by aelij with no comments
Filed under:

I Got Rhythm Now Available in XBAP!

This is not quite ready, but I just had to give you a sneak peek:

http://arbel.net/blogx/blog.xbap

I believe this is the first blog presented in XBAP. The possibilities are endless... The tag cloud uses Kevin Moore's Bag-O-Tricks. The HTML is being rendered by a modified version of the Windows SDK Team's HTML to Flow Document converter.

I've written a Community Server web service that allows me to pull all the data and bind to it.

Note that this was compiled in RC1 (waiting for Vista RTM in MSDN) but it seems to work on .NET 3.0 RTM.

Posted by aelij with 2 comment(s)
Filed under: , ,

Monopolij: Avalon* Edition

First - great news. .NET Framework 3.0 has finally been released. Get it now!

Monopolij was an app I wrote trying to win a free ticket to PDC'05 (you can download it at that post.) It had a special theme, as you can see in the screenshot... I thought it was a lot of fun to play as Bill. :-)

So, I've decided to migrate this game to .NET 3.0. It's proving to be quite interesting. I'm going to use WCF for communication (the original version used TcpClient, so there's much work to be done.) This will also enable me to try the peer to peer binding for the first time. Automatic peer discovery is kinda cool.

I'll also add different themes, animations and all sorts of WPF pyrotechnics we all love so much.

If anyone has any feature requests, I'll be happy to hear them.

 

* Avalon was WPF's codename. I'm just being nostalgic... And you have to admit it's a cooler name.

Posted by aelij with 1 comment(s)
Filed under: ,

Revamped Style Snooper

Update: This utility has become a bit irrelevant since Reflector now has a BAML Viewer add-in. You can use it to view any assembly containing BAML resources, which it will automatically decompile into XAML.

Style Snooper (or StyleSnooper?), originally posted by Lester, is a tool that can extract control styles from a compiled assembly. Quite useful to take a peek at someone else's work. :-)

I added a couple of features:

  • Switch to a FlowDocumentScrollViewer to view the style (much handier than a plain old TextBox; just try hitting Ctrl+F.)
  • Primitive syntax-coloring.
  • A bit of glass.
  • And the feature that made me start tinkering with this tool to begin with – load other assemblies.
  • I also fixed the TargetType property to use the proper Type MarkupExtension ({x:Type …}) and removed the IsPublic restriction from the type list.

P.S. If you're wondering about my wallpaper, it's "Song of the Sky" from Digital Blasphemy. It used to be in the free gallery, but isn't anymore. It's very reminiscent of Vista's Aurora.

Posted by aelij with 3 comment(s)
Filed under: ,

Forcing WPF to use a specific Windows theme

WPF comes with a few theme assemblies, one for each Windows theme (Luna, Royale and Aero and the fallback theme, Classic.) Usually the theme is loaded according to your current system theme, but if you want to create a consistent look for your application, you may want to force-load a specific one.

To accomplish that, simply add the following code in your Application Startup event (this example shows how to use the Aero theme):

Uri uri = new Uri("PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\\themes/aero.normalcolor.xaml", UriKind.Relative);

Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

It's important to specify the version and the public key token. Otherwise you'll have to copy the theme assembly to the folder of your executable. The reason I'm adding it to the merged dictionaries collection is that I don't want to lose other resources I added to the App.xaml file.

I usually put this code in a try…catch block (with an empty catch) since it doesn't really impair the application's functionality if it fails to execute.

Last note: From my experience, Windows Server 2003 always shows the Classic theme in WPF (even if you activate the Windows Themes service), so if you're deploying applications for that platform, you may want to use this trick (you will also want to turn on your display adapter's hardware acceleration and the DirectX accelerations, as they are disabled by default in 2003.)

Edit: Robby Ingebretsen (notstatic.com) also blogged about this because the new Zune theme, which caused WPF to fallback to the Classic theme. However, he placed the code in XAML. Here is a version of that using merged dictionaries (which will allow you to add other resources to App.xaml):

<Application.Resources>
    <
ResourceDictionary>
        <
ResourceDictionary.MergedDictionaries>
            <
ResourceDictionary Source="/PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\themes/aero.normalcolor.xaml" />
        </
ResourceDictionary.MergedDictionaries>

        <!-- other resources go here -->

    </
ResourceDictionary>
</
Application.Resources>

Update: The Orcas designer seems to be having problems with the relative URI. Using an absolute URI solves the issue: (I've also attached a sample Orcas project)

pack://application:,,,/PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\themes/aero.normalcolor.xaml

Posted by aelij with 23 comment(s)

Ælij’s Little Helpers

During my experiments with WPF, I sometimes encountered a recurring operation that required too much code (in my opinion.) So I did what every well-informed developer would: I encapsulated it into helper classes. Here are some of them:

Dependency Helpers

DependencyProperty GetDependencyProperty(DependencyObject o, string propertyName)
Retrieves a dependency property according to its name.

Binding Helpers

void UpdateSourceDefaultProperty(DependencyObject o)
If you ever set UpdateSourceTrigger of a Binding to Explicit, you may have felt it was a bit tedious to create the BindingExpression every time and call the UpdateSource() method. I realized that in many of the cases, the dependency property I'm updating is actually the default (or the content) property that the control author tagged using an attribute. So, instead of:

BindingExpression exp = BindingOperations.GetBindingExpression(TheTextBox, TextBox.TextProperty);
exp.UpdateSource();

We get:

UpdateSourceDefaultProperty(TheTextBox);

Storyboard Helpers

public static void Reverse(Storyboard storyboard)
Reverses the To and From properties of each linear AnimationTimeline in a Storyboard.

public static Storyboard GetReversed(Storyboard storyboard)
Clones the Storyboard and reverses it.

public static TAnimation AddLinearAnimation<TAnimation, T>(Storyboard storyboard, PropertyPath path, T? from, T? to, Duration duration)
Creates and adds a linear AnimationTimeline to a Storyboard. This one also saves quite a few lines. For example, instead of:

DoubleAnimation anim = new DoubleAnimation(from, to, new Duration(TimeSpan.FromSeconds(1)));
Storyboard.SetTargetProperty(anim, new PropertyPath(Control.OpacityProperty));
story.Children.Add(anim);

We get:

AddLinearAnimation<DoubleAnimation, double>(story, new PropertyPath(Control.OpacityProperty), from, to, new Duration(TimeSpan.FromSeconds(1)));

The one drawback of all of these methods is the use of Reflection. Had DoubleAnimation inherited from LinearAnimationBase<double> (see previous post) the use of Reflection could have been spared. :-)

Posted by aelij with no comments
Filed under:
More Posts