wpf 运行时找不到基于之前定义的 StaticResource 的样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18337002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:28:14  来源:igfitidea点击:

Style based on StaticResource previously defined is not found at runtime

wpftelerikrad-controls

提问by cguedel

I'm using Telerik's RadControls for WPF with implicit styling. The following style is defined in Themes/Windows8/Telerik.Windows.Controls.RibbonView.xaml:

我正在将 Telerik 的 RadControls 用于带有隐式样式的 WPF。以下样式定义在Themes/Windows8/Telerik.Windows.Controls.RibbonView.xaml

<Style TargetType="telerikRibbonView:RadRibbonView" x:Key="RadRibbonViewStyle">
...
</Style>

My own styles and the Telerik default ones get merged like this in the assembly Lib.Windows.Controlsin the folder Themes:

我自己的样式和 Telerik 默认样式Lib.Windows.Controls在文件夹中的程序集中像这样合并Themes

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Windows8/Telerik.Windows.Controls.RibbonView.xaml" />        
        <ResourceDictionary Source="MyTheme/TelerikCustomizations.xaml" />

        <ResourceDictionary>
            <!-- avoid optimization -->
            <Style TargetType="{x:Type Rectangle}" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

And in TelerikCustomizations.xamlI define the following (empty, for testing purposes) style:

TelerikCustomizations.xaml我定义以下(空,用于测试目的)样式:

<Style x:Key="MyThemeRadRibbonViewStyle" TargetType="{x:Type telerik:RadRibbonView}" BasedOn="{StaticResource ResourceKey=RadRibbonViewStyle}" />

Which results in the following exception at runtime:

这会在运行时导致以下异常:

'Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.' Line number '4' and line position '42'. {"Cannot find resource named 'RadRibbonViewStyle'. Resource names are case sensitive."}

'Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.' Line number '4' and line position '42'. {"Cannot find resource named 'RadRibbonViewStyle'. Resource names are case sensitive."}

Which led me to the following debugging statements in MyView.xaml.cs:

这导致我在 MyView.xaml.cs 中出现以下调试语句:

public ShellView()
{
    var baseStyle = FindResource("RadRibbonViewStyle");
    var inherited = FindResource("MyThemeRadRibbonViewStyle");
    InitializeComponent();
}

Now the thing is: The exception is thrown on the second FindResourcecall. With the exact same message. However the RadRibbonViewStyleis clearly found in the first line of the constructor.

现在的事情是:在第二次FindResource调用时抛出异常。带有完全相同的消息。然而RadRibbonViewStyle,在构造函数的第一行中可以清楚地找到。

If it matters, the merged dictionary is actually merged in App.xaml a second time.

如果重要的话,合并的字典实际上第二次合并到 App.xaml 中。

I'm sure I'm missing something obvious, but I can't figure out what.

我确定我遗漏了一些明显的东西,但我不知道是什么。

App.xaml

应用程序.xaml

<Application x:Class="TestClient.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Views/ShellView.xaml">
    <Application.Resources>
      <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Lib.Windows.Controls;component/Themes/MyTheme.xaml" />

              <ResourceDictionary>
                    <!-- added to avoid optimization -->
                    <Style TargetType="{x:Type Rectangle}" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>
</Application>

App.xaml.csdoes not overwrite the constructor. In fact it does not do anything.

App.xaml.cs不会覆盖构造函数。事实上,它没有做任何事情。

Update

更新

If I merge the Telerik dictionaries in TelerikCustomizations.xamlinstead of merging them in yet another dictionary (MyTheme.xaml), the exception disappears.

如果我将 Telerik 字典TelerikCustomizations.xaml合并而不是将它们合并到另一个字典 ( MyTheme.xaml) 中,异常就会消失。

However, I'd still like to know why this happens.

但是,我仍然想知道为什么会发生这种情况。

采纳答案by nemesv

You need to merge in the Windows8/Telerik.Windows.Controls.RibbonView.xamlin your MyTheme/TelerikCustomizations.xaml

你需要Windows8/Telerik.Windows.Controls.RibbonView.xaml在你的 MyTheme/TelerikCustomizations.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Windows8/Telerik.Windows.Controls.RibbonView.xaml" />
        <ResourceDictionary>
            <Style x:Key="MyThemeRadRibbonViewStyle" TargetType="{x:Type telerik:RadRibbonView}" BasedOn="{StaticResource ResourceKey=RadRibbonViewStyle}" />
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

And now you can use/merge this dictionary wherever you want.

现在您可以在任何地方使用/合并这本词典。

You need to do this because StaticResourceis not working between "sister" MergedDictionariesso you cannot reference a resource which was merged on the same level because the StaticResourcelooks only backwards to the directparents:

你需要这样做,因为StaticResource它不在“姐妹”之间工作, MergedDictionaries所以你不能引用在同一级别合并的资源,因为StaticResource它只向后看直接父母:

From MSDN:

MSDN

XAML resource references within a particular resource dictionary must reference a resource that has already been defined with a key, and that resource must appear lexically before the resource reference. Forward references cannot be resolved by a XAML resource reference

特定资源字典中的 XAML 资源引用必须引用已使用键定义的资源,并且该资源必须在词法上出现在资源引用之前。XAML 资源引用无法解析前向引用

But when using MergedDictionaries:

但是在使用时MergedDictionaries

In the resource-lookup sequence, a MergedDictionaries dictionary is checked only after a check of allthe keyed resources of the ResourceDictionary that declared MergedDictionaries.

在资源查找序列中,仅在检查了声明 MergedDictionaries 的 ResourceDictionary的所有键控资源之后,才会检查 MergedDictionaries 字典