我有ResourceDictionary
,其中包含DataTemplate
。在这个DataTemplate的资源中,我声明了CommandBindingCollection
。我的ResourceDictionary有一个代码隐藏文件,我在其中声明Executed / CanExecute的处理程序。
我遇到的问题是,当我从CommandBindingCollection
检索ResourceDictionary
时,未分配Executed / CanExecute处理程序。使用调试器我可以看到处理程序为空。为什么这样,我该如何解决?
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代码隐藏:
public partial class MyResourceDictionary: ResourceDictionary
{
public MyResourceDictionary()
{
InitializeComponent();
}
private void testExecuted(object sender, ExecutedRoutedEventArgs e)
{
}
private void testCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
}
}
更新
我在AvalonDock上使用它,它使用DataTemplateSelector
来应用DataTemplate。
以下是我加载模板的方法:
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);
}
如果我将CommandBindingCollection
直接移到ResourceDictionary
并以这种方式访问它:
CommandBindingCollection commandBindings =
res["CommandBindings"] as CommandBindingCollection;
然后正确设置处理程序。我想知道为什么当我在DataTemplate的资源中声明它时,它无法设置事件处理程序的委托。
答案 0 :(得分:1)
我的问题与.NET框架中的一个错误有关,这个错误似乎已在4.5中修复。
4.0上有一个问题的修补程序:http://support.microsoft.com/kb/2464222
在我的情况下,应用此修补程序解决了该问题。我的猜测是,在CommandBindingCollection XAML解析器的某个地方,异常是以静默方式处理的。