WPF:InvalidCastException:无法将“System.Windows.Style”类型的对象转换为“System.Windows.ResourceDictionary”类型
Posted
技术标签:
【中文标题】WPF:InvalidCastException:无法将“System.Windows.Style”类型的对象转换为“System.Windows.ResourceDictionary”类型【英文标题】:WPF: InvalidCastException: Unable to cast object of type 'System.Windows.Style' to type 'System.Windows.ResourceDictionary' 【发布时间】:2021-07-13 14:39:25 【问题描述】:我尝试在我的控件中重新设置 TextBoxes 的样式,以使 ReadOnly 具有相同的外观,就好像它们被禁用一样。 上周我可以毫无问题地做到这一点:
<UserControl.Resources>
<Style TargetType="x:Type Border" x:Key="TextBoxBorderStyle">
<Style.Triggers>
<DataTrigger Binding="Binding IsReadOnly, RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=TextBoxBase" Value="True">
<Setter Property="Opacity" Value="0.56"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
... 并像这样在 TextBoxes 中使用它:
<TextBox Text="Binding MyText"
IsReadOnly="Binding ReadOnly"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" >
<TextBox.Resources>
<StaticResource ResourceKey="TextBoxBorderStyle" />
</TextBox.Resources>
</TextBox>
我不记得在此期间更改此控件中的任何内容。 (虽然我今天将 Visual Studio 2019 更新为 16.9.4)。但是当我现在运行我的应用程序时,它给出了一个运行时错误:
System.Windows.Markup.XamlParseException HResult=0x80131501 Message='设置属性'System.Windows.FrameworkElement.Resources' 抛出异常。行号“90”和行位置“33”。 来源=PresentationFramework StackTrace:在 System.Windows.Markup.XamlReader.RewrapException(异常 e, IXamlLineInfo lineInfo, Uri baseUri)
此异常最初是在此调用堆栈中引发的: System.Windows.Baml2006.WpfSharedBamlSchemaContext.Create_BamlProperty_FrameworkElement_Resources.AnonymousMethod__276_0(对象, 目的) MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(object, System.Xaml.XamlMember, object)
内部异常 1:InvalidCastException:无法转换类型的对象 'System.Windows.Style' 输入 'System.Windows.ResourceDictionary'。
当我将样式直接复制粘贴到所有 Textbox.Resources
中时,它可以正常工作。
有谁知道为什么?
尤其是因为之前分享StaticResource
没有问题。
编辑:它在 xaml 编辑器/设计器中按预期工作,并正确地将样式调整为视图模型数据,没有任何异常。只有在运行时才会出现问题。
【问题讨论】:
确保您的目标是您之前使用的相同版本的 Net,或者执行干净的构建以使用最新版本的 Net。 我没有更改目标 .NET 版本(4.7.2),我尝试了 clean+rebuild,关闭 VS,删除 .vs 文件夹,但到目前为止没有任何帮助。一定有什么我错过了。奇怪的是它只在设计时工作(它甚至可以很好地响应我的设计时视图模型的变化) 【参考方案1】:您应该将<StaticResource ResourceKey="TextBoxBorderStyle" />
替换为实际的Style
:
<TextBox Text="Binding MyText"
IsReadOnly="Binding ReadOnly"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" >
<TextBox.Resources>
<Style TargetType="Border" BasedOn="StaticResource TextBoxBorderStyle" />
</TextBox.Resources>
</TextBox>
...或更改Style
的TargetType
并简单地设置TextBox
的Style
属性:
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="TextBoxBorderStyle">
<Style.Resources>
<Style TargetType="x:Type Border">
<Style.Triggers>
<DataTrigger Binding="Binding IsReadOnly, RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=TextBoxBase" Value="True">
<Setter Property="Opacity" Value="0.56"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
</UserControl.Resources>
用法:
<TextBox Text="Binding MyText"
IsReadOnly="Binding ReadOnly"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"
Style="StaticResource TextBoxBorderStyle" />
【讨论】:
谢谢。很简单。仍然奇怪为什么我这样做的方式在设计和运行时表现不同。虽然我现在还发现我们的应用程序在运行时动态加载了一个 3rd 方主题,它没有在设计器中加载,所以它在设计时使用默认样式和模板,在运行时使用 3r 方主题(它有模板中没有 Border 子元素,所以触发器没有效果 - 所以我设置了另一个属性/对象)【参考方案2】:替换
<TextBox Text="Binding MyText"
IsReadOnly="Binding ReadOnly"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" >
<TextBox.Resources>
<StaticResource ResourceKey="TextBoxBorderStyle" />
</TextBox.Resources>
</TextBox>
有
<TextBox Text="Binding MyText"
IsReadOnly="Binding ReadOnly"
VerticalScrollBarVisibility="Disabled"
HorizontalScrollBarVisibility="Disabled"
Style=DynamicResource TextBoxBorderStyle/>
这应该可以解决问题。如果没有,请尝试通过删除旧样式并通过转到该文本框并右键单击 - 编辑样式/模板 - 编辑副本来创建新样式来重置您的资源字典 然后选择“资源字典”并选择你的资源字典
【讨论】:
谢谢,但样式适用于 TextBox 内边框。不适用于整个 TextBox,因此这将给出“'Border' TargetType does not match type of element 'TextBox'”。我不确定您所说的“删除旧样式并制作新样式”是什么意思,因为我既不是源自也不是指任何自定义主题或样式。也许我忘了提到样式是在自定义控件的根中定义的。 您的意思是创建并使用带有附加触发器的默认 ControlTemplate 的副本以启用 ReadOnly 的边框样式?它可能是一个选项,但它会完全覆盖当前的 ControlTemplate,如果使用另一个基本主题或样式,它可能会改变。 我的意思是为整个文本框制作一个样式。这并不难 - 你可以为那部分使用触发器 我知道。只是默认模板调整了边框的属性,而不是文本框的属性,我希望它看起来一样。 (但是我现在发现在运行时使用了不同的模板,因此我需要以某种方式为此提取 xaml 以添加已定义触发器的副本以禁用作为只读触发器的新触发器)以上是关于WPF:InvalidCastException:无法将“System.Windows.Style”类型的对象转换为“System.Windows.ResourceDictionary”类型的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin 形式:System.InvalidCastException:'指定的转换无效
Xamarin 形式:System.InvalidCastException:“指定的强制转换无效。”
C# 转换枚举 InvalidCastException 错误
在 Unity 中使用泛型... InvalidCastException