原文 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. 从show slave status 中1062错误提示信息找到binlog的SQL

    mysql> show slave status\G *************************** 1. row *************************** Slave_I ...

  2. 下载的pod链接失效,build diff: /../Podfile.lock: No such file or directory解决办法

    build diff: /../Podfile.lock: No such file or directory 1.终端进入文件路径,执行pod install 2.在工程设置中的Build Phas ...

  3. 【u239】整数分解

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 某些数能表示成为一些互不相同的整数的阶乘之和.如9=l!+2! +3!. 现在给定一个非负整数n,要求 ...

  4. STS开发环境搭建与配置

    STS开发环境搭建与配置 (2012-04-11 07:24:51) 转载▼ 1.   环境准备 安装JDK.MAVEN 1.1.        下载 下载sprdfingsource-tool-su ...

  5. NOIP模拟 乘积 - 状压dp + 分组背包

    题目大意: 给出n和k,求从小于等于n的数中取出不超过k个,其乘积是无平方因子数的方案数.无平方因子数:不能被质数的平方整除. 题目分析: 10(枚举\(n\le8\)),40(简单状压\(n\le1 ...

  6. oracle 全部查询和表空间,以及其关系

    select * from dba_users;   查看数据库里面全部用户,前提是你是有dba权限的帐号.如sys,system select * from all_users;     查看你能管 ...

  7. 【t096】树的序号

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 我们可以用下面的方案给二叉树标号: 空树的序号为0. 只有一个根结点的树序号为1. 所有包含m个结点的 ...

  8. htmlunit 模拟登录 数字验证码

    使用htmlunit的好处有两点,相比httpclient,htmlunit是对浏览器的模拟,比如你定位一个按钮,就可以执行click()方法,此外不需要象在httpclient中一样编写复杂的代码, ...

  9. Web自动化测试(全网最给力自动化教程)

    http://www.cnblogs.com/zidonghua/p/7430083.html python+selenium自动化软件测试(第2章):WebDriver API 欢迎您来阅读和练手! ...

  10. FrameLayout帧布局

    一.FrameLayout(帧布局)重点: FrameLayout(帧布局)可以说是五大布局中最为简单的一个布局,这个布局会默认把控件放在屏幕上的左上角的区域,后续添加的控件会覆盖前一个,如果控件的大 ...