【问题标题】:Why is setting a TemplateBinding on an ImageSource throwing a KeyNotFoundException?为什么在 ImageSource 上设置 TemplateBinding 会引发 KeyNotFoundException?
【发布时间】:2020-12-07 04:11:51
【问题描述】:

我有以下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}",它会运行而不会崩溃,但当然不会显示图像。

【问题讨论】:

    标签: c# wpf controltemplate imagesource templatebinding


    【解决方案1】:

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

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

    否则,请使用通常的解决方法,即将 TemplateBinding 替换为 RelativeSource TemplatedParent 的常规 Binding:

    <Image Source="{Binding ImageSource,
                    RelativeSource={RelativeSource TemplatedParent}}"/>
    

    【讨论】:

    • 奇数。我特别选择了“AddOwner”,因为这个属性实际上只是“传递”到底层Image,而这就是我们过去大部分做这些事情的方式。但是您是对的,自己定义它可以解决问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2015-03-06
    • 2021-12-07
    • 2021-09-25
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    相关资源
    最近更新 更多