Please click this logo to help me get on their beta program:

Xobni outlook add-in for your inbox








31/3/2007

WPF: IntSequence helper class updated, including dependency properties

Filed under: General — Oliver Sturm @ 9:57 pm - 1 year, 4 months ago

This struck me right after my recent post about binding to arbitrary sequences: my helper class was implemented with traditional .NET properties, which isn’t optimal for use with WPF. One thing specifically isn’t good for my purpose, which is the fact that a “normal” property can’t be the target of WPF data binding. Like in this case:

<Window.Resources>
	<engine:Grid x:Key="gameGrid" />
	<helpers:IntSequence x:Key="rowDummyList" EndVal="{Binding Source={StaticResource gameGrid}, Path=RowCount}" />
</Window.Resources>

In this case I’m trying to bind the EndVal of the sequence to a value obtained from a different object, and that didn’t work using the standard properties. So I have created an updated version of the IntSequence class, which uses dependency properties to make this kind of binding possible. Here it is:

public class IntSequence : DependencyObject, IEnumerable<int> {
	public static readonly DependencyProperty StartValProperty;
	public static readonly DependencyProperty EndValProperty;
	
	static IntSequence( ) {
		StartValProperty = DependencyProperty.Register("StartVal",
			typeof(int), typeof(IntSequence), new PropertyMetadata(1));
		EndValProperty = DependencyProperty.Register("EndVal",
			typeof(int), typeof(IntSequence), new PropertyMetadata(10));
	}
	
	public int StartVal {
		get { return (int) GetValue(StartValProperty); }
		set { SetValue(StartValProperty, value); }
	}
	
	public int EndVal {
		get { return (int) GetValue(EndValProperty); }
		set { SetValue(EndValProperty, value); }
	}
	
	IEnumerator<int> IEnumerable<int>.GetEnumerator( ) {
		for (int val = StartVal; val <= EndVal; val++)
			yield return val;
	}
	
	IEnumerator IEnumerable.GetEnumerator( ) {
		foreach (int item in this)
			yield return item;
	}
}

WPF: Binding to a sequence

Filed under: General — Oliver Sturm @ 9:20 pm - 1 year, 4 months ago

In certain contexts I have always found it useful to bind to a sequence of numbers, or sometimes even just a dummy collection with a certain number of elements. It’s like a for-loop, just for data binding. I’ve found three good ways of doing that in XAML, as the following two source code snippets show:

<Window x:Class="WPFSequenceBinding.Window1"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:sys="clr-namespace:System;assembly=mscorlib"
	xmlns:local="clr-namespace:WPFSequenceBinding"
	Title="WPFSequenceBinding" Height="300" Width="300">
	<Window.Resources>
		<x:Array x:Key="list1" Type="{x:Type sys:Int32}">
			<sys:Int32>1</sys:Int32>
			<sys:Int32>2</sys:Int32>
			<sys:Int32>3</sys:Int32>
			<sys:Int32>4</sys:Int32>
			<sys:Int32>5</sys:Int32>
		</x:Array>
		<ObjectDataProvider x:Key="list2" ObjectType="{x:Type sys:Array}" MethodName="CreateInstance">
			<ObjectDataProvider.MethodParameters>
				<sys:Type>sys:Int32</sys:Type>
				<sys:Int32>5</sys:Int32>
			</ObjectDataProvider.MethodParameters>
		</ObjectDataProvider>
		<local:IntSequence x:Key="list3" StartVal="1" EndVal="5" />
	</Window.Resources>
	<StackPanel>
		<ListBox ItemsSource="{Binding Source={StaticResource list1}}" />
		<ListBox ItemsSource="{Binding Source={StaticResource list2}}" />
		<ListBox ItemsSource="{Binding Source={StaticResource list3}}" />
	</StackPanel>
</Window>
public class IntSequence : IEnumerable<int> {
	private int startVal = 1;
	public int StartVal {
		get { return startVal; }
		set { startVal = value; }
	} 
	
	private int endVal = 10;
	public int EndVal {
		get { return endVal; }
		set { endVal = vlue; }
	} 
	
	IEnumerator<int> IEnumerable<int>.GetEnumerator( ) {
		for (int val = startVal; val <= endVal; val++)
			yield return val;
	} 
	
	IEnumerator IEnumerable.GetEnumerator( ) {
		foreach (int item in this)
			yield return item;
	}
}

All these approaches come with their own advantages and disadvantages. The x:Array block can be defined completely in XAML and is obviously not restricted to sequential values. Then again, for a simple sequence, there’s a lot of typing and/or copying/pasting to be done and the result is extremely verbose. The ObjectDataProvider with the dynamically created array is an interesting approach, but the array is not actually initialized with values (so it contains a bunch of zeros) and the XAML code is also quite verbose. Finally the IntSequence looks great in XAML, but it requires a helper class, however simple. Well, there’s something for everyone here…

WPF: Bottom dwelling with an ItemsControl

Filed under: General — Oliver Sturm @ 8:50 pm - 1 year, 4 months ago

 Here’s something I just stumbled upon. Not quite intuitive, so I thought I’d write it down. Consider this piece of XAML (you can paste it into XamlPad to try it out):

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
	<DockPanel LastChildFill="False">
		<Button DockPanel.Dock="Bottom" Background="Yellow" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Red" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Blue" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Green" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Magenta" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Black" Content="X" />
		<Button DockPanel.Dock="Bottom" Background="Orange" Content="X" />
	</DockPanel>
</Page>

What it does is pretty obvious: it creates a bunch of buttons and docks them all to the bottom of the panel.

Now look at the following XAML. It uses an ItemsControl to create a dynamic structure based on data binding, that also contains a number of buttons. Similar to before, the buttons are children of a DockPanel and they have the DockPanel.Dock attribute attached and set to the value Bottom.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:sys="clr-namespace:System;assembly=mscorlib"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Page.Resources>
		<x:Array x:Key="sequence" Type="sys:Int32">
			<sys:Int32>1</sys:Int32>
			<sys:Int32>2</sys:Int32>
			<sys:Int32>3</sys:Int32>
			<sys:Int32>4</sys:Int32>
			<sys:Int32>5</sys:Int32>
			<sys:Int32>6</sys:Int32>
			<sys:Int32>7</sys:Int32>
			<sys:Int32>8</sys:Int32>
		</x:Array>
	</Page.Resources>
	<ItemsControl ItemsSource="{Binding Source={StaticResource sequence}}">
		<ItemsControl.ItemsPanel>
			<ItemsPanelTemplate>
				<DockPanel LastChildFill="False" />
			</ItemsPanelTemplate>
		</ItemsControl.ItemsPanel>
		<ItemsControl.ItemTemplate>
			<DataTemplate>
				<Button Content="{Binding}" DockPanel.Dock="Bottom" />
			</DataTemplate>
		</ItemsControl.ItemTemplate>
	</ItemsControl>
</Page>

If you paste this code into XamlPad, you might be as surprised as I was initially to find that this is the output:

So why is that? The answer can also be found in XamlPad, comparing an important part of the visual trees for both examples:

As you can see, the visual tree for the databound case is quite a bit more complex, and most importantly, the Button instances are wrapped in ContentPresenter instances before being included in the DockPanel. So the reason why the docking doesn’t work is because the DockPanel.Dock property is not attached to the actual children of the DockPanel!

Here’s the solution I found for this problem. It is possible to configure the style for the ContentPresenter that is wrapped around the items, and to attach the property to it instead of the Button itself. The ItemsControl has a property called ItemContainerStyle, and it can be used like this:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:sys="clr-namespace:System;assembly=mscorlib"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Page.Resources>
		<x:Array x:Key="sequence" Type="sys:Int32">
			<sys:Int32>1</sys:Int32>
			<sys:Int32>2</sys:Int32>
			<sys:Int32>3</sys:Int32>
			<sys:Int32>4</sys:Int32>
			<sys:Int32>5</sys:Int32>
			<sys:Int32>6</sys:Int32>
			<sys:Int32>7</sys:Int32>
			<sys:Int32>8</sys:Int32>
		</x:Array>
	</Page.Resources>
	<ItemsControl ItemsSource="{Binding Source={StaticResource sequence}}">
		<ItemsControl.ItemsPanel>
			<ItemsPanelTemplate>
				<DockPanel LastChildFill="False" />
			</ItemsPanelTemplate>
		</ItemsControl.ItemsPanel>
		<ItemsControl.ItemTemplate>
			<DataTemplate>
				<Button Content="{Binding}" />
			</DataTemplate>
		</ItemsControl.ItemTemplate>
		<ItemsControl.ItemContainerStyle>
			<Style>
				<Setter Property="DockPanel.Dock" Value="Bottom" />
			</Style>
		</ItemsControl.ItemContainerStyle>
	</ItemsControl>
</Page>

With this change, the result is finally what I want - all the buttons are docked to the bottom correctly.

There may be a second possible solution, by making the ItemControl somehow skip creating that additional wrapper altogether, but I haven’t tried doing that.

16/3/2007

Cross tables in Windows Forms - data binding magic

Filed under: General, Programming, .NET — Oliver Sturm @ 5:55 pm - 1 year, 4 months ago

I have this sample from a recent talk at Basta! conference in Germany, which shows (among other things) how to bind a cross table to a DataGridView (the standard .NET 2 data grid). A cross table is basically the result of transposing some data and using one of the fields for a second dimension.

The sample I have works on two tables of data. It doesn’t actually use a database and the reference that points from the list of votes to that of features is implemented as an object reference, but the relationship is like this:

 Now, let’s assume there’s this data in the two tables/lists:

Features
ID Name
1 Synthesize out-of-the-box supply-chains
2 Syndicate vertical mindshare
  
Votes
ID Feature_ID Year Priority
1 1 2004 30
2 1 2005 40
3 1 2006 70
4 2 2004 70
5 2 2005 60
6 2 2006 30

In a cross table the same data could look like this:

Feature/Year 2004 2005 2006
Synthesize out-of-the-box supply-chains 30 40 70
Syndicate vertical mindshare 70 60 30

This is exactly the kind of transformation demonstrated in my sample. Now, there are a number of other things in that program, so don’t be confused. I suggest you focus on the workings of the VoteValuePropertyDescriptor class.

Here’s the download: FeatureVoting.zip

 

13/3/2007

MSDN Roadshow and food, Zi Makki style

Filed under: General — Oliver Sturm @ 10:33 am - 1 year, 4 months ago

March 21st is the date of the MSDN Roadshow in London. Should be interesting to hear some news about LINQ, the Entity Framework, AJAX and XAML… I’ll be there, and hoping to meet a few of you! Registration is apparently still open, so follow this link if you haven’t signed up yet.

After the event, there’s another fabulous geek dinner organized by the every more experienced geek-dinner-organizer Zi Makki :-) If you’re interested in meeting some of the other guys you read about in the blog-o-sphere (or maybe you just think you’re going to be hungry <g>), be there! Sign-up is here.

10/3/2007

ReadyBoost? Not on my system, apparently…

Filed under: General — Oliver Sturm @ 4:08 pm - 1 year, 5 months ago

After reading lots of stuff about ReadyBoost, hearing Dave’s song and having it recommended to me by a colleague, I decided to try it out on my system. Why hadn’t I done so before? Well… laziness ;-) And, seriously, I didn’t think I’d really like it too much.

I’m using my main system (which is an Acer TravelMate 8204WLMi) on the road a lot, meaning elsewhere but standing on my desk. The most propagated option for ReadyBoost is to use a USB flash drive. Unlike (apparently) many people, I don’t have loads of those around… well, I found five or so, but they are all rather old (some of them are really old :-) ) and slow. In the end, the idea of using a USB drive for the purpose actually put me off more than anything, because the USB drive would always be sticking out of the machine, so I’d have to unplug it every time I move my machine, and plug it back in when I want to use it.

Now I heard that it is also possible to use a memory card with ReadyBoost. The Acer does have a memory card reader built in, but it has a plastic cover that can’t be closed when a card is in the reader. Okay, I thought, I may just cut of the cover once I’ve found the perfect card that I’m going to leave in there. So I proceeded to test some cards that I had around to find one that would fulfil the requirements of ReadyBoost. I had a SanDisk Memory Stick Pro (too large really for my purpose), a Sony Memory Stick Pro Duo (not too large, but not directly compatible with my reader – adapter makes it too large), a SanDisk SD Mini card (good size with an SD card adapter) and a SanDisk Ultra II SD Micro card (good size with the adapter as well). Going for the SD form factor seems the best idea, as it only sticks out from my machine about a millimeter – hardly enough to pull it back out, actually.

So, the fact that I tested all these different cards gives a hint at the next problem I found: the cards were all assessed to be too slow for ReadyBoost. If you want to do such a test yourself, note that the ReadyBoost service logs to the Event Log. So open Event Viewer and navigate to Application and Services Logs | Microsoft | Windows | ReadyBoost | Operational. Then run a speed test (insert the memory device you want to use, find the drive for the device, right-click to get to the Properties dialog, select the ReadyBoost page and click the Test Again button.), and you’ll find a line in the Event Log telling you what speed was measured for the device.

All my cards were measured at only around 1600Kb/s, roughly half of what ReadyBoost wants (as far as I understand – the requirements list usually shows a value for each the read and write speeds, but the Event Log has only one value). I got myself another card, a SanDisk Extreme III SD Card which is supposed to really fast, but I get about the same value for that one as for all the others. When I rerun the test a number of times with any given card, there’s quite a lot of variation – up to 200Kb/s – but on average the results are always the same.

My next idea was of course that I had some wrong drivers. I found Intel’s driver page for the 945PM chipset in the Acer, but the drivers I was using were already the newest they have (and yes, they are specifically for Vista). All the other drivers that appear to have anything at all to do with the card reader are Microsoft drivers, and their version number all say Vista RTM. I’m somewhat at a loss what else to look at…

I’ve been thinking a few times that some things on my laptop may not be quite as they should be, due to the fact that I installed Vista during the RC phase (that was the last time I did a clean install) and upgraded to the RTM version. So I guess it is possible that a clean install of Vista RTM would help, but that takes too much time :-(

The first hint that leads to a solution (no, “reinstall Vista” doesn’t count) wins a SanDisk Extreme III SD card :-)

9/3/2007

Installing BlackBerry Desktop on Vista

Filed under: General — Oliver Sturm @ 9:36 pm - 1 year, 5 months ago

Bb8800I got myself a BlackBerry, which I’ve never had before. It came with a software CD, but although the model I got is rather new (BlackBerry 8800), the software was an older version and I was immediately suspicious of its compatibility with Vista.

The first thing I noticed when I tried to install it nevertheless is that the installer is unbelievably slow – meaning it has long periods of doing nothing at all. Between the splash screen that comes up in the beginning and the point where the first wizard dialog of the actual installation process comes up, at least two minutes went by.

Much more importantly, the installation failed anyway. After what seems like a lot of wizard pages and an eternity of waiting time, I got an error message saying “Error 2738. Could not access VBScript runtime for custom action.“

I went to RIM to get the latest version of the software, as I assumed the problem had to do with Vista. Yet another horribly slow process – they required me to register with my shoe size to be allowed to download updated software, the session timed out several times so I had to restart the whole process, their web site is not compatible with Firefox, the download process sometimes runs in circles, bringing up the user registration page more than once, and they list three different files as part of the 4.2 SP 1 release, which turned out to point to the same download after all, once I’d worked my way through the exhausting download process three times. Way to go, RIM!

In the end I finally had the new version downloaded and I was glad to find that the copyright year in the splashscreen actually showed the software to be newer than what I already had – the version is given as 4.2.1 in both cases. Nothing changed with the horrible speed – or lack thereof, actually – and the result was also the same: Error 2738.

At this point I went to research some information about this, and I followed BlackBerry specific references first. Apparently a number of people have had this problem in the past, but the information I could find was largely from Vista pre-release days, and it didn’t amount to much either. Performing a clean uninstallation was one hint I got, but there wasn’t a single piece of the information on my system that I was supposed to delete. RIM themselves have an entry in a FAQ list of theirs, pointing to a knowledge base article that turned out to be no longer available.

In the end I found the reason for the issue, as well as the (then obvious) solution explained in an MSDN forum. I’m replicating Jamie Hollingworth’s info here, in case the forum article shouldn’t be there any more later:

Vista for some reason dosnt register VBScript. What you have to do is first of all find where vbscript.dll is, mine was in C:\Windows\System32, but I think it changes dependant on your version. Next you need to go to start -> accessories and the right click on command prompt and click “run as administrator”, next type “cd C:\Windows\System32″ (replace the dir if its differnt for you) and then type “regsvr32 vbscript.dll”. It should then confirm that vbscript has been registered and everything should work.

Thank you, Jamie, that works nicely!

Now I finally have the software installed, it seems to work just fine. One more funny thing I noticed: even before I tried installing any of the software, I just plugged in the BlackBerry to see what would happen. A driver was installed that made me think there was actually something BlackBerry specific about it – something about the name, I don’t remember precisely. In any case, there was a drive installed on my system for a removable media, which I thought would probably be the SD card slot that the BlackBerry has. I don’t have a card in it so far, so I couldn’t verify that.

Now, the interesting thing is that while that driver seemed to be working, I saw a message on the screen of the BlackBerry: your USB port doesn’t deliver enough power, yada yada, there’s probably something wrong with your driver installation or the port you’re using to connect to your computer. Eh? Interesting… now that I have the software package installed correctly, that message is gone, but together with it the removable media drive is gone as well. Hm.

7/3/2007

Speaking at NxtGenUG Fest 07

Filed under: General, Programming, .NET — Oliver Sturm @ 10:00 am - 1 year, 5 months ago

I don’t think I’ve blogged about this yet, other than the original announcement about the event – turns out I’m going to speak at the event as well. They haven’t published their complete agenda yet, but there’s an overview of (some of?) the sessions available, including mine. This is what my session’s going to be:

Dynamic Languages and .NET
Last year Microsoft announced their future plans for dynamic language support in the .NET CLR, and existing projects like IronPython and PowerShell provide some insight into the application of dynamic principles to the .NET environment. In theory the distinction between static and dynamic languages is clear, but in today’s programming world the lines are often blurred. Do we want to be Dynamic? Why? And what is it that Microsoft is going to do for us in that regard? The session shows practical examples and explains the status quo as well as the future plans.

I’m looking forward to seeing you there!

2/3/2007

ReadyBoohoohoohoost….

Filed under: General — Oliver Sturm @ 3:30 pm - 1 year, 5 months ago

I really love that song :-) Better leave the singing to Dave though: (click the image to link to the video!!)

Img_2990

Btw, just out of curiosity…. what were you smoking, Dave? :-)

Back from BASTA!

Filed under: General, Programming, .NET — Oliver Sturm @ 12:41 pm - 1 year, 5 months ago

BASTA! was a good conference with a lot of great sessions. I did two myself – advanced functionality in the DataGridView (with some non-DataGridView specific things, like a cross table implementation based on ITypedList) and a session on ORM in real-world applications, going into some scenarios that come up when the typical SQL/ADO.NET based application architecture is converted towards ORM.

For Developer Express, we also had a great time in the exhibition, where we did lots of demos and had good discussions with users of the controls and libraries. I can report that the Wow! factor of Refactor!’s Reorder Parameters refactoring is not decreasing yet :-)

Organization was nice as well – for the VIP reception on the first day they took us to Burg Frankenstein, where we had a great introduction about how the Frankenstein we all know relates to the history of the Burg, and then dinner along with an ongoing show of medieval folklore. Free beer on two other evenings was another goodie for everyone – they did everything to keep people happy :-)

Thanks to everybody I met there and the people who attended my sessions!

Powered by WordPress
© Copyright 2005-2008 Oliver Sturm