'无法从文本 'local:ImageButton' 创建 'Type'
'Failed to create a 'Type' from the text 'local:ImageButton'
我有一个 class 程序集,其中包含许多用户控件。我想向此 class 程序集添加一种新型按钮,并且我还想为其添加样式。具体来说,我想要一个包含多个图像的按钮,用于正常、悬停 (IsMouseOver) 和禁用状态。它还将包含要显示的文本。然后我可以在使用此 class 程序集的任何应用程序中添加它,如下所示:
<ns:ImageTextButton NormalImage="{StaticResource SomeImage}" HoverImage="{StaticResource SomeHoverImage}" Text={StaticResource SomeText}" />
首先我创建了一个 C# class:
public class ImageTextButton : Button {
public DependencyProperty ImageProperty = DependencyProperty.Register(nameof(Image), typeof(DrawingBrush), typeof(ImageTextButton));
public DependencyProperty HoverImageProperty = DependencyProperty.Register(nameof(HoverImage), typeof(DrawingBrush), typeof(ImageTextButton));
public DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(ImageTextButton));
public DrawingBrush Image {
get { return GetValue(ImageProperty) as DrawingBrush; }
set { SetValue(ImageProperty, value); }
}
public DrawingBrush HoverImage {
get { return GetValue(HoverImageProperty) as DrawingBrush; }
set { SetValue(HoverImageProperty, value); }
}
public string Text {
get { return GetValue(TextProperty) as string; }
set { SetValue(TextProperty, value); }
}
}
然后我在 Styles.xaml 文件中创建了一个样式,该文件被编译为 Resource
。
<Style TargetType="{x:Type local:ImageTextButton}" x:Key="ImageTextButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="0" Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}">
<StackPanel>
<Canvas x:Name="canvas" Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}" />
<TextBlock Style="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=TextStyle}"
Text="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Text}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=HoverImage}" TargetName="canvas" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我无法测试这种风格,很可能其中存在问题。我无法启动应用程序,因为上面的 TargetType
不存在。我相信这是因为我的 Styles.xaml 是一个资源,而实际的 class 是编译过的。我收到的错误是 Failed to create a 'Type' from the text 'local:ImageTextButton'.
我怎样才能做到这一点?其次,有什么方法可以默认将这种风格应用到这种类型上吗?我不想总是必须在此用户项的每个实例中指定 Style={StaticResource ImageTextButtonStyle}。
缺少 RelativeSource 模式 FindAncestor
将{RelativeSource AncestorType=local:ImageTextButton}
更改为{RelativeSource FindAncestor, AncestorType=local:ImageTextButton}
首先,您必须决定是要构建 UserControl 还是 CustomControl。
UserControl 需要派生自“UserControl”Base class。当您的 C# 代码扩展“Button”时,该实现不属于“UserControl”。
对于 CustomControl,您的样式应该出现在名为“Generic.xaml”的文件中,该文件应该放在文件夹“Themes”中。 (您仍然可以更改默认的主题文件夹位置)。并且您的 C# 文件应该定义将用于 find/target/identify Xaml 样式的键。
您的上述设置应该不起作用,因为它既不满足用户控件也不满足自定义控件要求。
我无法创建完整的示例,但可以在一定程度上指导您。
您需要使用以下静态方法将默认样式设置为最低限度。根据需要添加剩余属性。
public class ImageButton : Button
{
static ImageButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
}
public ImageButton()
{
}
对于 Xaml 部分。创建一个 Folder Themes 并在其中按名称 "Generic.xaml" 创建一个资源字典。在您的 Generic.Xaml 中,添加您的样式。 (将您的 xaml 逻辑放在控件模板中)。
<Style TargetType="{x:Type bc:ImageButton}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type bc:ImageButton}">
</ControlTemplate>
</Setter>
</Style>
以上都是自定义控件的最低要求。如果您想创建一个 UserControl,您需要一个 .xaml 和一个 .xaml.cs 文件。您可以轻松地使用 visual studio 上下文菜单(右键单击解决方案)并创建用户控件。
重要提示: 当您创建自定义控件时,您不需要像下面这样的东西
Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}">
就用,TemplateBinding
Background="{TemplateBinding Image}">
我有一个 class 程序集,其中包含许多用户控件。我想向此 class 程序集添加一种新型按钮,并且我还想为其添加样式。具体来说,我想要一个包含多个图像的按钮,用于正常、悬停 (IsMouseOver) 和禁用状态。它还将包含要显示的文本。然后我可以在使用此 class 程序集的任何应用程序中添加它,如下所示:
<ns:ImageTextButton NormalImage="{StaticResource SomeImage}" HoverImage="{StaticResource SomeHoverImage}" Text={StaticResource SomeText}" />
首先我创建了一个 C# class:
public class ImageTextButton : Button {
public DependencyProperty ImageProperty = DependencyProperty.Register(nameof(Image), typeof(DrawingBrush), typeof(ImageTextButton));
public DependencyProperty HoverImageProperty = DependencyProperty.Register(nameof(HoverImage), typeof(DrawingBrush), typeof(ImageTextButton));
public DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(ImageTextButton));
public DrawingBrush Image {
get { return GetValue(ImageProperty) as DrawingBrush; }
set { SetValue(ImageProperty, value); }
}
public DrawingBrush HoverImage {
get { return GetValue(HoverImageProperty) as DrawingBrush; }
set { SetValue(HoverImageProperty, value); }
}
public string Text {
get { return GetValue(TextProperty) as string; }
set { SetValue(TextProperty, value); }
}
}
然后我在 Styles.xaml 文件中创建了一个样式,该文件被编译为 Resource
。
<Style TargetType="{x:Type local:ImageTextButton}" x:Key="ImageTextButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="0" Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}">
<StackPanel>
<Canvas x:Name="canvas" Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}" />
<TextBlock Style="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=TextStyle}"
Text="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Text}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=HoverImage}" TargetName="canvas" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我无法测试这种风格,很可能其中存在问题。我无法启动应用程序,因为上面的 TargetType
不存在。我相信这是因为我的 Styles.xaml 是一个资源,而实际的 class 是编译过的。我收到的错误是 Failed to create a 'Type' from the text 'local:ImageTextButton'.
我怎样才能做到这一点?其次,有什么方法可以默认将这种风格应用到这种类型上吗?我不想总是必须在此用户项的每个实例中指定 Style={StaticResource ImageTextButtonStyle}。
缺少 RelativeSource 模式 FindAncestor
将{RelativeSource AncestorType=local:ImageTextButton}
更改为{RelativeSource FindAncestor, AncestorType=local:ImageTextButton}
首先,您必须决定是要构建 UserControl 还是 CustomControl。
UserControl 需要派生自“UserControl”Base class。当您的 C# 代码扩展“Button”时,该实现不属于“UserControl”。
对于 CustomControl,您的样式应该出现在名为“Generic.xaml”的文件中,该文件应该放在文件夹“Themes”中。 (您仍然可以更改默认的主题文件夹位置)。并且您的 C# 文件应该定义将用于 find/target/identify Xaml 样式的键。
您的上述设置应该不起作用,因为它既不满足用户控件也不满足自定义控件要求。
我无法创建完整的示例,但可以在一定程度上指导您。
您需要使用以下静态方法将默认样式设置为最低限度。根据需要添加剩余属性。
public class ImageButton : Button
{
static ImageButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
}
public ImageButton()
{
}
对于 Xaml 部分。创建一个 Folder Themes 并在其中按名称 "Generic.xaml" 创建一个资源字典。在您的 Generic.Xaml 中,添加您的样式。 (将您的 xaml 逻辑放在控件模板中)。
<Style TargetType="{x:Type bc:ImageButton}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type bc:ImageButton}">
</ControlTemplate>
</Setter>
</Style>
以上都是自定义控件的最低要求。如果您想创建一个 UserControl,您需要一个 .xaml 和一个 .xaml.cs 文件。您可以轻松地使用 visual studio 上下文菜单(右键单击解决方案)并创建用户控件。
重要提示: 当您创建自定义控件时,您不需要像下面这样的东西
Background="{Binding RelativeSource={RelativeSource AncestorType=local:ImageTextButton}, Path=Image}">
就用,TemplateBinding
Background="{TemplateBinding Image}">