Click here to Skip to main content
15,893,487 members
Articles / Desktop Programming / WPF

WPF.JoshSmith

Rate me:
Please Sign up or sign in to vote.
4.99/5 (51 votes)
13 Jul 2008CPOL5 min read 391K   4.8K   263  
A free library of controls and utility classes for use in WPF applications.
// Copyright (C) Josh Smith - July 2008
using System;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Data;

namespace WPF.JoshSmith.Data.ValueConverters
{
    /// <summary>
    /// A value converter that performs a resource lookup on the conversion value.
    /// NOTE: This class depends on the use of reflection to manipulate WPF to allow
    /// an instance of the converter to perform a resource lookup.
    /// </summary>
    /// <remarks>
    /// Documentation: http://www.codeproject.com/KB/WPF/SelectDetailLevels.aspx
    /// </remarks>
    [ValueConversion(typeof(object), typeof(object))]
    public class ResourceKeyToResourceConverter
        : Freezable, // Enable this converter to be the source of a resource lookup.
        IValueConverter
    {
        static readonly DependencyProperty DummyProperty =
            DependencyProperty.Register(
            "Dummy",
            typeof(object),
            typeof(ResourceKeyToResourceConverter));

        /// <summary>
        /// Performs a resource lookup using the value argument as the resource key.
        /// </summary>
        public object Convert(
          object value, Type targetType, object parameter, CultureInfo culture)
        {
            return this.FindResource(value);
        }

        /// <summary>
        /// Do not invoke.
        /// </summary>
        public object ConvertBack(
          object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException("Cannot convert back");
        }

        object FindResource(object resourceKey)
        {
            // NOTE: This code depends on internal implementation details of WPF and 
            // might break in a future release of the platform.  Use at your own risk!

            var resourceReferenceExpression =
                new DynamicResourceExtension(resourceKey).ProvideValue(null)
                as Expression;

            MethodInfo getValue = typeof(Expression).GetMethod(
                "GetValue",
                BindingFlags.Instance | BindingFlags.NonPublic);

            object result = getValue.Invoke(
                resourceReferenceExpression,
                new object[] { this, DummyProperty });

            // Either we do not have an inheritance context or the  
            // requested resource does not exist, so return null.
            if (result == DependencyProperty.UnsetValue)
                return null;

            // The requested resource was found, so we will receive a 
            // DeferredResourceReference object as a result of calling 
            // GetValue.  The only way to resolve that to the actual 
            // resource, without using reflection, is to have a Setter's 
            // Value property unwrap it for us.
            var deferredResourceReference = result;
            Setter setter = new Setter(DummyProperty, deferredResourceReference);
            return setter.Value;
        }

        /// <summary>
        /// Do not invoke.
        /// </summary>
        protected override Freezable CreateInstanceCore()
        {
            // We are required to override this abstract method.
            throw new NotImplementedException();
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Josh creates software, for iOS and Windows.

He works at Black Pixel as a Senior Developer.

Read his iOS Programming for .NET Developers[^] book to learn how to write iPhone and iPad apps by leveraging your existing .NET skills.

Use his Master WPF[^] app on your iPhone to sharpen your WPF skills on the go.

Check out his Advanced MVVM[^] book.

Visit his WPF blog[^] or stop by his iOS blog[^].

See his website Josh Smith Digital[^].

Comments and Discussions