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]
如果我尝试将 ControlTemplate
的 TargetType
设置为 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.cs
class后,项目会自动生成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(""));
public static readonly DependencyProperty SecondaryButtonGlyphProperty = DependencyProperty.Register
(nameof(SecondaryButtonGlyph),
typeof(string), typeof(ContentDialogTest),
new PropertyMetadata(""));
public static readonly DependencyProperty CloseButtonGlyphProperty = DependencyProperty.Register
(nameof(CloseButtonGlyph),
typeof(string),
typeof(ContentDialogTest),
new PropertyMetadata(""));
}
用法
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 集线器。
我正在尝试创建自定义 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]
如果我尝试将 ControlTemplate
的 TargetType
设置为 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.cs
class后,项目会自动生成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(""));
public static readonly DependencyProperty SecondaryButtonGlyphProperty = DependencyProperty.Register
(nameof(SecondaryButtonGlyph),
typeof(string), typeof(ContentDialogTest),
new PropertyMetadata(""));
public static readonly DependencyProperty CloseButtonGlyphProperty = DependencyProperty.Register
(nameof(CloseButtonGlyph),
typeof(string),
typeof(ContentDialogTest),
new PropertyMetadata(""));
}
用法
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 集线器。