OnApplyTemplate未在自定义控件中调用

时间:2010-05-30 18:23:44

标签: wpf

我有一个使用一些PART控件的自定义控件:

 [TemplatePart(Name = "PART_TitleTextBox", Type = typeof(TextBox))]
    [TemplatePart(Name = "PART_TitleIndexText", Type = typeof(Label))]
    [TemplatePart(Name = "PART_TimeCodeInText", Type = typeof(TextBlock))]
    [TemplatePart(Name = "PART_TimeCodeOutText", Type = typeof(TextBlock))]
    [TemplatePart(Name = "PART_ApprovedImage", Type = typeof(Image))]
    [TemplatePart(Name = "PART_CommentsImage", Type = typeof(Image))]
    [TemplatePart(Name = "PART_BookmarkedImage", Type = typeof(Image))]
    public class TitleBoxNew : Control
    {
        static TitleBoxNew()
        { 
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(TitleBoxNew),
                new FrameworkPropertyMetadata(typeof(TitleBoxNew)));
        } 

        public TitleBoxNew() { }

        // ... rest of class
    }

此控件覆盖OnApplyTemplate:

public override void OnApplyTemplate()
{
      base.OnApplyTemplate();

      InitializeEvents();
}

大部分时间都适用。我已经在窗口中的自定义选项卡控件中添加了控件,并且不会以某种方式为该控件调用OnApplyTemplate!为什么这不能像我期望的那样工作?

6 个答案:

答案 0 :(得分:39)

对于任何可能偶然发现这篇文章的人,我遇到了同样的问题,我设法通过将以下内容添加到包含我的自定义控件的项目的AssemblyInfo.cs中来解决它:

[assembly: ThemeInfo(
    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
    //(used if a resource is not found in the page, 
    // or application resource dictionaries)
    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
    //(used if a resource is not found in the page, 
    // app, or any theme specific resource dictionaries)
)]

我的控件模板位于与控件相同的项目中的Theme / Generic.xaml文件中。

答案 1 :(得分:25)

另外两个答案是正确的......但不完整。根据{{​​3}}(以及我刚刚解决此问题的经验),您需要检查4件事情:(由于某种原因,如果我使用数字或短划线,此帖子中的代码块将不会保持格式化...所以它是字母)

一个。控件模板和样式应位于Generic.xaml文件中,名为项目根目录Themes的文件夹。

B中。确保Generic.xaml

中的命名空间正确无误

℃。在控件的构造函数中设置样式键。还广泛建议您将以下内容放在静态构造函数中。

 static YourControl()
 {
      DefaultStyleKeyProperty.OverrideMetadata(typeof(YourControl), new FrameworkPropertyMetadata(typeof(YourControl)));
 }

d。确保您的assemblyinfo.cs

中有以下内容
 [assembly: ThemeInfo(ResourceDictionaryLocation.None, 
 //where theme specific resource dictionaries are located
 //(used if a resource is not found in the     
 // or application resource dictionaries)
 ResourceDictionaryLocation.SourceAssembly 
 //where the generic resource dictionary is located
 //(used if a resource is not found in the page,
 // app, or any theme specific resource dictionaries)
 )]

答案 2 :(得分:3)

我看不到你的构造函数,但不要忘记设置DefaultStyleKey:

DefaultStyleKeyProperty.OverrideMetadata(typeof(TitleBoxNew), new FrameworkPropertyMetadata(typeof(TitleBoxNew)));

答案 3 :(得分:1)

我将添加我自己的答案,因为上述答案都不完整,因为我一直在努力解决这个问题。

正如MoMo和Kai G所说:

  

一个。控件模板和样式应位于   Generic.xaml文件名为项目根目录的主题文件夹。

     

B中。确保您的名称空间在Generic.xaml

中是正确的      

℃。在控件的构造函数中设置样式键。

     

d。确保theme属性位于assemblyinfo.cs文件中

但您还需要确保为构建操作设置Generic.xaml文件为页面:不要复制。

如果您未能执行此操作或将值以某种方式设置为除此之外的其他值,则不会调用OnApplyTemplate()方法。

答案 4 :(得分:1)

@MoMo的答案是正确的,但另外:

E:预计Themes / Generic.xaml位于项目的根目录中。如果不是这种情况并且您的Generic.xaml不在根目录中,那么您必须在根目录中创建一个带有Generic.xaml的目录主题(Generic.xaml只是ResourceDictionary类型)。在那个Generic.xaml中,您需要引用Generic.xaml的位置。

例如:

<ResourceDictionary Source="/Foo.Bar;component/Controls/FooControl/Themes/Generic.xaml" />

答案 5 :(得分:0)

除了上面提到的所有正确内容之外,您还应该检查

实际上调用了OnApplayTemplete(),但是在所有属性更改后调用,我不知道为什么,应该将其称为第一件事

因此,如果您使用PARTS名称来获取元素,则会出错,因为wpf直到OnApplayTemplete()被调用时才会找到 因此,您必须在任何代码之前添加if(您的part元素!= null)条件取决于PARTs名称

然后在OnApplayTemplete()方法内部,它会再次自动调用您所有的逻辑方法,并且可以正常工作

format.pdf do
  render pdf: "file_name"   # Excluding ".pdf" extension.
end
相关问题