2010-01-06 11 views
11

Dato un pacchetto: // URI, qual è il modo migliore per determinare se esiste effettivamente una risorsa compilata (ad esempio un'immagine PNG, compilata con un'azione di compilazione di "Risorsa") URI?Rileva se esiste una risorsa WPF, basata sull'URI

Dopo un po 'inciampare in giro, sono arrivato fino a questo codice, che funziona ma è goffo:

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

(Si noti che la documentazione Application.GetResourcesis wrong - viene generata un'eccezione se la risorsa non viene trovato , invece di restituire nulla, come i documenti in modo non corretto stato.)(la documentazione sono stati corretti, vedi commenti qui sotto)

non mi piace la cattura di eccezioni per rilevare un non eccezionale) risultato atteso (. E inoltre, in realtà non voglio caricare il flusso, voglio solo sapere se esiste.

C'è un modo migliore per farlo, magari con API di risorse di livello inferiore - idealmente senza caricare effettivamente il flusso e senza catturare un'eccezione?

+0

Hanno aggiornato il documento, esso dice che esso genera un'eccezione quando la risorsa non viene trovata. – Shimmy

+1

@Shimmy, grazie per l'aggiornamento - Ho modificato per includere tali informazioni. –

+0

@John White: BTW, penso che dovresti contrassegnare [post di jpierson] (http://stackoverflow.com/questions/2013481/detect-whether-wpf-resource-exists-based-on-uri/2549641#2549641) come risposta. – Shimmy

risposta

10

Ho trovato una soluzione che sto utilizzando che non funziona direttamente con un pacchetto Uri ma cerca una risorsa dal suo percorso di risorse. Detto questo, questo esempio potrebbe essere modificato abbastanza facilmente per supportare un URI di pacchetto invece semplicemente attaccando sul percorso della risorsa alla fine di un uri che usa l'Assembly per formulare la parte di base dell'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

Sembra che i percorsi restituiti da 'GetResourcePaths' è caratteri minuscoli quindi assicuratevi di usare' .Contains (resourcePath.ToLower()); 'nel metodo' ResourceExists'. –

+2

Rendi ".ToLowerInvariant()" solo per sicurezza. – RandomEngy

Problemi correlati