根据URI检测WPF资源是否存在

14

给定一个pack:// URI,有什么最好的方法可以告诉我们是否在该URI上存在编译资源(例如使用“Resource”构建操作编译的PNG图像)?

经过一些摸索,我想出了下面的代码,它可以工作但很笨拙:

private static bool CanLoadResource(Uri uri)
{
    try
    {
        Application.GetResourceStream(uri);
        return true;
    }
    catch (IOException)
    {
        return false;
    }
}

(请注意,Application.GetResources文档有误--如果未找到资源,它会抛出异常,而不是像文档错误地声明的那样返回null。)(文档已经更正,请参见下面的注释)

我不喜欢用捕获异常来检测一个预期的(非异常的)结果。而且,除此之外,我实际上并不想加载流,我只是想知道它是否存在。

是否有更好的方法来做到这一点,也许是通过更低级别的资源API -- 最好不要实际加载流,并且不需要捕获异常?


他们更新了文档,上面写着当资源未找到时会抛出异常。 - Shimmy Weitzhandler
1
@Shimmy,感谢你的更新--我已经编辑过了,包括了那些信息。 - Joe White
@John White:顺便说一下,我认为你应该将jpierson的帖子标记为答案。 - Shimmy Weitzhandler
1个回答

14
我找到了一个解决方案,它并不能直接使用打包URI,而是通过查找资源路径来使用。话虽如此,这个示例可以很容易地进行修改,以支持打包URI,只需将资源路径添加到使用程序集组成URI的URI的末尾即可。
public static bool ResourceExists(string resourcePath)
{
    var assembly = Assembly.GetExecutingAssembly();

    return ResourceExists(assembly, resourcePath);
}

public static bool ResourceExists(Assembly assembly, string resourcePath)
{
    return GetResourcePaths(assembly)
        .Contains(resourcePath.ToLowerInvariant());
}

public static IEnumerable<object> GetResourcePaths(Assembly assembly)
{
    var culture = System.Threading.Thread.CurrentThread.CurrentCulture;
    var resourceName = assembly.GetName().Name + ".g";
    var resourceManager = new ResourceManager(resourceName, assembly);

    try
    {
        var resourceSet = resourceManager.GetResourceSet(culture, true, true);

        foreach(System.Collections.DictionaryEntry resource in resourceSet)
        {
            yield return resource.Key;
        }
    }
    finally
    {
        resourceManager.ReleaseAllResources();
    }
}

5
GetResourcePaths返回的路径似乎是小写的,因此请确保在ResourceExists方法中使用.Contains(resourcePath.ToLower()) - Simon Fischer
2
为了保险起见,请将其更改为 .ToLowerInvariant() - RandomEngy
希望能看到一个通用的解决方案,可以搜索所有已加载的程序集(也许通过从“pack:”字符串中解析程序集名称来做出有根据的第一猜测)。 - Kirk Kuykendall
1
这是找到资源是否存在的唯一真正答案,您可以使用Build Action > Resource将其编译成程序集。所有其他GetResourceName解决方案都不起作用。非常感谢!@Jpierson - Jason Stevenson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接