'无法从文本 '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}">