WPF - ControlTemplate中的事件?

9

有人知道为什么我不能在控件模板上设置事件吗?

例如,以下代码行将无法编译。对于控件模板中的任何事件都是如此。

<ControlTemplate x:Key="DefaultTemplate" TargetType="ContentControl">
   <StackPanel Loaded="StackPanel_Loaded">

   </StackPanel>
</ControlTemplate>

我正在使用MVVM设计模式,在这里的控件位于一个ResourceDictionary中,该ResourceDictionary已添加到应用程序的MergedDictionaries中。


对于有同样问题的人,我使用Style和EventSetter作为替代方案,尽管我仍然想知道为什么如果我使用ControlTemplate,就不能直接在控件上设置事件。 - Rachel
这个回答解决了你的问题吗?如何在ControlTemplate内声明事件处理程序? - StayOnTarget
1个回答

12

有人知道我为什么无法在控件模板上设置事件吗?

实际上,您可以...但是您期望在哪里定义事件处理程序?ResourceDictionary没有后台代码,因此没有放置事件处理程序代码的位置。但是,您可以为资源字典创建一个类,并将其与x:Class属性关联:

<ResourceDictionary x:Class="MyNamespace.MyClass"
                    xmlns=...>

    <ControlTemplate x:Key="DefaultTemplate" TargetType="ContentControl">
       <StackPanel Loaded="StackPanel_Loaded">

       </StackPanel>
    </ControlTemplate>

C# 代码:

namespace MyNamespace
{
    public partial class MyClass : ResourceDictionary
    {
        void StackPanel_Loaded(object sender, RoutedEventArgs e)
        {
            ...
        }
    }
}

(您可能还需要将资源字典的“构建操作”更改为“页面”,我记不太清了...)


这就是我目前拥有的...一个ResourceDictionary类,它的Build Action设置为Page。我唯一能看到的区别是我没有声明它为public,但改变这个并没有帮助解决问题。 - Rachel
具体是什么问题?您是否收到错误消息? - Thomas Levesque
当我运行程序时,它会抛出一个NullReferenceException(编译没有问题)。这一定与我的设计模式有关,因为我尝试创建了一个简单的测试用例,它可以正常工作。我的主要应用程序会覆盖app.xaml的OnStartup以加载许多不同的ResourceDictionaries,创建MainWindow的实例,设置其DataContext,然后调用MainWindow.Show() - 最后一行是我遇到异常的地方。将事件从ControlTemplate移动到EventSetter中可以消除错误。 - Rachel
我正在测试的ResourceDictionary为自定义对象定义了DataTemplate,在该DataTemplate中有一个自定义UserControl。 UserControl.Resources包含包含事件的ControlTemplate,而UserControl.Content包含引用ControlTemplate的ContentControl。 - Rachel
然后您需要将ControlTemplate移到另一个文件中。 - Thomas Levesque
为什么会这样呢?我本来希望避免这种情况的,因为应用程序的某些部分是模块化的,我想把一个部分的所有资源都放在一个文件中。 - Rachel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接