UWP:自定义控件模板失败,出现 "Failed to create a 'Windows.UI.Xaml.DependencyProperty' from the text" 错误

UWP: Template for custom control fails with "Failed to create a 'Windows.UI.Xaml.DependencyProperty' from the text" error

我正在尝试创建自定义 ContentDialog 控件。我的习惯 class 喜欢:

public class ContentDialogEx : ContentDialog
{
    public string PrimaryButtonGlyph
    {
        get => (string)GetValue(PrimaryButtonGlyphProperty);
        set => SetValue(PrimaryButtonGlyphProperty, value);
    }

    public string SecondaryButtonGlyph
    {
        get => (string)GetValue(SecondaryButtonGlyphProperty);
        set => SetValue(SecondaryButtonGlyphProperty, value);
    }

    public string CloseButtonGlyph
    {
        get => (string)GetValue(CloseButtonGlyphProperty);
        set => SetValue(CloseButtonGlyphProperty, value);
    }

    public static readonly DependencyProperty PrimaryButtonGlyphProperty = DependencyProperty.Register(nameof(PrimaryButtonGlyph), typeof(string), typeof(ContentDialogEx), new PropertyMetadata(""));
    public static readonly DependencyProperty SecondaryButtonGlyphProperty = DependencyProperty.Register(nameof(SecondaryButtonGlyph), typeof(string), typeof(ContentDialogEx), new PropertyMetadata(""));
    public static readonly DependencyProperty CloseButtonGlyphProperty = DependencyProperty.Register(nameof(CloseButtonGlyph), typeof(string), typeof(ContentDialogEx), new PropertyMetadata(""));

    public ContentDialogEx()
    {
        Template = PrismUnityApplication.Current.Resources["ContentDialogExTemplate"] as ControlTemplate;
    }
}

控件模板如下所示:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:MyApp.Xaml.Controls">

    <ControlTemplate x:Key="ContentDialogExTemplate" TargetType="controls:ContentDialogEx">
    ...
    </ControlTemplate>
</ResourceDictionary>

控件模板的内容是从默认模板复制而来的,当我将其应用到标准模板时,我已确认它有效 ContentDialog

编译正常,我可以 运行 应用程序,但是当我实例化对话框并尝试显示它时,出现以下错误:

Failed to create a 'Windows.UI.Xaml.DependencyProperty' from the text 'Background'. [Line: 163 Position: 33]

如果我尝试将 ControlTemplateTargetType 设置为 ContentDialog,我会得到同样的错误,但找不到我的自定义 属性 PrimaryButtonGlyph

好像它无法在基础上找到属性 class 但如果这是一个问题,那么几乎没有什么用。我做错了什么?

(目标版本:Windows 10,版本 1803(10.0;内部版本 17134),最低版本:Windows 10 Fall Creators Update(10.0;内部版本 16299))

编辑:我在这里创建了一个演示解决方案:https://www.dropbox.com/s/a4y7jrtcw3ivkqy/Whosebug53506051.zip?dl=0

根据您的代码,您希望制作继承 ContentDialog 的自定义 模板化控件 。但是你还没有初始化默认样式。您可以通过以下步骤自定义 ContentDialog

使用 Templated Control 模板创建新项目。

创建ContentDialogTest.csclass后,项目会自动生成Generic.Xaml文件。

请将您的 ContentDialogExTemplate 复制到 Generic.Xaml 文件。请注意,我已将自定义内容对话框名称修改为 ContentDialogTest.

<Style TargetType="controls:ContentDialogTest" >
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="controls:ContentDialogTest">
                <Border>
                   .........
                </Border>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
</Style>

然后在 ContentDialogTest class 中创建 DependencyProperty。你会发现在默认的构造方法中有this.DefaultStyleKey = typeof(ContentDialogTest);。并且这一行确保样式可以被初始化。

public sealed class ContentDialogTest : ContentDialog
{
    public ContentDialogTest()
    {
        this.DefaultStyleKey = typeof(ContentDialogTest);
    }
    public string PrimaryButtonGlyph
    {
        get => (string)GetValue(PrimaryButtonGlyphProperty);
        set => SetValue(PrimaryButtonGlyphProperty, value);
    }

    public string SecondaryButtonGlyph
    {
        get => (string)GetValue(SecondaryButtonGlyphProperty);
        set => SetValue(SecondaryButtonGlyphProperty, value);
    }

    public string CloseButtonGlyph
    {
        get => (string)GetValue(CloseButtonGlyphProperty);
        set => SetValue(CloseButtonGlyphProperty, value);
    }

    public static readonly DependencyProperty PrimaryButtonGlyphProperty = DependencyProperty.Register
              (nameof(PrimaryButtonGlyph),
               typeof(string),
               typeof(ContentDialogTest),
               new PropertyMetadata("&#xF13E;"));

    public static readonly DependencyProperty SecondaryButtonGlyphProperty = DependencyProperty.Register
        (nameof(SecondaryButtonGlyph),
        typeof(string), typeof(ContentDialogTest),
        new PropertyMetadata("&#xF13D;"));

    public static readonly DependencyProperty CloseButtonGlyphProperty = DependencyProperty.Register
             (nameof(CloseButtonGlyph),
              typeof(string),
              typeof(ContentDialogTest),
              new PropertyMetadata("&#xF13D;"));
}

用法

private async void OnShowContentDialogExButtonClick(object sender, RoutedEventArgs e)
{
    var dialog = new ContentDialogTest
    {
        Title = "Demo",
        Content = new Dialog(),

        PrimaryButtonText = "Primary",
        SecondaryButtonText = "Secondary",
        CloseButtonText = "Close"
    };

    await dialog.ShowAsync();
}

为了更好地理解,我已将 code sample 上传到 git 集线器。