【问题标题】:CommandBinding in DataTemplate within a ResourceDictionary, handlers not assigned correctlyResourceDictionary 内 DataTemplate 中的 CommandBinding,未正确分配处理程序
【发布时间】:2012-09-26 15:47:05
【问题描述】:

我有一个ResourceDictionary,其中包含一个DataTemplate。在此 DataTemplate 的资源中,我声明了 CommandBindingCollection。我的 ResourceDictionary 有一个代码隐藏文件,我在其中声明了 Executed/CanExecute 的处理程序。

我遇到的问题是,当我从 ResourceDictionary 检索我的 CommandBindingCollection 时,未分配 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 的资源中声明它时它不能设置事件处理程序的委托。

【问题讨论】:

  • 试试看这个类似的问题:stackoverflow.com/questions/5632698/…
  • @Johnny 是的,已经看过了,但该解决方案不适用于我的特定情况(我的 CommandBindingCollection 在 Datatemplate 的资源中,而 Datatemplate 本身又在 ResourceDictionary 中)
  • 从资源字典中检索命令绑定是什么意思。您将命令绑定分配给哪个控件?你能告诉我们TestCommands的源代码吗?数据模板是如何分配的?
  • @Per 使用 DataTemplateSelector 代码更新了问题

标签: c# .net wpf xaml resourcedictionary


【解决方案1】:

我的问题与 .NET 框架中的错误有关,该错误似乎已在 4.5 中修复。

在 4.0 上有一个针对该问题的修补程序:http://support.microsoft.com/kb/2464222

就我而言,应用修补程序解决了这个问题。我的猜测是,在 CommandBindingCollection XAML 解析器的某处,异常被静默处理。

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    相关资源
    最近更新 更多