验证可以找到包uri的最简单方法是什么?
例如,给定
pack://application:,,,Rhino.Mocks;3.5.0.1337;0b3305902db7183f;component/SomeImage.png
如何检查图像是否确实存在?
干杯,
Berryl
答案 0 :(得分:5)
我找不到一个简单的答案,所以我结束了自己的代码来完成关于图像资源的三件事:
(1)具有包uri(数据绑定)的字符串表示
(2)验证图像位于我认为它所在的位置(单元测试)
(3)验证包uri是否可用于设置图像(单元测试)
部分原因并不简单,因为打包uri一开始有点令人困惑,而且有几种风格。此代码用于包uri,表示包含在VS程序集中的图像(本地或带有'resource'构建操作的引用程序集。此msdn articles阐明了在此上下文中的含义。您还可以需要了解更多有关装配和构建的信息,而不是最初看起来像是一个好时机。
希望这会让其他人更容易。干杯,
Berryl
/// <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;
}
}
答案 1 :(得分:1)
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
答案 2 :(得分:1)
我知道,这个问题很老,但也许有人有同样的问题。 我也有问题,我想在单元测试中测试我的资源字符串。
最简单的解决方案是初始化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();