Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you port a theme from Silverlight to WPF?

It's "easy"!

I just came across this blog post by Rudi Grobler that says it's "easy" to port a theme from Silverlight to WPF. Unfortunately, he doesn't say how to do it.


Download and install

I have installed both the WPF Toolkit and Silverlight Toolkit from Codeplex.

I also went and dug up the source code for the theme I'm interested in (BureauBlue) (warning, this takes a little while to load), and pasted that into a fresh Resource Dictionary file in my test project.


Ut oh, broken references

Lots of blue squiggly lines.

alt text http://img32.imageshack.us/img32/6032/brokenreferences.jpg


No references here

So, I went to add the references and discovered...they aren't listed.

alt text http://img35.imageshack.us/img35/7466/addreferencedialog.jpg


Ahh, there they are

Fortunately, I was able to find them after some extensive browsing.

alt text http://img269.imageshack.us/img269/3830/addreferencedialogbrows.jpg


And so I added them

Having found the missing references, I attempted to add them. This actually seemed to resolve the broken xmlns links (at least the blue squiggly lines went away), but when I built my project I got an error:

Error 1 Unknown build error, 'Cannot resolve dependency to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' NmtConcept


And, so I ask...

How do I make a Silverlight theme work in WPF?


Update!

Well, I thought I figured it out. I decided to start with the DataGrid. I figured out what all the WPF equivalents were for the Silverlight assemblies, and I actually got my project to compile and run. And then I saw the result...

alt text http://img44.imageshack.us/img44/2418/porteddatagrid.jpg

The header is somewhat correct (except for the missing sort arrows), but the rest of it looks like there was some kind of horrible accident involving tan colored bricks.

Here's the example on the Silverlight Toolkit webpage.

alt text http://img196.imageshack.us/img196/997/silverlightdatagrid.jpg

So, I didn't even come close.


What I did

Please allow me to explain what I did to arrive at this mess.


DataGridFrozenGrid

First, I had to grab DataGridFrozenGrid from this Silverlight Toolkit source code page because WPF had never heard of such a class.


BureauBlue

Then I pasted in the key pieces from the source code for BureauBlue (again, warning: this baby is slow to load).

By key pieces, I mean:

  1. All the brush resources at the beginning of the file plus
  2. The Style for each of these controls:

    • DataGridColumnHeader
    • DataGridCell
    • DataGridRowHeader
    • DataGridRow

Strangely, the original file contained no style for the DataGrid itself (please correct me if I'm wrong, but I used Find and everything).


Silverlight --> WPF

Next, I converted the xmlns references to WPF equivalents. Here's how my ResourceDictionary element turned out:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mwc="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
    xmlns:mwcp="clr-namespace:Microsoft.Windows.Controls.Primitives;assembly=WPFToolkit"
    xmlns:swcp="clr-namespace:System.Windows.Controls.Primitives;assembly=CommonLibraryWpf"
    xmlns:sw="clr-namespace:System.Windows;assembly=WPFToolkit">

I of course edited the namespace tags to match.


Edit until it works

Once I had all this working, I still had a few minor problems. Some of the x:Name elements had spaces in them. The compiler wouldn't allow this, so I had to replace the spaces with underscores.

Here are the relevant snippets:

<!-- Important: all underscores used to be spaces -->
<sw:VisualState
    x:Name="MouseOver_CurrentRow_Selected">
<sw:VisualState
    x:Name="Normal_CurrentRow">
<sw:VisualState
    x:Name="Normal_Selected">
<sw:VisualState
    x:Name="Normal_EditingRow">
<sw:VisualState
    x:Name="Normal_AlternatingRow" />
<sw:VisualState
    x:Name="Normal_Selected">
<sw:VisualState
    x:Name="MouseOver_Selected">
<sw:VisualState
    x:Name="Unfocused_Selected">

Changing these names seemed like a very bad idea--and may be the cause of all my problems--but I didn't know what else to do to get the thing to compile.

The other change I had to make was: some of the SolidColorBrush and LinearGradientBrush items at the beginning used x:Name instead of x:Key. I changed all of them to x:Key. Perhaps this was also a bad idea, but again, the compiler made me.


Does this help you help me?

If you're still with me after all that, got any suggestions?

like image 565
devuxer Avatar asked Oct 23 '09 02:10

devuxer


1 Answers

I basically came to the conclusion that I was trying to fit a square peg into a round hole (despite claims that it's "easy"). The Silverlight DataGrid is just too different from the WPF Toolkit DataGrid. So, for the moment, I've just been trying to style the default data grid to look like BureauBlue. It's quite painstaking work and far from perfect, but it's a definite improvement over the ported style.

alt text http://img26.imageshack.us/img26/7163/styleddatagrid.jpg

like image 68
devuxer Avatar answered Nov 15 '22 08:11

devuxer