首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用<Style TargetType=时无法强制转换错误

使用<Style TargetType=时无法强制转换错误
EN

Stack Overflow用户
提问于 2013-03-01 03:43:05
回答 3查看 5.1K关注 0票数 3

我正在尝试使用资源字典和style TargetType属性来更改解决方案中按钮的外观。当加载第一个按钮时,我在运行时收到一个强制转换错误。如果我在按钮的属性中手动设置样式,一切都可以正常工作,但重点是更改所有按钮的外观,而不是一次更改一个。

下面是相关的例外:

代码语言:javascript
复制
System.Windows.Markup.XamlParseException occurred
  HResult=-2146233087
  Message='Initialization of 'System.Windows.Controls.Button' threw an exception.' Line number '6' and line position '72'.
  Source=PresentationFramework
  LineNumber=6
  LinePosition=72
  StackTrace:
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at WpfTestApplication.Views.MainWindow.InitializeComponent() in d:\TFSC\CUDL\Research\Chris.Dailey\WpfTestApplication\WpfTestApplication\Views\MainWindow.xaml:line 1
       at WpfTestApplication.Views.MainWindow..ctor() in d:\TFSC\CUDL\Research\Chris.Dailey\WpfTestApplication\WpfTestApplication\Views\MainWindow.xaml.cs:line 28
  InnerException: System.InvalidCastException
       HResult=-2147467262
       Message=Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.Windows.FrameworkTemplate'.
       Source=PresentationFramework
       StackTrace:
            at System.Windows.Controls.Control.OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
            at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
            at System.Windows.StyleHelper.ApplyStyleOrTemplateValue(FrameworkObject fo, DependencyProperty dp)
            at System.Windows.StyleHelper.InvalidateContainerDependents(DependencyObject container, FrugalStructList`1& exclusionContainerDependents, FrugalStructList`1& oldContainerDependents, FrugalStructList`1& newContainerDependents)
            at System.Windows.StyleHelper.DoStyleInvalidations(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle)
            at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
            at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
            at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
            at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty   dp, Boolean preserveCurrentValue)
            at System.Windows.FrameworkElement.UpdateStyleProperty()
            at System.Windows.FrameworkElement.OnInitialized(EventArgs e)
            at System.Windows.FrameworkElement.TryFireInitialized()
            at System.Windows.FrameworkElement.EndInit()
            at MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin)
       InnerException: 

下面是相关的代码。

代码语言:javascript
复制
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    <Style TargetType="{x:Type Button}">
    <Style TargetType="{x:Type Button}">
        <Setter Property="Control.Template" Value="{StaticResource ButtonTemplate}"
    </Style>
    <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
        <Border Name="Border" BorderBrush="Orange" BorderThickness="3" CornerRadius="3" Background="Red" TextBlock.Foreground="White">
            <Grid>
                <Rectangle Name="FocusCue" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2" SnapsToDevicePixels="True" ></Rectangle>
                <ContentPresenter RecognizesAccessKey="True" Margin="{TemplateBinding Padding}"></ContentPresenter>
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="Border" Property="Background" Value="DarkRed" />
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter TargetName="Border" Property="Background" Value="IndianRed" />
                <Setter TargetName="Border" Property="BorderBrush" Value="DarkKhaki" />
            </Trigger>
            <Trigger Property="IsKeyboardFocused" Value="True">
                <Setter TargetName="FocusCue" Property="Visibility" Value="Visible" />
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter TargetName="Border" Property="TextBlock.Foreground" Value="Gray" />
                <Setter TargetName="Border" Property="Background" Value="MistyRose" />
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</ResourceDictionary>

代码语言:javascript
复制
<Window x:Class="WpfTestApplication.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<WrapPanel>
    <Button x:Name="ButtonGradient" Click="ButtonGradient_OnClick">Gradient</Button>
    <Button x:Name="ButtonDrawing" Click="ButtonDrawing_OnClick">Drawing</Button>
    <Button x:Name="ButtonEventTester"  Click="ButtonEventTester_OnClick">Event Tester</Button>
    <Button x:Name="ButtonCommandTester"  Style="{x:Null}" Command="New">Execute a Command</Button>
</WrapPanel>

如果您对可能导致此问题的原因提供任何意见,我将不胜感激。外部错误是完全无用的,我对此了解不够多,无法理解为什么会发生强制转换错误。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-01 04:19:24

使用VS2012和你上面的风格,我能够成功地应用你的ControlTemplate。我确实先把它包装在Style中,但这更多的是一个偏好问题。

唯一的另一个区别是,我不得不猜测你的Border做了什么,因为它没有包括在内。

下面的风格在设计时和运行时都能完美地工作:

代码语言:javascript
复制
<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Name="Border" Background="LightBlue">
                    <Grid>
                        <Rectangle Name="FocusCue" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2" SnapsToDevicePixels="True" ></Rectangle>
                        <ContentPresenter RecognizesAccessKey="True" Margin="{TemplateBinding Padding}"></ContentPresenter>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="Border" Property="Background" Value="DarkRed" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="Border" Property="Background" Value="IndianRed" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="DarkKhaki" />
                    </Trigger>
                    <Trigger Property="IsKeyboardFocused" Value="True">
                        <Setter TargetName="FocusCue" Property="Visibility" Value="Visible" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="TextBlock.Foreground" Value="Gray" />
                        <Setter TargetName="Border" Property="Background" Value="MistyRose" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
票数 3
EN

Stack Overflow用户

发布于 2017-08-27 05:44:59

在Xaml代码中,order matters。将模板放在引用它的样式之上。

在使用WPF资源时,请记住以正确的顺序声明资源。

必须先定义在其他地方引用的样式或模板,然后才能使用它。换句话说,如果Style1使用BrushA作为StaticResource,那么BrushA必须在Style1之前定义。否则,你会得到一些有趣的错误,比如:

无法将'MS.Internal.NamedObject‘类型的对象强制转换为'System.Windows.FrameworkTemplate'类型

票数 1
EN

Stack Overflow用户

发布于 2016-05-12 21:57:41

我也遇到了类似的问题,结果是我的风格是使用StaticResource而不是DynamicResource。http://blog.alner.net/archive/2010/05/07/wpf-style-and-template-resources_order-matters.aspx

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15144245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档