ВПФ:Ошибка при использовании настраиваемого элемента управления в ItemTemplate другого настраиваемого элемента управления.
-
22-09-2019 - |
Вопрос
У меня есть библиотека настраиваемых элементов управления, в которой есть несколько настраиваемых элементов управления, которые я использую в своем основном приложении.У меня есть простой настраиваемый элемент управления, который позволяет пользователю выбирать значения толщины пера из поля со списком.Теперь я создаю новый настраиваемый элемент управления на основе списка и хочу включить поле со списком толщины пера в 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)));
}
}
}