Showing posts with label Data Binding. Show all posts
Showing posts with label Data Binding. Show all posts

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!!!

.