【问题标题】:pack uri validation打包 uri 验证
【发布时间】:2010-06-10 20:21:03
【问题描述】:

验证是否可以找到包 uri 的最简单方法是什么?

例如,给定

pack://application:,,,Rhino.Mocks;3.5.0.1337;0b3305902db7183f;component/SomeImage.png

如何检查图片是否真实存在?

干杯,
浆果

【问题讨论】:

    标签: c# uri


    【解决方案1】:

    我找不到一个简单的答案,所以我最终滚动自己的代码来完成与图像资源相关的三件事:
    (1) 有一个包 uri 的字符串表示(数据绑定)
    (2) 验证图像是否位于我认为的位置(单元测试)
    (3) 验证pack uri可以用来设置图片(单元测试)

    这并不简单的部分原因是,pack uri 一开始有点令人困惑,而且有多种风格。此代码用于表示包含在 VS 程序集中的图像的包 uri(本地或具有“资源”构建操作的引用程序集。此 msdn articles 阐明了在此上下文中的含义。您还需要了解更多关于程序集和构建的信息,而不是最初看起来的好时机。

    希望这对其他人来说更容易。干杯,
    浆果

        /// <summary> (1) Creates a 'Resource' pack URI .</summary>
        public static Uri CreatePackUri(Assembly assembly, string path, PackType packType)
        {
            Check.RequireNotNull(assembly);
            Check.RequireStringValue(path, "path");
    
            const string startString = "pack://application:,,,/{0};component/{1}";
            string packString;
            switch (packType)
            {
                case PackType.ReferencedAssemblySimpleName:
                    packString = string.Format(startString, assembly.GetName().Name, path);
                    break;
                case PackType.ReferencedAssemblyAllAvailableParts:
                    // exercise for the reader
                    break;
                default:
                    throw new ArgumentOutOfRangeException("packType");
            }
            return new Uri(packString);
        }
    
        /// <summary>(2) Verify the resource is located where I think it is.</summary>
        public static bool ResourceExists(Assembly assembly, string resourcePath)
        {
            return GetResourcePaths(assembly).Contains(resourcePath.ToLowerInvariant());
        }
    
        public static IEnumerable<object> GetResourcePaths(Assembly assembly, CultureInfo culture)
        {
            var resourceName = assembly.GetName().Name + ".g";
            var resourceManager = new ResourceManager(resourceName, assembly);
    
            try
            {
                var resourceSet = resourceManager.GetResourceSet(culture, true, true);
    
                foreach (DictionaryEntry resource in resourceSet)
                {
                    yield return resource.Key;
                }
            }
            finally
            {
                resourceManager.ReleaseAllResources();
            }
        }
    
        /// <summary>(3) Verify the uri can construct an image.</summary>
        public static bool CanCreateImageFrom(Uri uri)
        {
            try
            {
                var bm = new BitmapImage(uri);
                return bm.UriSource == uri;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return false;
            }
        }
    

    【讨论】:

      【解决方案2】:
      Public Class Res
      
          Private Shared __keys As New List(Of String)
      
          Shared Function Exist(partName As String) As Boolean
              Dim r As Boolean = False
      
              If __keys.Count < 1 Then
                  Dim a = Assembly.GetExecutingAssembly()
                  Dim resourceName = a.GetName().Name + ".g"
                  Dim resourceManager = New ResourceManager(resourceName, a)
                  Dim resourceSet = resourceManager.GetResourceSet(Globalization.CultureInfo.CurrentCulture, True, True)
                  For Each res As System.Collections.DictionaryEntry In resourceSet
                      __keys.Add(res.Key)
                  Next
              End If
      
              __keys.ForEach(Sub(e)
                                 If e.Contains(partName.ToLower) Then
                                     r = True
                                     Exit Sub
                                 End If
                             End Sub)
      
              Return r
          End Function
      End Class
      

      【讨论】:

        【解决方案3】:

        我知道,这个问题很老了,但也许有人有同样的问题。 我也有一个问题,我想在单元测试中测试我的资源字符串。

        最简单的解决方案是初始化一个 ResourceDictionary。您还可以使用 dictionary.Keys["myKey"] 访问特定键并检查内容。

        [SetUp]
        public void OnTestInitialize()
        {
            if (!UriParser.IsKnownScheme("pack"))
            {
               new Application();
            }
        }
        
        [TestCase]
        public void TestIfResourcesExist()
        {
            var resources = new [] {
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml",
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml",
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml"
            };
        
            foreach (var mergedResource in resources)
            {
                // init
                ResourceDictionary dictionary =
                    new ResourceDictionary {Source = new Uri(mergedResource, UriKind.RelativeOrAbsolute)};
        
                // verify
                dictionary.Keys.Count.Should().BeGreaterThan(0);
            }
        }
        


        顺便说一句,这是我在 App.xaml.cs 中注册我的资源的方式(所以我可以在每个单元测试中测试它们):

        public static class ResourceManager
        {
            public static readonly string[] MergedResources = {
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonColors.xaml",
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/CommonStyles.xaml",
                "pack://application:,,,/Tracto.UI.Infrastructure;component/Dictionaries/GridSplitterStyle.xaml"
            };
        
            public static void AddResources()
            {
                Application.Current.Resources.BeginInit();
                foreach (var resource in MergedResources)
                {
                    Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
                    {
                        Source = new Uri(resource, UriKind.Absolute)
                    });
                }
                Application.Current.Resources.EndInit();
            }
        }
        

        在 OnStartup 中:

        // add xaml resources (styles, colors, ...)
        ResourceManager.AddResources();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-23
          • 2011-02-05
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多