Reputation: 5246
I have a ResourceDictionary
, which contains a DataTemplate
. Within this DataTemplate's Resources I am declaring a CommandBindingCollection
. My ResourceDictionary has a codebehind file in which I declare the handlers for Executed/CanExecute.
The issue I have is that when I retreive my CommandBindingCollection
from the ResourceDictionary
, the Executed/CanExecute handlers are not assigned. Using the debugger I can see that the handlers are null. Why is that and how can I fix it?
ResourceDictionary XAML:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="Test"
x:Class="Test.MyResourceDictionary">
<DataTemplate x:Key="Template"
x:Name="Template">
<DataTemplate.Resources>
<CommandBindingCollection x:Key="CommandBindings">
<CommandBinding Command="local:TestCommands.Test"
Executed="testExecuted"
CanExecute="testCanExecute" />
</CommandBindingCollection>
</DataTemplate.Resources>
<!-- More stuff here -->
</DataTemplate>
<ResourceDictionary/>
ResourceDictionary codebehind:
public partial class MyResourceDictionary: ResourceDictionary
{
public MyResourceDictionary()
{
InitializeComponent();
}
private void testExecuted(object sender, ExecutedRoutedEventArgs e)
{
}
private void testCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
}
}
Update
I am using this with AvalonDock, which uses DataTemplateSelector
to apply the DataTemplate.
Here is how I load the Template:
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is TestViewModel)
{
ResourceDictionary res = Application.LoadComponent(new Uri("/MyResourceDictionary.xaml", UriKind.Relative)) as ResourceDictionary;
DataTemplate template = res["Template"] as DataTemplate;
if(template != null)
{
CommandBindingCollection commandBindings =
template.Resources["CommandBindings"] as CommandBindingCollection;
if(commandBindings != null)
{
foreach(var binding in commandBindings)
{
// add commandbinding to the container control
// here, using the debugger i can see that the handlers for the commandbinding
// are always null (private variables that I can only see using debugger)
}
}
return template;
}
}
return base.SelectTemplate(item, container);
}
If I move the CommandBindingCollection
directly into the ResourceDictionary
and access it this way:
CommandBindingCollection commandBindings =
res["CommandBindings"] as CommandBindingCollection;
Then the handlers are correctly set. I'm wondering why it can't set the event handler's delegates when I declare it within the DataTemplate's Resources.
Upvotes: 1
Views: 1806
Reputation: 5246
My problem was related to a bug in the .NET framework, which seems fixed in 4.5.
There is a hotfix for the problem on 4.0: http://support.microsoft.com/kb/2464222
In my case, applying the hotfix solved the issue. My guess is that somewhere in the CommandBindingCollection XAML parser, the exception is handled silently.
Upvotes: 1