Thursday, September 27, 2007

Ironic, isn't it?

Microsoft Windows

The screenshot says it all ...

Tuesday, September 18, 2007

Installing Ubuntu

I just installed Ubuntu feisty 64bit on one of the computers. For those of you who happen to know the story about that particular computer it might seem somewhat ironic, but that's not the point of this post.

The installation was *smooth*, I just entered:

  • partitioning info (yes, use all available disk)
  • keyboard layout
  • timezone
  • user account info

and that's all. After a few minutes I asked to reboot out of the livecd and into the new installation and everything just worked! (Well except for my slightly odd screen resolution of 1440x900, but I can live with that)

Anyone can manage such an installation, and excessive OK button clicking.

Kudos Ubuntu!

Thursday, September 13, 2007

Enumerating XAML (BAML) files in an Assembly

I wanted to play around with XAML Pages, and wanted an application that automagically showed me a list of all included (embedded) XAML files in an assembly without me doing more than adding the XAML file to the project.

This turned out to be tricky until you got it...

Well, it is simple when you know how to do it, but until then you'll have some googling to do. (At least that is  my experience)

Basically, a XAML file with a build action of Page or Resource ends up in a .resources file named <assemblyname>.g.resources. This .resources file contains the binary version of the XAML file (BAML).

Enumerating the contents of a .resources file can be done using the System.Resources.ResourceReader class as follows:

using (ResourceReader reader = new ResourceReader("Foo.g.resources"))
{
foreach (DictionaryEntry entry in reader)
{
Console.WriteLine(entry.Key);
}
}

So all that's left to do is to create the application, (and no, it ain't pretty but it works):


MainForm.xaml:

<Window x:Class="AutoToc.MainForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=system"
Title="AutoToc" Height="400" Width="600" Loaded="FormLoaded"
>
<
Window.Resources>
<
HierarchicalDataTemplate DataType="{x:Type sys:Uri}">
<
BulletDecorator VerticalAlignment="Center">
<
BulletDecorator.Bullet>
<
Ellipse Fill="BlueViolet" Width="5" Height="5"
VerticalAlignment="Center"/>
</
BulletDecorator.Bullet>
<
TextBlock Text="{Binding Path=OriginalString}"
Margin="5,0,0,0" VerticalAlignment="Center" />
</
BulletDecorator>
</
HierarchicalDataTemplate>
</
Window.Resources>
<
Grid>
<
Grid.ColumnDefinitions>
<
ColumnDefinition Width="200"/>
<
ColumnDefinition Width="Auto"/>
<
ColumnDefinition Width="*"/>
</
Grid.ColumnDefinitions>
<
TreeView Grid.Column="0" Name="tocTree"
ItemsSource="{Binding}"
SelectedItemChanged="tocTreeSelectedItemChanged"></TreeView>
<
GridSplitter Grid.Column="1" Width="2" HorizontalAlignment="Left"
VerticalAlignment="Stretch"/>
<
Frame Name="contentFrame" Grid.Column="2" NavigationUIVisibility="Hidden"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</
Grid>
</
Window>

and the interesting parts of the code behind:

private void FormLoaded(object sender, RoutedEventArgs e)
{
// UriCollection inherits ObservableCollection<Uri>
UriCollection pages = new UriCollection();
Assembly asm = Assembly.GetExecutingAssembly();
Stream stream = asm.GetManifestResourceStream(asm.GetName().Name + ".g.resources");

DataContext = pages;
using (ResourceReader reader = new ResourceReader(stream))
{
foreach (DictionaryEntry entry in reader)
{
// for some curious reason, we get "cannot locate resource"
// if we leave the .baml extension, it needs to be .xaml !?!
pages.Add(new Uri(((string)entry.Key).Replace(".baml", ".xaml"),
UriKind.Relative));

}
}
}

private void tocTreeSelectedItemChanged(object sender, RoutedEventArgs e)
{
contentFrame.Source = tocTree.SelectedItem as Uri;
}

That was easy, wasn't it?


Obviously this is not production quality code but more a proof of concept, and yes, I do use it for playing around with the 3D samples...


Obviously, it would be better to filter out non-Page xaml files, such as mainform ...

Thursday, September 06, 2007

DiffuseMaterial.Color vs DiffuseMaterial.Brush

I've been getting my feet wet with 3D in WPF lately, as I've been reading the new Petzold book 3D Programming for Windows.

It's too early to give any review of the book yet, but back to the subject matter:

As I was trying the examples out I was just getting emptiness !?! I suspected I had screwed up either the MeshGeometry.Positions and/or camera directions so those I checked first, and found no differences.

I looked at my code, and nothing jumped out as wrong.

When I looked closer I noticed that I'd been using DiffuseMaterial.Color instead of DiffuseMaterial.Brush

According to MSDN:

Brush: "Brush to be applied as a Material to a 3-D model."

Color: "The color allowed to emit from the Material. The default value is #FFFFFF. Since all colors make up white, all colors are visible by default."

Obviously? .Color was the wrong choice.

It seems I've got plenty to learn ...