WPF: ошибка при использовании настраиваемого элемента управления в ItemTemplate другого настраиваемого элемента управления

У меня есть библиотека настраиваемых элементов управления, в которой есть несколько настраиваемых элементов управления, которые я использую в своем основном приложении. У меня есть простой настраиваемый элемент управления, который позволяет пользователю выбирать значения толщины пера из поля со списком. Теперь я создаю новый настраиваемый элемент управления на основе списка и хочу включить поле со списком толщины пера в ItemTemplate нового настраиваемого элемента управления.

Я получаю эту ошибку:

«Невозможно создать экземпляр LineThicknessComboBox, определенный в сборке CustomControls ... Исключение было создано целью вызова. Ошибка в объекте« 10_T »в файле разметки CustomControls; component / Themes / CustomListBox.General.xaml '.

Вот XAML и код для LineThicknessComboBox:

namespace CustomControls
{
    public class LineThicknessComboBox : ComboBox
    {
        public LineThicknessComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(LineThicknessComboBox)
                        , new FrameworkPropertyMetadata(typeof(LineThicknessComboBox)));

        }
    }
}

и в LineThicknessCombobox.Generic.xaml:

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControls">

<Style TargetType="{x:Type local:LineThicknessComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                ...
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

</ResourceDictionary>

Вот XAML и код для моего нового CustomListBox:

namespace CustomControls
{
    public class CustomListBox : ListBox
    {
        public CustomListBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomListBox)
                        , new FrameworkPropertyMetadata(typeof(CustomListBox)));
        }
    }
}

и в CustomListBox.Generic.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControls">

<Style TargetType="{x:Type local:CustomListBox}" BasedOn="{StaticResource {x:Type ListBox}}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border>
                 ...
                     <local:LineThicknessComboBox />
                 ...  
                </Border>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

</ResourceDictionary>

А вот и мой Generix.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="CustomControls;component/Themes/LineThicknessComboBox.Generic.xaml"/>
        <ResourceDictionary Source="CustomControls;component/Themes/CustomListBox.Generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Я думаю, что у меня какая-то проблема с эталоном, но не могу понять, что не так. Программа компилируется и запускается без каких-либо предупреждений / ошибок, но когда CustomListBox создается в моем основном приложении, я получаю указанную выше ошибку. Без включения LineThicknessComboBox CustomListBox работает нормально.

Может ли кто-нибудь объяснить, почему я получаю эту ошибку? Можно включить мой настраиваемый элемент управления в другой, даже если они находятся в той же библиотеке настраиваемых элементов управления, верно?

Спасибо!


person stevosaurus    schedule 18.10.2009    source источник
comment
Исключение было создано целью вызова. Просмотрите InnerException (вам может потребоваться развернуть более одного уровня), и вы должны найти более значимое исключение. Это может сделать ошибку очевидной, как только вы ее увидите, или если вы не сможете опубликовать ее, это поможет с диагностикой.   -  person itowlson    schedule 19.10.2009


Ответы (2)


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

// not public LineThicknessComboBox()
static LineThicknessComboBox()        
{
            DefaultStyleKeyProperty.OverrideMetadata(
               typeof(LineThicknessComboBox)
                        , new FrameworkPropertyMetadata(
                              typeof(LineThicknessComboBox)));
}

Вызовы OverrideMetadata должны выполняться только в статических конструкторах типа который предоставляется в качестве параметра forType этого метода или с помощью аналогичного экземпляра. Попытка изменить метаданные после того, как экземпляры типа владельца существуют, не вызовет исключений, но приведет к несогласованному поведению в системе свойств.

ОТ MSDN

person Akash Kava    schedule 19.10.2009
comment
Я попробую это сделать, когда вернусь домой сегодня вечером. Спасибо за внимание, я не уверен, почему мои конструкторы не объявлены статическими. - person stevosaurus; 20.10.2009

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

Решение состоит в том, чтобы использовать класс System.ComponentModel.DesignerProperties, чтобы проверить, находитесь ли вы в режиме разработки, и обернуть любой код, который не работает в режиме разработки, в блок if, чтобы предотвратить его запуск:

namespace CustomControls
{
    public class LineThicknessComboBox : ComboBox
    {
        public LineThicknessComboBox()
        {
            // Design-mode capable code...

            if (DesignerProperties.GetIsInDesignMode(this)) return;

            // Design mode incapable code...

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

        }
    }
}
person jrista    schedule 18.10.2009
comment
Я не думаю, что это моя проблема, так как я получаю сообщение об ошибке во время выполнения. Спасибо за ответ. - person stevosaurus; 18.10.2009