#c# #wpf #controltemplate #imagesource #templatebinding
#c# #wpf #controltemplate #imagesource #привязка к шаблону
Вопрос:
У меня есть следующий ListBox
подкласс…
public class ImageAnnotationEditor : ListBox {
static ImageAnnotationEditor() {
DefaultStyleKeyProperty.OverrideMetadata(
typeof(ImageAnnotationEditor),
new FrameworkPropertyMetadata(typeof(ImageAnnotationEditor)));
}
#region ImageSource Property
public static readonly DependencyProperty ImageSourceProperty = Image.SourceProperty.AddOwner(
typeof(ImageAnnotationEditor));
public ImageSource? ImageSource {
get => (ImageSource)GetValue(ImageSourceProperty);
set => SetValue(ImageSourceProperty, value);
}
#endregion ImageSource Property
}
Со следующим шаблоном…
<ControlTemplate TargetType="{x:Type c:ImageAnnotationEditor}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Viewbox Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<c:LayerPanel>
<Image Source="{TemplateBinding ImageSource}" /> <-- This line causes the problem
<StackPanel IsItemsHost="True" />
</c:LayerPanel>
</Viewbox>
</Border>
</ControlTemplate>
Что когда я запускаю приложение, оно выдает следующее…
System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the dictionary.'
Если я удаляю Source="{TemplateBinding ImageSource}"
из ControlTemplate
, он запускается без сбоев, но, конечно, не отображает изображение.
Ответ №1:
Понятия не имею, почему именно генерируется KeyNotFoundException, но привязка шаблона будет работать, если вы зарегистрируете новое свойство DependencyProperty вместо добавления типа владельца Image.SourceProperty
. Это также позволило бы избежать зависимости от класса Image.
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register(
nameof(ImageSource), typeof(ImageSource), typeof(ImageAnnotationEditor));
В противном случае используйте обычный обходной путь, т. Е. Замените привязку шаблона обычной привязкой на RelativeSource TemplatedParent
:
<Image Source="{Binding ImageSource,
RelativeSource={RelativeSource TemplatedParent}}"/>
Комментарии:
1. Странно. Я выбрал «AddOwner» специально, потому что это свойство действительно просто «передается» базовому
Image
, и именно так мы в основном делали такие вещи в прошлом. Но вы правы, определение этого термина само решает проблему. Спасибо!