wpf - ComponentResourceKey 作为 DynamicResource 的问题

标签 wpf xaml systemcolors dynamicresource componentresourcekey

我在使用 ComponentResourceKey 时发现一些意外行为。出现问题是因为我使用了 SystemColors 类中使用的名称。

考虑以下代码:

首先,我将 a 中的 ComponentResourceKey 公开为静态属性:


public enum ColorKeys
{
    ControlColor
}

public class MyColors
{
    public static ComponentResourceKey ControlColorKey
    {
        get 
        { 
            return new ComponentResourceKey(typeof(MyColors), ColorKeys.ControlColor); 
        }
    }
}

使用标记中的键将资源分配给该键是可行的。使用 ComponentResourceKey 标记将该资源作为 DynamicResource 调用是可行的。但是使用静态属性调用同一资源会解析为 SystemColors.ControlColorKey 资源。

这是 xaml:

<Window.Resources>
    <Color x:Key="{x:Static l:MyColors.ControlColorKey}">#FF0000FF</Color>
    <SolidColorBrush x:Key="UsingVerbose" 
                     Color="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type l:MyColors}, 
                                ResourceId={x:Static l:ColorKeys.ControlColor}}}"/>
    <SolidColorBrush x:Key="UsingStatic" 
                     Color="{DynamicResource {x:Static l:MyColors.ControlColorKey}}"/>                
</Window.Resources>
<Grid>
    <StackPanel>
        <Button Height="20" Width="80" Background="{DynamicResource UsingVerbose}" Content="Verbose"/>
        <Button Height="20" Width="80" Background="{DynamicResource UsingStatic}" Content="Static"/>
    </StackPanel>
</Grid>

显示窗口时,“详细”按钮会正确显示蓝色背景。但下方的“静态”按钮显示 SystemColors.ControlColorKey 颜色。

将静态属性的名称更改为另一个名称会使两个画笔解析为正确的颜色。

但我不确定为什么 DynamicResource 对 key 的静态实例和标记实例化的实例的解析不同?

谢谢,

K

PS:这里是ResourceDictionarySource的相关trace输出

System.Windows.ResourceDictionary Start: 10 : New resource dictionary set; Owner='TestMergedDictionaries.Window1'; Owner.HashCode='64923656'; Owner.Type='TestMergedDictionaries.Window1'; OldDictionary='0'; NewDictionary='System.Windows.ResourceDictionary'; NewDictionary.HashCode='44624228'; NewDictionary.Type='System.Windows.ResourceDictionary'
System.Windows.ResourceDictionary Stop: 10 : 
System.Windows.ResourceDictionary Start: 12 : Deferred resource has been added to ResourceDictionary; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'
System.Windows.ResourceDictionary Stop: 12 : 
System.Windows.ResourceDictionary Start: 12 : Deferred resource has been added to ResourceDictionary; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='UsingVerbose'
System.Windows.ResourceDictionary Stop: 12 : 
System.Windows.ResourceDictionary Start: 12 : Deferred resource has been added to ResourceDictionary; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='UsingStatic'
System.Windows.ResourceDictionary Stop: 12 : 
System.Windows.ResourceDictionary Start: 11 : Searching for resource; Element='System.Windows.Controls.Button'; Element.HashCode='52727599'; Element.Type='System.Windows.Controls.Button'; ResourceKey='UsingVerbose'
System.Windows.ResourceDictionary Start: 3 : Found resource item on an element; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='UsingVerbose'; Value='System.Windows.DeferredResourceReference'; Value.HashCode='14347911'; Value.Type='System.Windows.DeferredResourceReference'
System.Windows.ResourceDictionary Stop: 3 : 
System.Windows.ResourceDictionary Stop: 11 : Searching for resource; Element='System.Windows.Controls.Button'; Element.HashCode='52727599'; Element.Type='System.Windows.Controls.Button'; ResourceKey='UsingVerbose'

... removed uninteresting traces ...

System.Windows.ResourceDictionary Start: 11 : Searching for resource; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'
System.Windows.ResourceDictionary Start: 3 : Found resource item on an element; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'; Value='System.Windows.DeferredResourceReference'; Value.HashCode='23488915'; Value.Type='System.Windows.DeferredResourceReference'
System.Windows.ResourceDictionary Stop: 3 : 
System.Windows.ResourceDictionary Stop: 11 : Searching for resource; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'

System.Windows.ResourceDictionary Start: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='23264094'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='System.Windows.Controls.TextBlock'; Value='DefAttributeKeyType typeId=TextBlock'; Value.HashCode='23521433'; Value.Type='System.Windows.Markup.BamlDefAttributeKeyTypeRecord'
System.Windows.ResourceDictionary Stop: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='23264094'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='System.Windows.Controls.TextBlock'; Value='System.Windows.Style'; Value.HashCode='5'; Value.Type='System.Windows.Style'

System.Windows.ResourceDictionary Start: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='UsingStatic'; Value='DefAttributeKeyString'; Value.HashCode='24854661'; Value.Type='System.Windows.Markup.BamlDefAttributeKeyStringRecord'
System.Windows.ResourceDictionary Start: 11 : Searching for resource; Element=''; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'
System.Windows.ResourceDictionary Start: 8 : Found resource item in theme; Dictionary='System.Windows.SystemResourceHost'; Dictionary.HashCode='65273341'; Dictionary.Type='System.Windows.SystemResourceHost'; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'; Value='#FFF0F0F0'
System.Windows.ResourceDictionary Stop: 8 : 
System.Windows.ResourceDictionary Stop: 11 : Searching for resource; Element=''; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'
System.Windows.ResourceDictionary Stop: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='UsingStatic'; Value='#FFF0F0F0'; Value.HashCode='12408161'; Value.Type='System.Windows.Media.SolidColorBrush'

System.Windows.ResourceDictionary Start: 11 : Searching for resource; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'
System.Windows.ResourceDictionary Start: 8 : Found resource item in theme; Dictionary='System.Windows.SystemResourceHost'; Dictionary.HashCode='65273341'; Dictionary.Type='System.Windows.SystemResourceHost'; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'; Value='#FFF0F0F0'
System.Windows.ResourceDictionary Stop: 8 : 
System.Windows.ResourceDictionary Stop: 11 : Searching for resource; Element='TestMergedDictionaries.Window1'; Element.HashCode='64923656'; Element.Type='TestMergedDictionaries.Window1'; ResourceKey='ControlColor'; ResourceKey.HashCode='35'; ResourceKey.Type='System.Windows.SystemResourceKey'

System.Windows.ResourceDictionary Start: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'; Value='KeyElementStart typeId=StaticExtension'; Value.HashCode='54371668'; Value.Type='System.Windows.Markup.BamlKeyElementStartRecord'
System.Windows.ResourceDictionary Stop: 2 : Delayed creation of resource; Dictionary='System.Windows.ResourceDictionary'; Dictionary.HashCode='44624228'; Dictionary.Type='System.Windows.ResourceDictionary'; ResourceKey='TargetType=TestMergedDictionaries.MyColors ID=ControlColor'; ResourceKey.HashCode='1936592'; ResourceKey.Type='System.Windows.ComponentResourceKey'; Value='#FF0000FF'

最佳答案

在您的静态 ControlColorKey 中,每次访问 getter 时,您都会创建一个 ComponentResourceKey 的新实例。因此,第二次使用引用了不同的对象并且没有获得更新的颜色。 如果您将代码更改为简单的静态字段,它会按预期工作:

public static ComponentResourceKey ControlColorKey = new ComponentResourceKey(typeof(MyColors), ColorKeys.ControlColor);

关于wpf - ComponentResourceKey 作为 DynamicResource 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1610090/

相关文章:

wpf - 从 HierachicalDataTemplate 绑定(bind)到 TreeView 的 DataContext

c# - 如何将 X 按钮绑定(bind)到窗口的关闭按钮

silverlight - 无法在 Silverlight 的样式中添加系统颜色?

wpf - 如何从样式影响子控件属性

jquery - 在 IE 中使用 jQuery 从 CSS 获取系统颜色

c# - 列出所有系统颜色

c# - 按下鼠标左键时更改鼠标光标?

c# - 强制 DataGrid 列验证 (WPF)

c# - "parameter count mismatch"调用方法时

wpf - 将图标添加到 WPF 数据网格中