`

Use an attached Property to set Resources/Styles

    博客分类:
  • WPF
wpf 
阅读更多

Suppose that you have a UserControl and you want to merge some resources (which defines the styles, template and etc). 

 

Suppose again that we cannot add the style to Application or Window, whereas you might conflict with styles that may be used by other part of the application (typical e.g. when the shell is designed by some developers but individual view is taken care by some other developers).

 

You may do something like this :

 

 

<UserControl x:Class="MyView"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             >
  
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/MyModule;component/Resource/Style/DarkStyles.xaml" />
        <ResourceDictionary Source="pack://application:,,,/MyModule;component/Resource/Style/Styles.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    </UserControl.Resources>

</UserControl>
 

 

 

This sound OK, however, suppose there are many of them, and you might need to do the copy and paste more than once.. 

 

which sound OK at initial sight, but look at the possibility of a change, see rename to the styles, things get ugly with copy&paste.

 

 

Suppose that the UserControl may use one/a group of fixed styles, then it make sense to have some way that you can easily pick up the styles.

 

 

One things comes to us is the attached property. below is the impl which leverage the attachedProperty, which accepts a string (in Pack Uri format) to the target style.

 

here are the code.

 

 

 

namespace MyNamespace
{
  public class ResourceLoader
  {


    public static string GetResourcePackUri(DependencyObject obj)
    {
      return (string)obj.GetValue(ResourcePackUriProperty);
    }

    public static void SetResourcePackUri(DependencyObject obj, string value)
    {
      obj.SetValue(ResourcePackUriProperty, value);
    }

    // Using a DependencyProperty as the backing store for ResourcePackUri.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ResourcePackUriProperty =
        DependencyProperty.RegisterAttached("ResourcePackUri", typeof(string), typeof(ResourceLoader), new UIPropertyMetadata(string.Empty, ResourcePackUriChanged));


    private static void ResourcePackUriChanged(object sender_, DependencyPropertyChangedEventArgs args)
    {
      //DependencyPropertyDescriptor dpDescriptor = DependencyPropertyDescriptor.FromName("ResourcePackUri", typeof(ResourceLoader), 
      if (sender_ == null) throw new ArgumentNullException("sender_");
      //DependencyPropertyDescriptor dpDescriptor = DependencyPropertyDescriptor.FromName("ResourcePackUri", typeof(ResourceLoader), sender_.GetType());
      //if (dpDescriptor != null)
      //{
      //}
      var dpObject = sender_ as DependencyObject;

      if (dpObject != null)
      {
        if (dpObject is UserControl)
        {
          var usercontrol = (UserControl)dpObject;
          var uriInString = (string)args.NewValue;
          var uriOld = (string)args.OldValue;
          if (!string.IsNullOrEmpty(uriInString))
          {
            Uri uri = new Uri(uriInString);
            ResourceDictionary resourceNew = new ResourceDictionary();
            resourceNew.Source = uri;

            if (!string.IsNullOrEmpty(uriOld))
            {
              var resourceOld = usercontrol.Resources.MergedDictionaries.FirstOrDefault<ResourceDictionary>(r => r.Source == new Uri(uriOld));
              if (resourceOld != null)
                usercontrol.Resources.MergedDictionaries.Remove(resourceOld);
            }
            usercontrol.Resources.MergedDictionaries.Add(resourceNew);
          }
          else
          {
            throw new ArgumentException("ResourcePackUri only accepts string values");
          }
        }
        else
        {
          // ??
          throw new ArgumentException("AttachedProperty ResourcePackUri is only applicable on UserControl");
        }
      }
    }

  }
}
 

 

 

after this, you may do this to add the attached property to the UserControl.

 

 

 

<UserControl x:Class="MyNamespace.MyView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:local="clr-namespace:MyNamespace"
             local:ResourceLoader.ResourcePackUri="pack://application:,,,/MyModule;component/Resource/Style/MergedStyles.xaml"
             >
</UserControl>
 

 

 

and if you look at the pack://application:,,,/MyModule;component/Resource/Style/MergeStyles.xaml, you will see something like this:

 

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/MyModule;component/Resource/Style/DarkStyles.xaml"/>
    <ResourceDictionary Source="pack://application:,,,/MyModule;component/Resource/Style/Styles.xaml"  />
  </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
  
 

 

Follow this discussion, we mihgt looks into how to make use of the Custom Markup Extension to accomplish the same task.

 

 

分享到:
评论

相关推荐

    问题解决:Fragment not attached to Activity相关代码

    问题解决:Fragment not attached to Activity的相关代码,更多详细内容请参考:http://blog.csdn.net/u012939909/article/details/53355836

    2019年省市区三级联动数据

    2018年最新的省市区联动数据表。一张表搞定全国所有省市区县。

    Windows Presentation Foundation 4.5 Cookbook的源码

    Using an attached property 25 Creating an attached property 28 Accessing a static property from XAML 33 Creating a custom markup extension 37 Handling routed events 44 Chapter 2: Resources 51 ...

    QHierarchy 4.2 最新版Unity插件

    QHierarchy is an editor extension that adds several often used functions to hierarchy window: - Displaying the icon of a GameObject - Showing / hiding a GameObject - Locking / unlocking a GameObject...

    Devphone toolkit开发控件 v2.0源码201271

    Devphone toolkit开发控件 v2.0源码 项目描述: ... Zoom attached property Html attached property Clip attached property 提示: 如果有的项目不能正常加载,请尝试下载安装此程序(类库): ...

    USB Attached SCSI (UAS)(PDF文档)

    USB Attached SCSI(UAS),全称为Universal Serial Bus Attached SCSI,是一种在USB接口上实现SCSI协议的技术,旨在提高外部存储设备的数据传输速度和效率。UAS标准是为了解决传统USB Mass Storage Class(UMSC)...

    xUtils+gson的简单运用

    json数据:{"result":1,"message":"获取信息成功","data":[{"ID":2,"NAME":"呵呵呵呵","TYPE_ID":22,"TEXT":"\u003cimg alt=\"\" src=\"/File/attached/image/20150421/20150421101617_6620.jpg","CREATEDATE":...

    FastReport.v4.15 for.Delphi.BCB.Full.Source企业版含ClientServer中文修正版支持D4-XE5

    + [enterprise] added property "Scheduler" - "StudioPath" in server configuration - set the path to FastReport Studio, leave blank for default - [enterprise] fixed bug with MIME types in http header ...

    NVM-Express-1_4a-2020.03.09-Ratified.pdf

    This interface is optimized for Enterprise and Client solid state drives, typically attached as a register level interface to the PCI Express interface. Note: During development, this specification ...

    XDA成员开发出Carrier IQ检测程序(Android)

    Attached to this post is my app that should interface with these logging services. Lets start by saying I HATE JAVA. Im an IT guy so i know my way around a few languages but im not the best so deal ...

    Android代码-替代Toast的MessageBar

    There's two ways to use the MessageBar. It can either be attached directly to an activity, or a View can be passed. Attaching to an activity This approach requires adding the following attributes to ...

    SSD7 选择题。Multiple-Choice

    When mapping from an ER model to a relational model, a strong entity is mapped into a (a) table (b) row (c) column (d) key Correct answer is (a) 10. Which of the following is true about ...

    Sakemail

    Because some people need to use IP addresses instead of Host names, I‘ve added a new property IPAddress to SakPOP and SakSMTP. If both are filled, then the Host name will be used, thanks to Roger F. ...

    8-07-14_MegaCLI for linux_windows

    SCGCQ00327929 Defect Command to enable Patrol Read on SSDs controller property is not shown in Help SCGCQ00331576 Defect LSI MegaCLI EncInfo (Enclosure Info) duplicates the first power supply status ...

    rexx and jcl

    *--- Desc. : Generate list of packages promoted to DIT2 and not */ /*--- : promoted to SIT2 for V2014 releases ... Get package attached to baselined releases */ /*--- : 3. Get package promotion history

    USB Attached SCSI - 3 (UAS-3) Revision 02 March 29, 2020

    This standard specifies the requirements for the USB Attached SCSI - 3 (UAS-3) transport ... This standard is intended to be used in conjunction with SCSI command set standards and USB specifications.

    SAS (Serial Attached SCSI) 技术详解

    SAS (Serial Attached SCSI) 技术是一种先进的磁盘连接技术,它结合了并行SCSI(Small Computer System Interface)的稳定性和串行连接技术(如FC、SSA、IEEE1394)的高效性。SAS采用了串行通信协议,基于SCSI-3指令...

    ATTACHED

    很抱歉,但根据您给出的信息,"ATTACHED" 和 "831" 并没有提供足够的上下文来生成一个超过1000字的详细IT知识文章。标题和描述都是相同的,而“字体”作为标签可能指的是文件内容涉及到字体设计、使用或技术。然而,...

    CyAPI说明文档

    When a CCyUSBDevice object is open to an attached USB device, its endpoint members provide an interface for performing data transfers to and from the device's endpoints. Endpoint-specific data members...

Global site tag (gtag.js) - Google Analytics