原文 https://stackoverflow.com/questions/28240528/how-do-i-duplicate-a-resource-reference-in-code-behind-in-wpf

如何在WPF后台代码中中复制引用的资源?

In my application, I have a color resources. I have one element that uses that color as a dynamic resource in xaml.

  <Window x:Class="ResourcePlay.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="" Width="">
<Window.Resources>
<Color x:Key="MyColor">Red</Color>
</Window.Resources>
<Grid>
<Rectangle VerticalAlignment="Top" Width="" Height="" Margin="">
<Rectangle.Fill>
<SolidColorBrush x:Name="TopBrush" Color="{DynamicResource MyColor}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle VerticalAlignment="Bottom" Width="" Height="" Margin="">
<Rectangle.Fill>
<SolidColorBrush x:Name="BottomBrush"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Window> In the code, I want to duplicate this resource reference. using System.Windows;
using System.Windows.Media; namespace ResourcePlay {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent(); // I want to copy the resource reference, not the color.
BottomBrush.Color = TopBrush.Color; // I'd really rather do something like this.
var reference = TopBrush.GetResourceReference(SolidColorBrush.ColorProperty);
BottomBrush.SetResourceReference(reference); // I want this to change the colors of both elements
Resources["MyColor"] = Colors.Green;
}
}
} However, SetResourceReference only works for FrameworkElements or FrameworkContentElements. SolidColorBrush is just a Freezable. Also, I have no idea how to get a resource reference in code behind. Is there a way to do this in WPF so that both of the colors change at the same time? In my real application, the problem isn't quite so simple, so I can't just add a second DynamicResource in xaml.
Il Vic suggested using reflection. Expanding on that, I was able to build some extension methods for DependencyObject that do what I want. I don't really like using reflection in code, and if someone else knows a better way to implement this, I'd love to see it. At least this will be helpful whenever I'm trying to debug DynamicResources from code behind.

  public static class DependencyObjectExtensions
{
public static object GetDynamicResourceKey(this DependencyObject obj, DependencyProperty prop)
{
// get the value entry from the depencency object for the specified dependency property
var dependencyObject = typeof(DependencyObject);
var dependencyObject_LookupEntry = dependencyObject.GetMethod("LookupEntry", BindingFlags.NonPublic | BindingFlags.Instance);
var entryIndex = dependencyObject_LookupEntry.Invoke(obj, new object[] { prop.GlobalIndex });
var effectiveValueEntry_GetValueEntry = dependencyObject.GetMethod("GetValueEntry", BindingFlags.NonPublic | BindingFlags.Instance);
var valueEntry = effectiveValueEntry_GetValueEntry.Invoke(obj, new object[] { entryIndex, prop, null, 0x10 }); // look inside the value entry to find the ModifiedValue object
var effectiveValueEntry = valueEntry.GetType();
var effectiveValueEntry_Value = effectiveValueEntry.GetProperty("Value", BindingFlags.Instance | BindingFlags.NonPublic);
var effectiveValueEntry_Value_Getter = effectiveValueEntry_Value.GetGetMethod(nonPublic: true);
var rawEntry = effectiveValueEntry_Value_Getter.Invoke(valueEntry, new object[]); // look inside the ModifiedValue object to find the ResourceReference
var modifiedValue = rawEntry.GetType();
var modifiedValue_BaseValue = modifiedValue.GetProperty("BaseValue", BindingFlags.Instance | BindingFlags.NonPublic);
var modifiedValue_BaseValue_Getter = modifiedValue_BaseValue.GetGetMethod(nonPublic: true);
var resourceReferenceValue = modifiedValue_BaseValue_Getter.Invoke(rawEntry, new object[]); // check the ResourceReference for the original ResourceKey
var resourceReference = resourceReferenceValue.GetType();
var resourceReference_resourceKey = resourceReference.GetField("_resourceKey", BindingFlags.NonPublic | BindingFlags.Instance);
var resourceKey = resourceReference_resourceKey.GetValue(resourceReferenceValue); return resourceKey;
} public static void SetDynamicResourceKey(this DependencyObject obj, DependencyProperty prop, object resourceKey)
{
var dynamicResource = new DynamicResourceExtension(resourceKey);
var resourceReferenceExpression = dynamicResource.ProvideValue(null);
obj.SetValue(prop, resourceReferenceExpression);
}
} The second method uses DynamicResourceExtension to avoid some nastiness with Activator, but the first method feels incredibly brittle. I can use these methods in my original example as follows: public MainWindow() {
InitializeComponent(); var key = TopBrush.GetDynamicResourceKey(SolidColorBrush.ColorProperty);
BottomBrush.SetDynamicResourceKey(SolidColorBrush.ColorProperty, key); Resources["MyColor"] = Colors.Green;
} This will work for any DependencyProperty, provided it is set to a DynamicResource when we try to get the resource key. A little more finesse would be needed for production code.

How do I duplicate a resource reference in code behind in WPF?如何在WPF后台代码中中复制引用的资源?的更多相关文章

  1. error: <item> inner element must either be a resource reference or empty.

    FAQ: Android resource compilation failedOutput: /home/cmm/code/AndroidHttpCapture/app/build/intermed ...

  2. 解决问题 inner element must either be a resource reference or empty.

    -Q: 错误<item>内部元素必须是资源引用或空 升级Andriod Studio之后编译发现如下错误 Android resource compilation failed ***\a ...

  3. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  4. Illegal resource reference: @*android resources are private and not always present

    0:前言 在android开发中,当使用别人的代码的时候,在style.xml中有此种错误 1:解决方案 删除*星号

  5. windows phone 7 中怎样定义和使用资源(Resource)

    1. 系统资源. 在wp7开发中可以看到很多使用系统资源(resource)的例子,例如默认的新page: http://blog.csdn.net/matrixcl/article/details/ ...

  6. 【Unity3D】中的空引用 Null Reference Exception

    Null Reference Exception : Object reference not set to an instance of an object. 异常:空引用,对象的引用未设置到对象的 ...

  7. java中的方法引用(method reference)官方文档总结

    2017/7/5 转载写明出处:http://www.cnblogs.com/daren-lin/p/java-method-reference.html 今天要说的是java中的一项新特性,方法引用 ...

  8. 遇到问题---java---myeclipse中maven项目引用另一个导致的resource文件混乱的问题

    遇到情况 情况是这样的,我们在构建项目时,经常会把一些公用的类和配置提取出去,作为一个公共项目.然后把公共项目作为一个jar包构件引入我们当前的项目中. 引入方式是 <dependency> ...

  9. java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)

    之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用.强引用不会被gc回收直到gc roo ...

随机推荐

  1. [React] Recompose: Override Styles & Elements Types in React

    When we move from CSS to defining styles inside components we lose the ability to override styles wi ...

  2. [NPM] List available npm scripts and support tab completion

    In this lesson we will look at different ways you can list the available npm scripts. Whether we wan ...

  3. Java序列化机制中的类版本号问题

    原文地址:http://yanwushu.sinaapp.com/java_serialversionuid/ 内容简单介绍 某些实现了serializable接口的java类中会看到名称为seria ...

  4. 学习鸟哥的Linux私房菜笔记(3)——基础使用

    一.设备文件 设备在Linux中以特殊文件的形式存在 块(block)设备文件 字符(character)设备文件 设备文件所在位置 查看设备类型 二.虚拟控制台及用户身份切换 在系统中有12个虚拟控 ...

  5. vijos1070 新年趣事之游戏 - 次小生成树

    传送门 题目大意: 求原图的最小生成树,和次小生成树. 题目分析: kruskals求mst(\(O(mlogm)\)) 考虑次小生成树暴力的做法,因为次小生成树总是由最小生成树删掉一条边并添加一条边 ...

  6. 利用SendMessage实现窗口拖动

    原文:利用SendMessage实现窗口拖动 利用SendMessage实现窗口拖动                                            周银辉 想想以前用跟踪鼠标位 ...

  7. tensorflow 函数接口的理解

    1. tf.nn.softmax tf.nn.softmax(logits, dim=-1, name=None) w*x+b ⇒ logits softmax 函数执行的操作:exp(logits) ...

  8. 关于java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.makeAccessible

    <span style="font-size:18px;"> java.lang.NoSuchMethodError: org.springframework.util ...

  9. Asp.net压缩网站中的文件

    为了说明自定义虚拟路径,这里弄个示例,仅仅用一个压缩包存放一个网站的多个文件. 这个东西是要需要通过实现3个抽象类来实现: System.Web.Hosting.VirtualPathProvider ...

  10. XSS攻击之基础篇:HTML标签与字符串的渲染

    <body> XSS攻击之基础篇:HTML标签与字符串的渲染 测试 <div class="a1"> </div> <div class= ...