OnApplyTemplate не вызывается в пользовательском контроле

У меня есть пользовательский элемент управления, который использует некоторые элементы управления 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 никогда не вызывается для этого элемента управления! Почему это не работает, как я ожидаю?

Ответ 1

Для всех, кто может наткнуться на этот пост, у меня была такая же проблема, и мне удалось решить эту проблему, добавив следующее в 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 в том же проекте, что и элемент управления.

Ответ 2

Два других ответа верны... но не полностью. Согласно этому сообщению (и мой опыт решения этой проблемы) есть четыре вещи, которые вам нужно проверить: (по какой-то причине блоки кода в этом сообщении не будут оставаться форматированным, если я использовал числа или тире... так что это буквы)

а. Шаблоны и стили управления должны находиться в файле Generic.xaml в папке с именем Themes корня вашего проекта.

В. Убедитесь, что ваши пространства имен верны в Generic.xaml

С. Установите ключ стиля в конструкторе вашего элемента управления. Также рекомендуется использовать следующее в статическом конструкторе.

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

Д. Убедитесь, что в вашей сборкеinfo.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)
 )]

Ответ 3

Я не вижу ваш конструктор, но не забудьте установить DefaultStyleKey:

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

Ответ 4

Я собираюсь добавить свой собственный ответ, потому что оба вышеупомянутых ответа неполны, поскольку я уже некоторое время борется с этой проблемой.

Как сказано MoMo и Kai G выше:

а. Шаблоны и стили управления должны быть расположены в Generic.xaml создайте папку под названием "Темы корня вашего проекта".

В. Убедитесь, что ваши пространства имен верны в Generic.xaml

С. Установите ключ стиля в конструкторе вашего элемента управления.

Д. Убедитесь, что атрибут theme находится в файле assemblyinfo.cs

НО вы также должны убедиться, что ваш файл Generic.xaml установлен для действия сборки как Страница: не копировать.

Если вы этого не сделаете или значение было каким-то образом установлено на что-то другое, то метод OnApplyTemplate() не будет вызываться.

Ответ 5

Ответ @MoMo правильный, но дополнительно:

E: Ожидается, что Themes/Generic.xaml находится в корне вашего проекта. Если это не так, и ваш Generic.xaml не находится в корне, тогда вам нужно создать каталог Themes с Generic.xaml в корневом каталоге (Generic.xaml имеет тип ResourceDictionary). В этом Generic.xaml вам нужно ссылаться на местоположение вашего Generic.xaml.

например:

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