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

本杰明

在我的应用程序中,我有一种颜色资源。我有一个元素使用该颜色作为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="350" Width="425">
     <Window.Resources>
        <Color x:Key="MyColor">Red</Color>
     </Window.Resources>
     <Grid>
        <Rectangle VerticalAlignment="Top" Width="80" Height="80" Margin="10">
           <Rectangle.Fill>
              <SolidColorBrush x:Name="TopBrush" Color="{DynamicResource MyColor}"/>
           </Rectangle.Fill>
        </Rectangle>
        <Rectangle VerticalAlignment="Bottom" Width="80" Height="80" Margin="10">
           <Rectangle.Fill>
              <SolidColorBrush x:Name="BottomBrush"/>
           </Rectangle.Fill>
        </Rectangle>
     </Grid>
  </Window>

在代码中,我想复制此资源引用。

  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;
        }
     }
  }

但是,SetResourceReference仅适用于FrameworkElements或FrameworkContentElements。SolidColorBrush只是一个Freezable。另外,我也不知道如何在后面的代码中获得资源引用。

在WPF中有没有一种方法可以使两种颜色同时改变?在我的实际应用程序中,问题并不是那么简单,所以我不能只在xaml中添加第二个DynamicResource。

本杰明

Il Vic建议使用反射。对此进行扩展,我能够为DependencyObject构建一些可以实现我想要的扩展方法。我真的不喜欢在代码中使用反射,如果其他人知道实现此目标的更好方法,我很乐意看到它。至少当我尝试从后面的代码调试DynamicResources时,这将很有帮助。

  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[0]);

        // 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[0]);

        // 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);
     }
  }

第二种方法用于DynamicResourceExtension避免使用Activator造成麻烦,但是第一种方法感觉非常脆弱。

我可以在原始示例中使用这些方法,如下所示:

  public MainWindow() {
     InitializeComponent();

     var key = TopBrush.GetDynamicResourceKey(SolidColorBrush.ColorProperty);
     BottomBrush.SetDynamicResourceKey(SolidColorBrush.ColorProperty, key);

     Resources["MyColor"] = Colors.Green;
  }

这将对任何DependencyProperty都适用,只要我们尝试获取资源密钥时将其设置为DynamicResource。生产代码将需要更多技巧。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在WPF资源中创建对公共类的引用?

来自分类Dev

WPF-如何在资源字典中设置键集时引用资源中的样式

来自分类Dev

如何在Dart网页中引用资源

来自分类Dev

如何在代码隐藏中添加资源

来自分类Dev

如何在运行时将动态资源分配给WPF代码中的按钮

来自分类Dev

如何在C代码中引用汉字

来自分类Dev

如何在Markdown中引用代码?

来自分类Dev

如何在DSC脚本资源中引用脚本参数

来自分类Dev

如何在Terraform中引用for_each创建的资源

来自分类Dev

如何在Lambda中引用通过SAM创建的AWS资源?

来自分类Dev

如何在Terraform中引用用for_each创建的资源

来自分类Dev

如何在cloudformation策略文档中引用资源ARN?(yaml)

来自分类Dev

如何在新的Cloudformation模板中引用Cloudformation资源?

来自分类Dev

如何在eclipse中引用android框架资源?

来自分类Dev

如何在定义中引用自我?

来自分类Dev

如何在SKScene中引用我的UIViewController?

来自分类Dev

我将如何在php和html中引用此代码

来自分类Dev

如何在Java中复制对File对象的引用

来自分类Dev

如何在Word中复制对活动列表编号的引用?

来自分类Dev

如何在我的代码中实现AsyncTask?

来自分类Dev

如何在 xaml 中编写我的代码

来自分类Dev

如何在本地Perl代码中复制cat / sort / uniq?

来自分类Dev

如何在C#WPF中引用和使用标签

来自分类Dev

我如何在 delphi 中获得可绘制的资源 ID?

来自分类Dev

如何在 SpringSecurity 中访问我的资源

来自分类Dev

如何在代码库中查找未引用的类

来自分类Dev

如何在Sencha Touch代码中获得Cordova插件的引用

来自分类Dev

如何在pandoc markdown中引用受保护的代码块?

来自分类Dev

如何在Sencha Touch代码中获得Cordova插件的引用

Related 相关文章

  1. 1

    如何在WPF资源中创建对公共类的引用?

  2. 2

    WPF-如何在资源字典中设置键集时引用资源中的样式

  3. 3

    如何在Dart网页中引用资源

  4. 4

    如何在代码隐藏中添加资源

  5. 5

    如何在运行时将动态资源分配给WPF代码中的按钮

  6. 6

    如何在C代码中引用汉字

  7. 7

    如何在Markdown中引用代码?

  8. 8

    如何在DSC脚本资源中引用脚本参数

  9. 9

    如何在Terraform中引用for_each创建的资源

  10. 10

    如何在Lambda中引用通过SAM创建的AWS资源?

  11. 11

    如何在Terraform中引用用for_each创建的资源

  12. 12

    如何在cloudformation策略文档中引用资源ARN?(yaml)

  13. 13

    如何在新的Cloudformation模板中引用Cloudformation资源?

  14. 14

    如何在eclipse中引用android框架资源?

  15. 15

    如何在定义中引用自我?

  16. 16

    如何在SKScene中引用我的UIViewController?

  17. 17

    我将如何在php和html中引用此代码

  18. 18

    如何在Java中复制对File对象的引用

  19. 19

    如何在Word中复制对活动列表编号的引用?

  20. 20

    如何在我的代码中实现AsyncTask?

  21. 21

    如何在 xaml 中编写我的代码

  22. 22

    如何在本地Perl代码中复制cat / sort / uniq?

  23. 23

    如何在C#WPF中引用和使用标签

  24. 24

    我如何在 delphi 中获得可绘制的资源 ID?

  25. 25

    如何在 SpringSecurity 中访问我的资源

  26. 26

    如何在代码库中查找未引用的类

  27. 27

    如何在Sencha Touch代码中获得Cordova插件的引用

  28. 28

    如何在pandoc markdown中引用受保护的代码块?

  29. 29

    如何在Sencha Touch代码中获得Cordova插件的引用

热门标签

归档