1

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.

Jf Beaulac
  • 5,206
  • 1
  • 25
  • 46
  • Try have a look at this similar question: http://stackoverflow.com/questions/5632698/execute-command-does-not-fire-in-resource-dictionary-code-behind – Johnny Sep 26 '12 at 16:37
  • @Johnny Yeah already had a look at it but the solution is not applicable in my particular situation (my CommandBindingCollection is within the resources of a Datatemplate which is itself within a ResourceDictionary) – Jf Beaulac Sep 26 '12 at 18:03
  • What do you mean by retreiving the command binding from the resource dictionary. To what control are you assigning the command binding? Can you show us the source code for TestCommands? How is the data template assigned? – Per Sep 26 '12 at 18:21
  • @Per Updated the question with the DataTemplateSelector code – Jf Beaulac Sep 26 '12 at 18:37

1 Answers1

1

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.

Jf Beaulac
  • 5,206
  • 1
  • 25
  • 46