Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.7k views
in Technique[技术] by (71.8m points)

wpf - Error when using StaticResourceExtension inside Style.Resources

I am using DynamicResource in a template, and StaticResourceExtensions as resource inside each style using that template, so that the DynamicResource is evaluated differently in each of them them.

The problem is, I get this error:

Unable to cast object of type 'System.Windows.Media.Effects.DropShadowEffect' to type 'System.Windows.ResourceDictionary'

Here's my code:

<DropShadowEffect 
    x:Key="Sombra" 
    Opacity="0.5" 
    ShadowDepth="3" 
    BlurRadius="5"
/>

<ControlTemplate 
    x:Key="ControleGeometriaTemplate"
    TargetType="{x:Type Control}"
>
    <Border
        x:Name="border"
        Background="{TemplateBinding Background}"
        Width="{TemplateBinding Width}"
        Height="{TemplateBinding Height}"
    />
        <Path
            x:Name="ícone"
            Fill="{TemplateBinding Foreground}"
            Effect="{DynamicResource PathShadow}"
        />
    </Border>
</ControlTemplate>

<Style x:Key="Bot?oGeometria" TargetType="{x:Type ButtonBase}">
    <Setter Property="Template" Value="{StaticResource ControleGeometriaTemplate}"/>
</Style>

<Style 
    x:Key="Bot?oNavega??oBase" 
    TargetType="{x:Type ButtonBase}" 
    BasedOn="{StaticResource Bot?oGeometria}"
>
    <Style.Resources>
        <StaticResource x:Key="PathShadow" ResourceKey="Sombra"/>
    </Style.Resources>      
</Style>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As far as I know StaticResourceExtension does not work properly in some situations.

It smells like you found a similar situation:

<SolidColorBrush x:Key="RedBrush" Color="Red" />
<Style TargetType="TextBox" x:Key="Test">
    <Style.Resources>
        <StaticResourceExtension x:Key="NewRedBrushKey" ResourceKey="RedBrush" />
    </Style.Resources>
</Style>

Using the Test style in your Window is enough to reproduce your issue.

So my suggestion is to use your own extension:

public class ResourceFinder : System.Windows.Markup.MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        FrameworkElement frameworkElement;
        IDictionary dictionary;
        IRootObjectProvider rootObjectProvider = (IRootObjectProvider)
            serviceProvider.GetService(typeof(IRootObjectProvider));

        if (rootObjectProvider != null) 
        {
            dictionary = rootObjectProvider.RootObject as IDictionary;

            if (dictionary != null)
            {
                return dictionary[ResourceKey];
            }
            else
            {
                frameworkElement = rootObjectProvider.RootObject as FrameworkElement;
                if (frameworkElement != null)
                {
                    return frameworkElement.TryFindResource(ResourceKey);
                }
            }

        }

        return null;
    }


    public object ResourceKey
    {
        get;
        set;
    }
}

Then your style will become:

<Style 
    x:Key="Bot?oNavega??oBase" 
    TargetType="{x:Type ButtonBase}" 
    BasedOn="{StaticResource Bot?oGeometria}">
    <Style.Resources>
        <local:ResourceFinder x:Key="PathShadow" ResourceKey="Sombra" />
    </Style.Resources>
</Style>

I hope this can help you with your issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...