Exemplo n.º 1
0
        private static bool TryGetImageResource(Type owningType, FieldInfo field, ResourceDictionary imageResources, string subPath)
        {
            if (string.IsNullOrEmpty(subPath))
            {
                throw new ArgumentNullException("subPath");
            }

            // Get Image attributes
            object[] attributes = field.GetCustomAttributes(typeof(ImageResourceAttribute), false);

            if (attributes.Length == 0)
            {
                return(false);
            }

            var       attribute = (ImageResourceAttribute)attributes[0];
            Freezable img       = null;

            if (string.IsNullOrEmpty(attribute.ImageName1))
            {
                throw new InvalidOperationException("Cannot have an image attribute whose first image name is null or empty");
            }
            var extension = Path.GetExtension(attribute.ImageName1);

            if (string.IsNullOrEmpty(extension))
            {
                throw new InvalidOperationException("Cannot have an image attribute whose first image name has no extension");
            }
            extension = extension.ToLower();

            // Generate packUri
            var assmName       = owningType.Assembly.GetName();
            var basePackUriRel = "/" + assmName + ";component/" + subPath;

            if (!basePackUriRel.EndsWith("/"))
            {
                basePackUriRel += "/";
            }

            if (extension == ".xaml")
            {
                var uri = new Uri(basePackUriRel + attribute.ImageName1, UriKind.Relative);
                img = Application.LoadComponent(uri) as Freezable;
                if (img == null)
                {
                    throw new InvalidOperationException("Invalid xaml image resource: " + attribute.ImageName1);
                }
            }
            else if (extension == ".cur")
            {
                var uri = new Uri(basePackUriRel + attribute.ImageName1, UriKind.Relative);

                try
                {
                    var info = Application.GetResourceStream(uri);
                    img = new FreezableCursor {
                        Cursor = new System.Windows.Input.Cursor(info.Stream)
                    };
                }
                catch (IOException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
            }
            else if (extension == ".bmp" || extension == ".png" || extension == ".ico")
            {
                // First attempt to retrieve the image as an 'Embedded Resource' (ie legacy WinForms-era resource compilation)
                var stream = owningType.Assembly.GetManifestResourceStream(owningType + "." + attribute.ImageName1);
                if (stream != null)
                {
                    img = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None);
                }
                else
                {
                    // image must be compiled in as a 'Linked Resource' (ie WPF-era resource compilation)
                    var basePackUriAbs = "pack://application:,,," + basePackUriRel;
                    var uri            = new Uri(basePackUriAbs + attribute.ImageName1);
                    try
                    {
                        img = new BitmapImage(uri);
                    }
                    catch (IOException ex)
                    {
                        System.Diagnostics.Debug.WriteLine(ex.Message);
                    }
                }
            }
            else
            {
                throw new Exception(
                          "Unrecognized extension '" + extension + "' on image resource '" + field.Name + "'");
            }

            if (img == null)
            {
                throw new Exception("Failed to create image from image resource '" + field.Name + "'");
            }

            // Might it be better to keep the img as a DrawingGroup and then assign to relevant Image type later?
            if (img is DrawingGroup)
            {
                var brush = new DrawingBrush(img as DrawingGroup);
                brush.Stretch = Stretch.Uniform;
                img           = brush;
            }

            if (img.CanFreeze && !img.IsFrozen)
            {
                img.Freeze();
            }

            object imageKey = owningType.FullName + "." + attribute.ImageName1;

            if (field.FieldType.IsAssignableFrom(typeof(ResourceKey)))
            {
                var componentResourceKey = new ComponentResourceKey(owningType, imageKey);
                s_resourceKeys[attribute.ImageName1] = componentResourceKey;
                imageKey = componentResourceKey;
            }

            field.SetValue(owningType, imageKey);
            if (!imageResources.Contains(imageKey))
            {
                imageResources.Add(imageKey, img);
            }

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Registers any attributed resource keys found on the type</summary>
        /// <param name="type">Type, usually a static set of keys</param>
        /// <param name="resourcePath">Path to resources</param>
        public static void Register(Type type, string resourcePath)
        {
            if (s_registeredTypes.Contains(type))
            {
                return;
            }

            s_registeredTypes.Add(type);

            // Generate packUri
            AssemblyName assmName            = type.Assembly.GetName();
            string       relativePackUriBase = "/" + assmName.Name + ";component/" + resourcePath;
            string       absolutePackUriBase = "pack://application:,,," + relativePackUriBase;

            ResourceDictionary imageResources = null;

            FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
            foreach (FieldInfo field in fields)
            {
                // Get Image attributes
                object[] attributes = field.GetCustomAttributes(typeof(WpfImageResourceAttribute), false);

                if (attributes.Length > 0)
                {
                    if (!field.FieldType.IsAssignableFrom(typeof(ResourceKey)))
                    {
                        System.Diagnostics.Debug.WriteLine("Warning: WpfImageResourceAttribute used on a field which is not a ResourceKey");
                    }

                    var       attribute = (WpfImageResourceAttribute)attributes[0];
                    Freezable img       = null;
                    string    extension = System.IO.Path.GetExtension(attribute.ImageName).ToLower();

                    if (extension == ".bmp" || extension == ".png" || extension == ".ico")
                    {
                        var uri = new Uri(absolutePackUriBase + attribute.ImageName);
                        try
                        {
                            img = new BitmapImage(uri);
                        }
                        catch (IOException ex)
                        {
                            System.Diagnostics.Debug.WriteLine(ex.Message);
                        }
                    }
                    else if (extension == ".xaml")
                    {
                        var uri = new Uri(relativePackUriBase + attribute.ImageName, UriKind.Relative);
                        img = Application.LoadComponent(uri) as Freezable;

                        if (img == null)
                        {
                            throw new InvalidOperationException("Invalid xaml image resource: " + attribute.ImageName);
                        }
                    }
                    else if (extension == ".cur")
                    {
                        var uri = new Uri(relativePackUriBase + attribute.ImageName, UriKind.Relative);

                        try
                        {
                            var info = Application.GetResourceStream(uri);
                            img = new FreezableCursor {
                                Cursor = new System.Windows.Input.Cursor(info.Stream)
                            };
                        }
                        catch (IOException ex)
                        {
                            System.Diagnostics.Debug.WriteLine(ex.Message);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Unrecognized Wpf image resource file extension for file: " + attribute.ImageName);
                    }

                    if (img != null)
                    {
                        // Might it be better to keep the img as a DrawingGroup and then assign to relevant Image type later?
                        if (img is DrawingGroup)
                        {
                            var brush = new DrawingBrush(img as DrawingGroup);
                            brush.Stretch = Stretch.Uniform;
                            img           = brush;
                        }

                        if (img.CanFreeze && !img.IsFrozen)
                        {
                            img.Freeze();
                        }

                        object imageKey = type.FullName + "." + attribute.ImageName;

                        if (field.FieldType.IsAssignableFrom(typeof(ResourceKey)))
                        {
                            imageKey = new ComponentResourceKey(type, imageKey);
                        }

                        field.SetValue(type, imageKey);

                        if (imageResources == null)
                        {
                            imageResources = new ResourceDictionary();
                        }

                        imageResources.Add(imageKey, img);
                    }
                }

                // Get ResourceDictionary attributes
                if (field.FieldType == typeof(string))
                {
                    attributes = field.GetCustomAttributes(typeof(ResourceDictionaryResourceAttribute), false);

                    if (attributes.Length > 0)
                    {
                        var attribute = attributes[0] as ResourceDictionaryResourceAttribute;

                        var    dictionary = new ResourceDictionary();
                        string uri        = absolutePackUriBase + attribute.Path;
                        dictionary.Source = new Uri(uri, UriKind.RelativeOrAbsolute);

                        Application.Current.Resources.MergedDictionaries.Add(dictionary);
                    }
                }
            }

            if (imageResources != null)
            {
                Application.Current.Resources.MergedDictionaries.Add(imageResources);
            }
        }