为什么在 ImageSource 上设置 TemplateBinding 会抛出 KeyNotFoundException?

Why is setting a TemplateBinding on an ImageSource throwing a KeyNotFoundException?

我有以下 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.'

如果我从 ControlTemplate 中删除 Source="{TemplateBinding ImageSource}",它 运行 不会崩溃,但当然不会显示图像。

不知道为什么会抛出 KeyNotFoundException,但如果您注册一个新的 DependencyProperty,而不是将所有者类型添加到 Image.SourceProperty,TemplateBinding 将起作用。这也将避免对图像的依赖 class.

public static readonly DependencyProperty ImageSourceProperty =
   DependencyProperty.Register(
       nameof(ImageSource), typeof(ImageSource), typeof(ImageAnnotationEditor));

否则,使用通常的解决方法,即用 RelativeSource TemplatedParent:

的常规绑定替换 TemplateBinding
<Image Source="{Binding ImageSource,
                RelativeSource={RelativeSource TemplatedParent}}"/>