Почему установка привязки шаблона к источнику изображения вызывает исключение KeyNotFoundException?

#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 , и именно так мы в основном делали такие вещи в прошлом. Но вы правы, определение этого термина само решает проблему. Спасибо!