UWP:自定义控件的模板失败,并显示“无法从文本创建'Windows.UI.Xaml.DependencyProperty”错误

时间:2018-11-27 18:32:51

标签: c# uwp uwp-xaml

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

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]

如果我尝试将TargetType中的ControlTemplate设置为ContentDialog,则会收到相同的错误,但是找不到我的自定义属性PrimaryButtonGlyph

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

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

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

1 个答案:

答案 0 :(得分:1)

从您的代码中,您想创建继承ContentDialog的自定义模板控件。但是您尚未初始化默认样式。您可以按照以下步骤自定义ContentDialog

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

enter image description here

创建ContentDialogTest.cs类后,项目将自动生成Generic.Xaml文件。

enter image description here

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

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

然后在DependencyProperty类中创建ContentDialogTest。您会发现默认构造函数方法中有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 hub。