wpf - 目标类型与元素类型不匹配,控件不会显示在设计器中
问题描述
我们有一些具有自己的样式、模板的自定义控件。基本上是这样的:(我将在最后发布完整的样式/模板)
public class CustomBtn : Button
{
public propdp DependencyProp1...
public propdp DependencyProp2...
...
}
<Style x:Key="XStyle.CustomBtnStyle" TargetType="{x:Type cc:CustomBtn}">
...
<Setter Property="Template" Value="{StaticResource XControlTemplate.CustomButton}"/>
<ControlTemplate x:Key="XControlTemplate.CustomButton" TargetType="{x:Type cc:CustomBtn}">
...
定义的一些属性在模板中使用,一些在样式中使用。
我们一直面临的问题是这些控件不会显示在设计器中(大部分时间),而是显示为好像它们已损坏。错误为“目标类型与元素类型不匹配”
- 运行时没有问题
- 我们的任何自定义控件中都没有私有/无默认构造函数。
- 我有一个更新的 DesignTimeResources
- 我注意到错误中有一个奇怪的差异,在控件名称后面的数字之间
那里有很多类似的问题,但所附答案对我不起作用/适用。
尽管有时在修改样式/类之后,设计师会以非常基本的形式显示它们......直到它不再出现。
样式,类(为代码墙道歉):
public class ButtonIcon : Button { // VisualTheme 确定颜色主题 public EVisualTheme VisualTheme { get { return (EVisualTheme)GetValue(VisualThemeProperty); } set { SetValue(VisualThemeProperty, value); } }
// Using a DependencyProperty as the backing store for VisualTheme. This enables animation, styling, binding, etc... public static readonly DependencyProperty VisualThemeProperty = DependencyProperty.Register("VisualTheme", typeof(EVisualTheme), typeof(ButtonIcon), new PropertyMetadata(EVisualTheme.Common)); // Icon for Button public Geometry IconGeometry { get { return (Geometry)GetValue(IconGeometryProperty); } set { SetValue(IconGeometryProperty, value); } } // Using a DependencyProperty as the backing store for IconGeometry. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconGeometryProperty = DependencyProperty.Register("IconGeometry", typeof(Geometry), typeof(ButtonIcon), new PropertyMetadata(new PathGeometry())); public double IconSize { get { return (double)GetValue(IconSizeProperty); } set { SetValue(IconSizeProperty, value); } } // Using a DependencyProperty as the backing store for IconSize. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconSizeProperty = DependencyProperty.Register("IconSize", typeof(double), typeof(ButtonIcon), new PropertyMetadata(40.0)); // Text to be set on Button public object Caption { get { return (object)GetValue(CaptionProperty); } set { SetValue(CaptionProperty, value); } } // Using a DependencyProperty as the backing store for Caption. This enables animation, styling, binding, etc... public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(object), typeof(ButtonIcon), new PropertyMetadata(null)); // For running Animations from 0 to 1 in order to change Animation property during Runtime (see examples of usage in code) public double GradientPercentage { get { return (double)GetValue(GradientPercentageProperty); } set { SetValue(GradientPercentageProperty, value); } } // Using a DependencyProperty as the backing store for GradientPercentage. This enables animation, styling, binding, etc... public static readonly DependencyProperty GradientPercentageProperty = DependencyProperty.Register("GradientPercentage", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); public Point IconRenderTransformOrigin { get { return (Point)GetValue(IconRenderTransformOriginProperty); } set { SetValue(IconRenderTransformOriginProperty, value); } } // Using a DependencyProperty as the backing store for IconRenderTransformOrigin. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconRenderTransformOriginProperty = DependencyProperty.Register("IconRenderTransformOrigin", typeof(Point), typeof(ButtonIcon), new PropertyMetadata(new Point(0.5, 0.5))); // Angle at which to rotate Icon public double IconRotationAngle { get { return (double)GetValue(IconRotationAngleProperty); } set { SetValue(IconRotationAngleProperty, value); } } // Using a DependencyProperty as the backing store for IconRotationAngle. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconRotationAngleProperty = DependencyProperty.Register("IconRotationAngle", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); // CenterX for Icon rotation public double IconRotationCenterX { get { return (double)GetValue(IconRotationCenterXProperty); } set { SetValue(IconRotationCenterXProperty, value); } } // Using a DependencyProperty as the backing store for IconRotationCenterX. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconRotationCenterXProperty = DependencyProperty.Register("IconRotationCenterX", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); // CenterY for Icon rotation public double IconRotationCenterY { get { return (double)GetValue(IconRotationCenterYProperty); } set { SetValue(IconRotationCenterYProperty, value); } } // Using a DependencyProperty as the backing store for IconRotationCenterY. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconRotationCenterYProperty = DependencyProperty.Register("IconRotationCenterY", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); // ScaleX of Icon public double IconScaleX { get { return (double)GetValue(IconScaleXProperty); } set { SetValue(IconScaleXProperty, value); } } // Using a DependencyProperty as the backing store for IconScaleX. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconScaleXProperty = DependencyProperty.Register("IconScaleX", typeof(double), typeof(ButtonIcon), new PropertyMetadata(1.0)); // ScaleY of Icon public double IconScaleY { get { return (double)GetValue(IconScaleYProperty); } set { SetValue(IconScaleYProperty, value); } } // Using a DependencyProperty as the backing store for IconScaleY. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconScaleYProperty = DependencyProperty.Register("IconScaleY", typeof(double), typeof(ButtonIcon), new PropertyMetadata(1.0)); // CenterX for Icon scale public double IconScaleCenterX { get { return (double)GetValue(IconScaleCenterXProperty); } set { SetValue(IconScaleCenterXProperty, value); } } // Using a DependencyProperty as the backing store for IconScaleCenterX. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconScaleCenterXProperty = DependencyProperty.Register("IconScaleCenterX", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); // CenterY for Icon scale public double IconScaleCenterY { get { return (double)GetValue(IconScaleCenterYProperty); } set { SetValue(IconScaleCenterYProperty, value); } } // Using a DependencyProperty as the backing store for IconScaleCenterY. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconScaleCenterYProperty = DependencyProperty.Register("IconScaleCenterY", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); public double IconTranslateX { get { return (double)GetValue(IconTranslateXProperty); } set { SetValue(IconTranslateXProperty, value); } } // Using a DependencyProperty as the backing store for IconTranslateX. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconTranslateXProperty = DependencyProperty.Register("IconTranslateX", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0)); public double IconTranslateY { get { return (double)GetValue(IconTranslateYProperty); } set { SetValue(IconTranslateYProperty, value); } } // Using a DependencyProperty as the backing store for IconTranslateY. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconTranslateYProperty = DependencyProperty.Register("IconTranslateY", typeof(double), typeof(ButtonIcon), new PropertyMetadata(0.0));
}
<Style x:Key="XStyle.ButtonIcon.Action" TargetType="{x:Type cc:ButtonIcon}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Height" Value="{StaticResource XDouble.Height.Button.Default}"/>
<Setter Property="Template" Value="{StaticResource XControlTemplate.ButtonIcon.Action}"/>
<Setter Property="IconSize" Value="30"/>
<Setter Property="GradientPercentage" Value="0.0"/>
<Setter Property="IconGeometry" Value="{x:Null}"/>
<Setter Property="FontSize" Value="{StaticResource XDouble.FontSize.Header3}"/>
<Setter Property="Foreground" Value="{Binding VisualTheme, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type cc:ButtonIcon}}, Converter={rconv:VisualThemeToForegroundConverter}}"/>
<Setter Property="BorderBrush" Value="{StaticResource XBrush.Frame}"/>
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<Trigger Property="VisualTheme" Value="ListItem">
<Setter Property="BorderThickness" Value="{StaticResource XThickness.Border.Frame}"/>
</Trigger>
<Trigger Property="VisualTheme" Value="DarkOnLight">
<Setter Property="BorderThickness" Value="{StaticResource XThickness.Border.Frame}"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="XControlTemplate.ButtonIcon.Action" TargetType="{x:Type cc:ButtonIcon}">
<Border
x:Name="OuterBorder"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="10,0"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{StaticResource XCornerRadius.Frame}">
<Border.Background>
<MultiBinding Converter="{rconv:PercentageToBrushConverter}">
<Binding Path="GradientPercentage" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type cc:ButtonIcon}}" />
<Binding Path="VisualTheme" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type cc:ButtonIcon}}" />
</MultiBinding>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="IconColumn" Width="Auto" />
<ColumnDefinition x:Name="SpacerColumn" Width="10" />
<ColumnDefinition x:Name="CaptionColumn" Width="*" />
</Grid.ColumnDefinitions>
<Border
x:Name="IconBorder"
Width="{TemplateBinding IconSize}"
Height="{TemplateBinding IconSize}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Path
x:Name="IconPart"
Data="{TemplateBinding IconGeometry}"
Fill="{TemplateBinding Foreground}"
RenderTransformOrigin="{Binding Path=IconRenderTransformOrigin, RelativeSource={RelativeSource TemplatedParent}}"
Stretch="Uniform">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform
CenterX="{Binding Path=IconScaleCenterX, RelativeSource={RelativeSource TemplatedParent}}"
CenterY="{Binding Path=IconScaleCenterY, RelativeSource={RelativeSource TemplatedParent}}"
ScaleX="{Binding Path=IconScaleX, RelativeSource={RelativeSource TemplatedParent}}"
ScaleY="{Binding Path=IconScaleY, RelativeSource={RelativeSource TemplatedParent}}" />
<RotateTransform
Angle="{Binding Path=IconRotationAngle, RelativeSource={RelativeSource TemplatedParent}}"
CenterX="{Binding Path=IconRotationCenterX, RelativeSource={RelativeSource TemplatedParent}}"
CenterY="{Binding Path=IconRotationCenterY, RelativeSource={RelativeSource TemplatedParent}}" />
</TransformGroup>
</Path.RenderTransform>
</Path>
</Border>
<ContentPresenter
x:Name="ContentPresenter"
Grid.Column="2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Content="{TemplateBinding Caption}"
Focusable="False"
SnapsToDevicePixels="True"
TextBlock.FontSize="{TemplateBinding FontSize}"
TextBlock.Foreground="{TemplateBinding Foreground}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="{StaticResource XDouble.Opacity.Disabled}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="StoryBoardMouseEnter" Storyboard="{StaticResource XStoryboard.DoubleAnimation.GradientPercentage.RunUp}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard x:Name="StoryBoardMouseLeave" Storyboard="{StaticResource XStoryboard.DoubleAnimation.GradientPercentage.RunDown}" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="Caption" Value="{x:Null}">
<Setter TargetName="ContentPresenter" Property="Visibility" Value="Collapsed" />
<Setter TargetName="IconColumn" Property="Width" Value="*" />
<Setter TargetName="SpacerColumn" Property="Width" Value="0" />
<Setter TargetName="CaptionColumn" Property="Width" Value="0" />
</Trigger>
<Trigger Property="Caption" Value="">
<Setter TargetName="ContentPresenter" Property="Visibility" Value="Collapsed" />
<Setter TargetName="IconColumn" Property="Width" Value="*" />
<Setter TargetName="SpacerColumn" Property="Width" Value="0" />
<Setter TargetName="CaptionColumn" Property="Width" Value="0" />
</Trigger>
<Trigger Property="IconGeometry" Value="{x:Null}">
<Setter TargetName="IconPart" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="SpacerColumn" Property="Width" Value="0"/>
<Setter TargetName="IconColumn" Property="Width" Value="0"/>
<Setter TargetName="ContentPresenter" Property="Grid.Column" Value="0"/>
<Setter TargetName="ContentPresenter" Property="Grid.ColumnSpan" Value="3"/>
<Setter TargetName="ContentPresenter" Property="HorizontalAlignment" Value="Center"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
解决方案
推荐阅读
- windows - 编译时如何自动包含依赖的dll?
- swift - 如何使用异步等待 Swift 5.5 等待 x 秒
- reactjs - 如何修复“NativeFirebaseError: [storage/object-not-found] No object exists at the desired reference.”?
- javascript - 2021 年在 Web 应用程序中嵌入 HTML 页面最安全的方法是什么:iframe、对象、嵌入或其他方式?
- python - (XML) 如果节点具有给定值,则获取元素
- java - 如何优化将一种对象类型的列表转换为另一种?
- python - 删除带有熊猫的行,字段中的字符串长度过长
- javascript - 相当于 Python 列表 (l) 的 Chrome Javascript 调试器
- javascript - 如何使用 javascript 选择“srcset”属性的值?
- python - 如何使 Google Colab 代码适应 AWS lambda 函数?