it-swarm.com.de

Die Komponente verfügt nicht über eine durch den URI identifizierte Ressource

Ich möchte ein generisches DataGrid erstellen, das für alle meine Views/UserControls verwendet werden soll.

Das ist meine Struktur:

Class Library aufgerufen "Core":

Class aufgerufen "ViewBase":

public class ViewBase : UserControl
{
    public ViewBase()
    {
    }   

    //Rest of Methods and Properties
}

Class Library aufgerufen "Controls":

UserControl aufgerufen "GridView":

XAML:

    <vb:ViewBase x:Class="Controls.GridView"
             xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:vb="clr-namespace:Core;Assembly=Core">

    <Grid>
        <DataGrid></DataGrid>
    </Grid>

    </vb:ViewBase>

Code hinter:

using Core;

public partial class GridView : ViewBase
{
    public GridView ()
    {
        InitializeComponent();
    }
}

Dann ist die WPF-Anwendung namens "WPFApp":

Class aufgerufen "View":

using Controls;

public class View : GridView
{
    public View()
    {
        InitializeComponent();
    }
}

Meine ganze Idee ist, GridView zu verwenden, wo ich eine DataGrid brauche.

Wenn ich die Anwendung starte, erhalte ich diesen Fehler:

"The component 'WpfApp.View' does not have a resource identified by the URI '/Controls;component/GridView.xaml'."

Was mache ich falsch?

Ist das der richtige Ansatz oder bin ich weit weg?

39
Willem

Ich habe etwas sehr ähnliches mit dem gleichen Ergebnis gemacht. Ich hatte eine C # -Klassenbibliothek, die ein WPF-Steuerelement namens UsageControl (xaml mit der zugehörigen xaml.cs-Datei) enthielt. In einem separaten C # -Projekt (d. H. Einer separaten DLL) habe ich ein C # Klasse CPUUsageControl erstellt, das geerbt von UsageControl ist, aber seinen eigenen Dreh darauf legt. Als ich versucht habe, das CpuUsageControl in einer meiner Ansichten zu verwenden, ist derselbe Fehler aufgetreten, den Sie gemacht haben.

Anstatt eine Klasse zu erstellen, die vom Basissteuerelement geerbt wurde, habe ich ein neues WPF-Steuerelement erstellt, das enthalten das Basissteuerelement. Ich habe dann die gesamte Logik, die in der CpuUsage-Klasse enthalten war, in den Code des WpfCpuUsageControls eingefügt. Ich war in der Lage, dieses Objekt zu verwenden. Alle meine anderen Steuerelemente sind in Ordnung.

Für Ihr Steuerelement "GridView" würde ich ein neues WPF-Benutzersteuerelement erstellen, es als GridView bezeichnen und enthalten eine "ViewBase" als Inhalt des Grid-Steuerelements.Inside von Der ViewBase-Inhalt wird in Ihr DataGrid eingefügt:

<UserControl....>
    <Grid>
        <ViewBase name="vBase">
            <DataGrid name="dGrid" />
        </ViewBase>
    </Grid>
</UserControl>

Mir ist auch nicht klar, dass Sie ViewBase benötigen, um direkt von UserControl zu erben. Wenn Ihre Steuerelemente nur bestimmte Eigenschaften und Methoden haben sollen, erstellen Sie einfach eine BaseControl-Klasse (die nur von einem Objekt erbt) und zukünftige Steuerelemente von dieser Klasse. Vielleicht suchen Sie eine abstrakte Basisklasse oder Schnittstelle.

Für MVVM-WPF-Projekte habe ich normalerweise ein BaseViewModel, das INotifyPropertyChanged für mich implementiert, damit ich nicht überall denselben Code ausführen muss.

Viel Glück, ich weiß, dass dieses Problem eine große Herausforderung war. Die Ausnahme-Nachricht und Google sind am wenigsten hilfreich!

11

Frustrierend hatte ich genau diesen Fehler und habe ewig versucht, die Ursache herauszufinden. Für mich funktionierte es einmal, aber dann nahm ich einige geringfügige Änderungen an der XAML des abgeleiteten Steuerelements vor, und der Compiler begann mit der Fehlermeldung ... _ Visual Studio heruntergefahren und erneut geöffnet, neu kompiliert, Problem ging magisch weg! (Dies ist VS2012 Pro) Nur hinzugefügt, falls sich jemand beim Lesen in Kreisen bewegt, um ein nicht existierendes Problem mit seinem Code zu finden. Vielleicht lohnt es sich, zuerst die "IT Crowd-Lösung" auszuprobieren.

56
HughHughTeotl

Der Grund für diesen Fehler ist, dass die Methode InitializeComponent (in VS 2010) immer in der Assembly der abgeleiteten Klasse sucht.

Hier ist InitializeComponent:

/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = new System.Uri("/WpfApplication1;component/mainwindow.xaml", System.UriKind.Relative);

    #line 1 "..\..\..\MainWindow.xaml"
    System.Windows.Application.LoadComponent(this, resourceLocater);

    #line default
    #line hidden
}

Die Zeile, in der Ihre XAML-Ressource gesucht wird, lautet System.Windows.Application.LoadComponent (this resourceLocator). Und das schlägt höchstwahrscheinlich fehl, weil das Äquivalent von "this.GetType (). Assembly" verwendet wird, um zu bestimmen, welche Assembly nach der durch den relativen Uri identifizierten Ressource suchen soll. 'This.GetType ()' ruft den abgeleiteten Typ des Objekts ab, nicht den Typ der Klasse, in der der Code implementiert ist.

PS. Ist das ein Fehler? Ich weiß es nicht...

19

Das hat mir drei Tage lang Kopfschmerzen bereitet! Ich habe ein XAML UserControl in einer Klassenbibliothek und eine Klasse (nur C #), die vom UserControl in meinem EXE-Projekt abgeleitet ist. Im Xaml-Designer meiner MainWindow.xaml und beim Starten der Anwendung habe ich die Komponente "Fehler" erhalten hat keine von der uri identifizierte Ressource ". Die Antwort von" Juan Carlos Girón "führte mich schließlich zur Lösung:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Reflection;
using System.IO.Packaging;
using System.Windows.Markup;

namespace ClassLibrary1
{
    static class Extension
    {
        public static void LoadViewFromUri(this UserControl userControl, string baseUri)
        {
            try
            {
                var resourceLocater = new Uri(baseUri, UriKind.Relative);
                var exprCa = (PackagePart)typeof(Application).GetMethod("GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { resourceLocater });
                var stream = exprCa.GetStream();
                var uri = new Uri((Uri)typeof(BaseUriHelper).GetProperty("PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null), resourceLocater);
                var parserContext = new ParserContext
                {
                    BaseUri = uri
                };
                typeof(XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { stream, parserContext, userControl, true });
            }
            catch (Exception)
            {
                //log
            }
        }
    }
}

und rief das aus der .cs-Datei von UserControl auf:

namespace ClassLibrary1
{
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            //InitializeComponent();
            this.LoadViewFromUri("/ClassLibrary1;component/myusercontrol.xaml");
        }
    }
}

Nochmals vielen Dank an "Juan Carlos Girón"!

18
PainElemental

Sie können diesen Ansatz ausprobieren

Ich habe meine eigene InitializeComponent() erstellt und auf diese Weise angerufen

this.LoadViewFromUri("/NameOfProject;component/mainwindow.xaml");


public static void LoadViewFromUri(this Window window, string baseUri)
    {
        try
        {
            var resourceLocater = new Uri(baseUri, UriKind.Relative);
            var exprCa = (PackagePart)typeof(Application).GetMethod("GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { resourceLocater });
            var stream = exprCa.GetStream();
            var uri = new Uri((Uri)typeof(BaseUriHelper).GetProperty("PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null), resourceLocater);
            var parserContext = new ParserContext
            {
                BaseUri = uri
            };
            typeof(XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { stream, parserContext, window, true });

        }
        catch (Exception)
        {
            //log
        }
    }
9

Selbes Problem hier.

Kurze Version:

Copy Local muss auf False gesetzt sein!

Lange Version:

Wir haben eine WPF-Lösung (MVVM, 20 Projekte) entwickelt und ein Plug-In-System implementiert. Unser/bin/Debug-Verzeichnis enthält die ausführbare Datei, einige DLL-Dateien und ein Plugin-Verzeichnis, das die Plugins enthält ..__ Es gibt ein Projekt "DialogLib" (Klassenbibliothek, Art des Dialogs), das ein Fenster (die Ansicht) definiert ViewModel, Model und einige Schnittstellen. Eines der Plugins verwendete eine der Schnittstellen von DialogLib. Das Fenster selbst wird von der Hauptanwendung geöffnet.

Um die Schnittstelle der Bibliothek 'DialogLib' im Plugin zu verwenden, mussten wir den Projektverweisen des Plugins eine Projektreferenz von DialogLib hinzufügen. Beim Start der Anwendung wurden die Plugins geladen. Wenn der Benutzer dann einen Menüpunkt auswählt, sollte sich das Fenster öffnen. Zu diesem Zeitpunkt trat der Fehler "... Komponente hat keine durch die URI identifizierte Ressource ..." auf, als der dahinterliegende Windows-Code versuchte, seine InitializeComponent () auszuführen.

Wo ist das Problem?

Das Problem ist, dass VS die DialogLib.dll beim Erstellen der Lösung korrekt erstellt und nach/bin/Debug/kopiert hat. Dies liegt daran, dass die Hauptanwendungsdatei das Fenster öffnen möchte. DialogLib.dll wurde jedoch auch nach/bin/Debug/plugins kopiert, weil eines der Plugins darauf verwies, um eine der in DialogLib.dll definierten Schnittstellen zu verwenden. Na und?

Wenn das Plugin zur Laufzeit geladen wird, verwendet es die in /bin/Debug/plugins/DialogLib.dll definierte Schnittstelle. Die Hauptanwendungsdatei versucht, das in /bin/Debug/DialogLib.dll definierte Fenster zu öffnen. Obwohl die Dateien identisch sind, gerät VS in Schwierigkeiten. Durch Festlegen des Werts von Copy Local der DialogLib-Verweiseigenschaften der Plugins-Referenzen wird das Kopieren von DialogLib.dll nach/bin/Debug/plugins vermieden und das Problem somit gelöst.

Wir hatten ein ähnliches Problem (aber einen anderen Fehler) in einem anderen Projekt, in dem wir einen Typ TypeA verwenden wollten, der in einer DLL-Datei, in einem Plug-In und in der Hauptanwendung definiert war. Copy Local wurde auf true gesetzt, wodurch eine Kopie der DLL-Datei in ../bin/Debug/plugins und in . ./bin/Debug/. Es stellte sich heraus, dass TypeA in der Hauptanwendungsdatei und TypeA im Plugin, obwohl es sich um dieselbe DLL-Datei handelte, als unterschiedliche Typen behandelt wurden, die nicht als solche gelten konnten ausgetauscht. 

7
ooorndtski

Ich habe das durch Platzieren gelöst 

myusercontrol = Activator.CreateInstance<myusercontrol>(); 

im Konstruktor des Fensters, das die Benutzerkontrolle vor der InitializeComponent();-Zeile enthält

6
Darren
  • obj Ordner löschen
  • bin Ordner löschen
  • Lösung neu erstellen

Arbeitete für mich!

Wenn Sie Assemblys mit Assembly.LoadFile laden, überprüfen Sie AppDomain.CurrentDomain.GetAssemblies() in der aktuellen AppDomain nach doppelten Assemblys. Da im automatisch generierten Code von WPF UserControl die Komponente mit ihrem relativen URI geladen wird. Und da es in der aktuellen AppDomain doppelte Assemblys gibt, weiß die Anwendung nicht, welche verwendet werden soll.

6
VahidN

Bei der Verwendung von Visual Studio 2013 wurde der gleiche Fehler angezeigt.

Die Komponente verfügt nicht über eine durch den URI identifizierte Ressource

Versucht:
Lösung reinigen und neu aufbauen - hat nicht funktioniert.
Schließen und Öffnen von Visual Studio - hat nicht funktioniert.

Lösung:
Ging in das bin-Verzeichnis des Projekts und löschte alle Dateien.
Lief das Projekt erneut und funktionierte gut.

Öffnen Sie die Package Manager Console , die sich im Stammverzeichnis Ihrer Lösung öffnet, und führen Sie den folgenden Powershell-Befehl aus:

Get-ChildItem -inc bin,obj -recurse | Remove-Item -recurse -force -EA SilentlyContinue
5
Ralph Willgoss

Ich war glücklich, als ich dasselbe Projekt in zwei Lösungen geöffnet hatte. Das Ändern des Basissteuerelements in einem Projekt verursacht das Problem in dem anderen Projekt. Wenn das Schließen und Öffnen nicht funktioniert, löschen Sie alle Ordner unter "C:\Benutzer ...\AppData\Local\Microsoft\VisualStudio\12.0\Designer\ShadowCache".

1
AMissico

@Willem, das scheint mir vollkommen in Ordnung zu sein. Tatsächlich habe ich es versucht und es hat in meinem Fall funktioniert. Ich habe ListBox anstelle von DataGrid verwendet (aber das sollte keine Rolle spielen).

Alle meine Namespaces befanden sich in einer Assembly. Also habe ich einen gemeinsamen übergeordneten Namespace für alle verwendet, z. 

MyWpfApplication.ControlsMyWpfApplciation.GridViewMyWpfApplciation.ViewBase

Alle diese Variablen Controls, GridView, ViewBase stehen im Konflikt mit vorhandenen System- oder System.Windows.Controls-basierten Namespaces und Klassendeklarationen. Also habe ich sichergestellt, dass ich in meinem Projekt den richtigen Code MyWpfApplication.* genannt habe.

1
WPF-it

Dies kann auch passieren, wenn Schließen und erneutes Öffnen eines Fensters. Es kann also auch nichts mit Paketen und/oder DLLs zu tun haben.
Ich löste das Problem dank der von PainElemental veröffentlichten Lösung, die IMHO unterbewertet ist:

namespace MyNamespace
{
  public partial class MyDialog : Window
  {
    public MyDialog(ExcelReference sheetReference)
      {
        this.LoadViewFromUri("/MyApp;component/mynamespace/mydialog.xaml");
      }
  }
}

LoadViewFromUri ist als Erweiterung implementiert, wie PainElemental schrieb. Das Verrückteste ist, dass ich auch andere Fenster in das gleiche Projekt geschrieben habe, ohne dass ein Problem auftritt.
Vielen Dank, PainElemental, Sie haben meinen langwierigen Schmerz beendet!

1
Mauro

Ich habe diese Fehlermeldung erhalten, nachdem ich eine XAML-Datei umbenannt habe. Durch Umkehren der Umbenennung wurde das Problem behoben. 

Darüber hinaus fand ich heraus, dass ein Verweis auf den XAML-Dateinamen in App.xaml nicht aktualisiert wurde (StartupUri), aber das Umbenennen in den aktuellen Namen löste das Problem nicht (möglicherweise jedoch für Sie). Grundsätzlich kann ich die XAML-Datei nicht umbenennen. 

Fyi, für mich war SplitComboBox die Komponente, die sich im Fehler "beschwert".

1
JBSnorro

Ich hatte versehentlich gelöscht ein Benutzersteuerelement über eine umbenennen / Kopie - Aktion. Als ich die Projektdatei und die XAML-Datei und .cs aus der Versionskontrolle wiederherstellte, trat dieser Fehler im Designstudio für dieses Steuerelement auf, das irrtümlicherweise gelöscht oder umbenannt wurde. 

Daraufhin wurde eine Art Cache für die betreffende Datei vorgeschlagen ... Schließen Sie also Visual Studio, löschen Sie das Verzeichnis bin und erstellen Sie einen Neustart.

0
ΩmegaMan

Schneller als das Schließen von Visual Studio ist das Beenden von XDescProc.exe in Ihrem Task-Manager. 

XDescProc ist der Designer. Sobald der Vorgang abgeschlossen ist, wird in Visual Studio ein Link zum erneuten Entwerfen des Designers angezeigt. Klicken Sie darauf und XDes werden erneut gestartet und der Fehler "Keine Ressource" sollte verschwunden sein.

Hier sehen Sie den Link Visual Studio, nachdem Sie den Designer-Prozess beendet haben:

 enter image description here

0
Bill Tarbell

Followed PainElementals Lösung (um zu verdeutlichen, dass die ClassLibrary1 für mich der DLL-Name ohne die Erweiterung .dll war), ist hier mein Szenario für den Fall, dass es jemandem hilft, seine spezifischen Fehlermeldungen mit dem Problem zu verknüpfen:

Ich benutze DLLs, um UserControls in ein Hauptprogramm als eigene Popup-Fenster zu laden und auszuführen. Die Lösung von PainElemental funktionierte meistens, aber eine der 3 Klassen in meiner "popup .dll" konnte nicht richtig geladen werden. Ich würde eine Ausnahme mit zwei inneren Ausnahmen erhalten, wie:

mscorlib InvokeMethod ...;
WpfXamlLoader.Load ... Geben Sie einen Wert für ... StaticResourceExtension ...;
ResolveBamlType .... Methode oder Vorgang ist nicht implementiert. 

In meinem Fall habe ich bestätigt, dass der neue URI geladen und getestet werden würde. Wenn ich jedoch versuchte, ihn in meiner Live-Umgebung auszuführen, wurde er in LoadViewFromUri () angezeigt.

Während ich weiter testete, beschränkte ich mich auf das Problem, dass ich keine separate "library .dll" -Datei laden konnte, die ich verwendete und einen Konverter enthielt, den ich in der .xaml-Datei der fehlgeschlagenen Klasse verwendete, sowie weitere Untersuchungen Das Problem dabei war, dass die Live-Umgebung eine andere "Library-DLL" -Version als in meiner Testumgebung verwendete, obwohl die Ausnahmemeldung aus meiner "Popup-DLL" dies nicht erwähnte.

Als Referenz verwende ich Copy Local = True und das gab mir keine Probleme. Um diese Art von Problemen bestmöglich zu debuggen, ist es hilfreich zu wissen, an welchen Speicherorten DLL-Dateien von der EXE-Datei gesucht werden. Soweit ich es verstehe, werden die DLLs bei der Ausführung von Projekten in VS in Copy Local = True in den gleichen Ordner wie die EXE-Datei kopiert, wenn sie "Built" ist. Wenn die EXE-Datei als Standardpfad ausgeführt wird, sucht sie nach .DLLS-Dateien im selben Ordner wie die EXE-Datei. Zusätzliche Speicherorte, nach denen die EXE-Datei nach DLLs suchen kann, können in der Datei .exe.config im Prüfelement festgelegt werden. Im folgenden Beispiel kann auch in einem Verzeichnis 'MyDLLs' und 'MyDLLs\Core' relativ zum Speicherort der .exe-Datei gesucht werden. Beachten Sie, dass natürlich keine Unterordner durchsucht werden. Sie müssen diese explizit angeben. Ich glaube, es durchsucht auch die GAC, aber ich habe derzeit wenig Wissen über GAC.

<configuration>
 ... 

   <runtime>  
      <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
         <probing privatePath="MyDLLs;MyDLLs\Core;"/>
      </assemblyBinding>
   </runtime>  
</configuration>
0
DeltaPng

Ich bin einfach auch auf dieses Problem gestoßen, ohne Probleme mit der Vererbung. Ich habe gerade auf ein DLL verwiesen, das ein Dialogfeld enthielt, und versuchte, dieses Dialogfeld zu erstellen und anzuzeigen. Ich habe Assembly Resolver, der Assemblys aus einem bestimmten Ordner lädt, und es stellt sich heraus, dass ich den Verweis in VS hinzugefügt und die Funktion "Lokal kopieren" nicht deaktiviert habe. Um es kurz zu machen: Mein Prozess hatte zwei Versionen derselben DLL geladen. Dies scheint WPF (oder die Laufzeit) zu verwirren. Nachdem ich die lokale Kopie gelöscht und die zusätzlichen DLL -Kopien gelöscht hatte, funktionierte es wieder einwandfrei.

0
Clutchplate