Thursday, January 29, 2009

Monday, January 26, 2009

[Silverlight 2, C#] Data Binding and Event Handlers

So, right to the point, it seems that you cannot data bind event handlers.

What I wanted to do was be able to bind a name and delegate function to a custom menu item.
[ListBox x:Name="ItemList" Width="Auto" Height="Auto"]
[ListBox.ItemTemplate]
[DataTemplate]
[StackPanel Orientation="Horizontal"]
[TextBlock Text="{Binding itemname}"
FontFamily="Arial" Font Foreground="Black"
MouseLeftButtonDown="{Binding itemaction}"/]
[/StackPanel]
[/DataTemplate]
[/ListBox.ItemTemplate]
[/ListBox]

But I was getting a compiler error:
Error 5 The "ValidateXaml" task failed unexpectedly.
System.InvalidOperationException: Stack empty.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Stack`1.Pop()...

After a quick trip to the Silverlight forums I found out that you cannot databind to an event handler - which made some sense after I found this on the MSDN page for DataBinding:

The binding engine gets information from the Binding object about the following:



My Solution: Sneak the function delegate into the tag property
Since I couldn't bind the event directly I decided to sneak the delegate into the tag property of the textbox, and then setup a generic mouseLeftButtonDown handler that would read out the tag and cast it to my delegate, and then invoke it. So far it seems to work pretty well.

[ListBox x:Name="ItemList" Width="Auto" Height="Auto"]
[ListBox.ItemTemplate]
[DataTemplate]
[StackPanel Orientation="Horizontal"]
[TextBlock Text="{Binding itemname}"
FontFamily="Arial" Font Foreground="Black"
Tag="{Binding itemaction}"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" /]
[/StackPanel]
[/DataTemplate]
[/ListBox.ItemTemplate]
[/ListBox]

and then in the code behind:

private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get the tag info and run it.
MenuActionDelegate func = ((FrameworkElement) sender).Tag as MenuActionDelegate;
func.Invoke();
}

If anyone else has a more elegant solution, please let me know!!!

.

Friday, January 23, 2009

Shameless Picture Post - MS Tech Days

Over the past two days many of the people on my team attended Microsoft 2008 Tech Days - the main reason for me at least being that they had a few Silverlight presentations. Much of the content I had seen before from MIX webcasts, but I was able to pickup on some tips/classes that I just wasn't aware of before.

I left my notes at home today, so these are just off the top of my head:
- HtmlPage class : Allows access to the browser DOM, so you can actually pop open other HTML windows when you need them. I think this may come in very handy when trying to debug issues.
- I really need to start looking into binding more. I don't use it at all in my application and I'm not sure if that's because it just doesn't "fit" into my model, or because I haven't been smart enough to figure out "how" to use it.
- ... well ... I just can't remember at the moment - but I promise I'll update this when I get home and get my notebook ^^


Shameless picture... this is a large majority of the women that attended the conference, I think that Qixing [the "Women in Technology" leader] told us that only 10% of the registered attendees were female. We all had breakfast together, and it was a great way to meet new people! I'm in the front on the right side of the pic :)

















.

Thursday, January 22, 2009

Silveright Deep Zoom + LOLCats = Best Use of Cutting Edge Tech EVAR

So, this is a little side post and isn't related to any coding issues at all - BUT - it made my day and since it is related to Silverlight I figure I'm allowed to post it here ;)

This amazingly brilliant person took the new[ish] Deep Zoom technology and applied it to one of my most favourite things: LOLCats. Check it out... zoom in, waaaaaaaaay in!




http://robburke.net/2008/08/08/fractlol/

.

Tuesday, January 20, 2009

[Silverlight 2, C#] Fun with Namespaces

Hi everybody!

Alright - so if you've read my other posts, you'll know that I'm working on a WYSIWYG-type graphics editor - and I've been dealing with naming issues with regards to having to name and clone thousands of elements on a canvas. Also in my application, when I drag and stretch, I create a ghost of the base element. This also required cloning, and up until now, namespace checks.

I was aware that a user control actually creates it's own namespace, such that you can have the same x:name is multiple controls. This is obviously a very, very handy thing to have. I wanted to be able to separate some content from the rest of my application easily, so that I could reduce the number of name checks I need to do as a result of cloning elements based on hardcoded strings.

Try 1: Creating an essentially empty UserControl
Originally, I had tried to create a helper UserControl called "SafeNamespace" which was essentially an empty control with a Canvas root.

[UserControl x:Class="Graphics.SafeNamespace"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"]
[Canvas x:Name="LayoutRoot"]

[/Canvas]
[/UserControl]


This was mildly annoying because I could not easily treat this like a canvas [to my knowledge] and I wrote small helper functions in the xaml.cs to allow for simplier setting and getting of the LayoutRoot content. It was just a little ugly - it worked, it was just icky.


Better Method: Extending the Canvas Class
After a little searching I came across this forum post which talked about extending the Canvas class itself, instead of extending the UserControl class. This also allows you to implement custom functionality onto the Canvas if you desired, but for me I was really only looking for the ability to create a seperate namespace.

xaml:
[Canvas x:Class="Graphics.SafeNamespaceCanvas"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"]
[/Canvas]


and

xaml.cs
public partial class SafeNamespaceCanvas : Canvas
{ ... }



In short, creating an extention of a class was a nice way for me to achieve some namespace independance... and was extremely handy given the large number of named elements I was dealing with! Just thought I'd pass along the idea :)


.

Friday, January 16, 2009

[Silverlight 2, C#] Performance of doing many many FindName calls...

Today I was looking into an issue I was having regarding having to do many [up to thousands] of FindName checks in my WYSIWYG graphics editor. This is due to the fact that most [if not all] of my elements are named, and when adding a new palette item I need to check and make sure that the names of the new item do not conflict with any existing items on my canvas. I stress test using palette items that contain roughly 3k elements, all with their own names. In practice, this may never be the case, but I always like to stress the crap out of things to see where they can break down the line... and honestly I can see a user ending up with complex palette items that may contain many many elements.

Aaaaaaaaaaaaanyways. Before I was going through my new item and checking all names against the canvas [using FindName] that the item was to be placed in. I found when stress testing that this comparison could take a long long time.

The solution we came up with was to create a Dictionary of all names on the canvas and then do my checks against THAT [Dictionary.ContainsKey("nameOfItem")] instead of using FindName. I chose to use a Dictionary since it is implemented on a hash, whereas a List is not.

In my tests I found that the time to do my naming checks was cut roughly in half by doing this. Obviously more memory is required to house the Dictionary of names, but the time savings more then makes up for it in my case.

In summary - it may be quicker to generate a Dictionary of names and then check against that, instead of using FindName.

I haven't tested the single case [ie only doing ONE FindName], but when doing thousands and hundreds of thousands, my performance was doubled.

.

Thursday, January 15, 2009

[Silverlight 2, C#] Testing Performance, Memory Usage

So after some code reviews and the like, I had decided to try and implement some of my core functionality a little different in order to *hopefully* decrease the memory allocation of my application.

Since Silverlight 2 does not appear to support the System.Diagnostics.Process class, I believe the only way to get similar information is via [Garbage Collector] System.GC.GetTotalMemory

System.GC.GetTotalMemory
public static long GetTotalMemory(
bool forceFullCollection
)

* Set forceFullCollection to true if you can wait for garbage collection to occur before doing the check.

* Returns the estimated number of bytes the application has allocated.

Difference Between GetTotalMemory() vs Windows Task Manager Memory Estimation
I have noticed QUITE a difference between the bytes returned from this function, vs. the Windows Task Manager estimation of the memory used by iexplorer while my app is running.

Siverlight Plugin Memory
One reason that I know for sure, is that the Task Manager takes into account the memory it takes to run the Silverlight plugin. I created an empty Silverlight project and when running it, it appeared to take up between 38,000kb to 40,624kb. Not sure why there was ever a difference, but every time I ran it I got a slightly different value. GetTotalMemory does not appear to include this cost and only counts the memory the app itself allocates.

Unmanaged Memory
GetTotalMemory only counts managed memory allocated by your application. If there is a memory leak for whatever reason, then that cost will not be included in the total.

There may be other reasons that the two memory estimations are different, but those are the two that I have come across so far.

.