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

StackOverflow https://stackoverflow.com/questions/1585737

Вопрос

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

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

«Невозможно создать экземпляр LineThicknessComboBox, определенный в сборке CustomControls...Исключение было создано целью вызова.Ошибка объекта «10_T» в файле разметки «CustomControls;comment/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 работает нормально.

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

Спасибо!

Это было полезно?

Решение

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

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

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

ИЗ MSDN

Другие советы

Возможно, у вас возникла проблема с 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)));

        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top