2010-07-28 1 views
5

J'ai un contrôle utilisateur UserControl qui se trouve dans un assembly Assembly. J'ai une application WPF qui instancie UserControl d'une manière programmatique. J'ai déjà ajouté une référence à l'Assemblée. Cependant, pendant l'exécution, je reçois le ff. exception:System.IO.IOException dans PresentationFramework.dll lors de l'instanciation d'un contrôle utilisateur dans WPF

Cannot locate resource 'usercontrol.xaml'. 
    at MS.Internal.AppModel.ResourcePart.GetStreamCore(FileMode mode, FileAccess access) 
    at System.IO.Packaging.PackagePart.GetStream(FileMode mode, FileAccess access) 
    at System.IO.Packaging.PackagePart.GetStream() 
    at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) 
    ... 

J'ai changé l'action de construction pour UserControl.xaml à EmbeddedResource mais cela a causé des problèmes de compilation si je l'ai remis à la mise en page par défaut. J'ai essayé ceci dans .NET 3 et 4 en vain. Quelqu'un a quelquonque idée?

+1

solution propre et la reconstruction, peut-être cela aidera. –

+0

Déjà essayé cela en vain. –

+0

Etrange ... J'ai créé une nouvelle compilation pour essayer la réponse de Ray Burns ci-dessous et maintenant ça semble fonctionner correctement. J'aurais juré que j'avais fait au moins deux cycles de construction propre. –

Répondre

6

La cause la plus fréquente de ceci est si vous renommez un assemblage. Je vais expliquer ce scénario, puis donner d'autres possibilités.

Supposons que vous avez un projet DLL "Abc" contenant UserControl "MyControl". Le InitializeComponent généré pour MyControl dans Abc.dll contiendra le Uri "/Abc;Component/MyControl.xaml".

Lors de l'exécution, le nom de l'assembly "Abc" est extrait et les assemblys chargés sont recherchés pour un assembly de ce nom. Si un tel assembly est trouvé mais qu'il n'a pas de ressource "MyControl.xaml", vous obtenez l'erreur que vous avez affichée dans la question.

Voici donc le scénario:

  • renommer le fichier Abc.dll à Def.dll
  • Vous (ou quelqu'un) crée un fichier Abc.dll différent
  • Dans votre projet, vous faites référence Def.dll (qui a été compilé comme Abc.dll)
  • Votre projet a également directement ou indirectement des références Abc.dll il est chargé lorsque MyControl est instancié

Maintenant, lorsque vous instanciez MyControl à partir Def.dll, il recherche son xaml dans l'assembly Abc.dll au lieu de l'assembly Def.dll.

D'autres scénarios dans lesquels cela peut se produire:

  • Vous avez un fichier .g.cs périmé dans votre répertoire obj qui a le mauvais nom pour le fichier XAML. Cela peut se produire si vous avez modifié le code source sans mettre à jour la date (ce qui peut se produire lors d'une extraction à partir d'un système de contrôle de source ou d'un dézippage d'un fichier zip ou de plusieurs autres façons). Le nettoyage et la reconstruction de la solution permettront de résoudre ce problème. Puisque votre commentaire dit que vous avez essayé cela, cela ne s'applique pas à vous.

  • Vous modifiez manuellement les noms de ressources dans le fichier .dll après qu'il a été compilé

  • Vous avez chargé deux assemblées avec le même nom (oui, cela est possible), et le chargeur de ressources trouvé le mauvais un

Notez que toute modification du chemin d'accès au fichier XAML, comme changement de nom ou de le déplacer, peut provoquer ce problème si le fichier .g.cs ne correspond pas au chemin dans les ressources.

Pour diagnostiquer votre problème plus loin, je vous recommande de télécharger une copie de NET Reflector et de regarder votre.Fichier dll à voir:

  1. Qu'est-ce que Uri fait pour InitializeComponent()?
  2. Existe-t-il un fichier .baml portant le même nom?

Vous pouvez également examiner la pile d'appels au point où l'exception est levée pour vous assurer que le gestionnaire de ressources utilisé contient une référence à l'assembly attendu, et non un autre assembly.

+0

Pourquoi cherche-t-il le XAML? Je pensais que le XAML est nécessaire uniquement pour dériver le fichier g.cs. –

+0

Reconstruire semble avoir fait l'affaire. J'ai créé un nouveau build pour tester votre réponse et je ne l'ai pas encore rencontré. Je sais que j'ai dit que j'ai déjà essayé et je suis vraiment sûr de l'avoir fait. –

+2

Pour répondre à votre question: Lorsque vous générez votre projet, votre fichier .xaml est converti en deux fichiers: un fichier .g.cs et un fichier .baml. Le compilateur C# compile le fichier .g.cs à IL et l'inclut dans votre assembly. Le .baml est ajouté à votre assembly en tant que ressource. Dans le fichier .g.cs, le chemin d'accès au fichier .baml est répertorié mais son extension est ".xaml". Application.LoadComponent a une logique interne qui remplace l'extension ".xaml" par ".baml" avant de rechercher les ressources dans l'assembly. Ainsi, vous avez IL (code) qui spécifie ".xaml" mais la ressource elle-même a l'extension ".baml". –

0

J'ai reçu cette erreur après avoir déplacé toutes mes fenêtres WPF dans un nouveau dossier du projet appelé "Windows". Je corrige l'erreur en allant dans « app.xaml » et mettre à jour le chemin de la fenêtre principale à:

StartupUri = « Windows \ MainWindow.xaml »

Questions connexes