Laden...

InvalidOperationException im Designer-Fenster sofort beim Öffnen einer .xaml-Datei

Erstellt von bb1898 vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.229 Views
B
bb1898 Themenstarter:in
110 Beiträge seit 2008
vor 8 Jahren
InvalidOperationException im Designer-Fenster sofort beim Öffnen einer .xaml-Datei

In einer kleinen Testanwendung mit WPF und Entity Framework bekomme ich diesen Fehler, sobald ich die .xaml-Datei für das Hauptfenster öffne:

Fehlermeldung:
InvalidOperationException: In der Anwendungskonfigurationsdatei wurde keine Verbindungszeichenfolge mit dem Namen 'KrimiCn' gefunden.
StackTrace
bei System.Data.Entity.Internal.LazyInternalConnection.get_ConnectionHasModel()
bei System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
bei System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
bei System.Data.Entity.Internal.Linq.InternalSet1.Initialize() bei System.Data.Entity.Internal.Linq.InternalSet1.GetEnumerator()
bei System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.IEnumerable.GetEnumerator()
bei System.Data.Entity.QueryableExtensions.Load(IQueryable source)
bei OkCancel_Versuche.KrimiBAPI..ctor() in d:\home\Sibylle\Dokumente\Visual Studio 2012\Projects\OkCancel_Versuche\OkCancel_Versuche\ViewModel\KrimiBAPI.cs:Zeile 54.
bei OkCancel_Versuche.App..cctor() in d:\home\Sibylle\Dokumente\Visual Studio 2012\Projects\OkCancel_Versuche\OkCancel_Versuche\App.xaml.cs:Zeile 16.
InnerException: Keine

Das steht so im WPF-Designer-Fenster für MainWindow.xaml. Der xaml-Text sieht aus, wie er soll.

Trotzdem startet das Programm ganz normal und tut auch das Wenige, was es bisher kann und soll. Das heißt insbesondere, dass es Daten aus der Datenbank anzeigt.

Das Fenster enthält u.a. eine UserControl-Komponente. Zu den beiden gehören verschiedene ViewModels, die aber beide Referenzen auf die gleiche Instanz einer Klasse für die Geschäftslogik enthalten. Liegt hier das Problem?

Natürlich habe ich mir meine app.config gründlich angesehen, selbstverständlich steht die Verbindungszeichenfolge richtig drin und hat den Namen, unter dem das Programm auf sie zugreift.

Das sieht so aus:

public class KrimiDB : DbContext
{
	static KrimiDB()
	{
		Database.SetInitializer<KrimiDB>(null);
	}

	public KrimiDB()
		: base("name=KrimiCn")
	{ }
        
    ....
}

und in der app.config:

 <connectionStrings>
    <clear/>
    <add name="KrimiCn" providerName="System.Data.SqlClient"
         connectionString="data source=(localDb)\v11.0;initial catalog=Krimi_Versuch_1.KrimiDB;integrated security=True;" />
  </connectionStrings>

Es gibt auch nur diese eine app.config, die Projektmappe enthält nur ein Projekt, keine separaten Klassenbibliotheken. Die Datenbank ist in einem früheren Projekt erzeugt worden, das aktuelle Projekt heißt nicht "Krimi_Versuch_1".

Weder die Suche in diesem Forum noch die Suchmaschine meines Vertrauens haben weitergeholfen.

1.040 Beiträge seit 2007
vor 8 Jahren

Was steht im KrimiBAPI Konstruktor?

74 Beiträge seit 2014
vor 8 Jahren

Wahrscheinlich versucht VS diese Einstellungen aus seiner eigenen .config-Datei zu lesen. Besser wäre es aber den DB-Zugriff zu abstrahieren - Stichwort Repository.

5.299 Beiträge seit 2008
vor 8 Jahren

mir sieht das so aus, als ob man diesem KrimiDb-Konstruktor beibringen muss, zur Designzeit die Füsse stillzuhalten, und nicht den Initializer abzufahren.

ich hab da nur eine Schaurigkeit für, noch dazu in VB:



      Private Shared _IsInDesignMode As Boolean? = Nothing
      Private Shared _HostProcesses As New List(Of String)({"XDesProc", "denev"})
      Public Shared Function IsInDesignMode() As Boolean
         If Not _IsInDesignMode.HasValue Then
            _IsInDesignMode = _HostProcesses.Contains(Process.GetCurrentProcess().ProcessName)
         End If
         Return _IsInDesignMode.Value
      End Function

DAs ist ein bischen wie ein Cache, damit Process.GetCurrentProcess() möglichst selten aufgerufen wird.

Der frühe Apfel fängt den Wurm.

1.040 Beiträge seit 2007
vor 8 Jahren

In C# ist es mit

DesignerProperties.GetIsInDesignMode(this);

möglich.

Dies sollte dann im

KrimiBAPI-Konstruktor geprüft werden.

B
bb1898 Themenstarter:in
110 Beiträge seit 2008
vor 8 Jahren

Der Konstruktor von KrimiBAPI:

public KrimiBAPI()
{
	KDB = new KrimiDB();
	KDB.Autoren.Load();
	AlleAutoren = new AutorlisteVM(KDB.Autoren.Local.OrderBy(au => au.Name));
	AktuellerAutor = AlleAutoren.FirstOrDefault();
	AutorBuecher = new BuecherlisteVM();
	if (AktuellerAutor != null)
	{
		AutorBuecher.RefillVM(AktuellerAutor.Buecher.OrderBy(b => b.Titel));
	}
}

Was möglicherweise nicht gut ist, ist meine Konstruktion in App.xaml.cs:

public partial class App : Application
{
	private static KrimiBAPI _bapi = new KrimiBAPI();

	public static KrimiBAPI BAPI
	{ get { return _bapi; } }
}

Überall, wo nötig, wird App.BAPI benutzt. Ich habe das aus einem WPF-Lehrbuch und bin damit bisher noch nicht in offensichtliche Probleme gelaufen.

Ich habe Änderungen gemacht, die die Fehlermeldung beseitigt haben, blicke aber nicht wirklich durch, warum das so ist. Ursprünglich war ein ViewModel für Hauptfenster und UserControls zuständig, jetzt habe ich es aufgeteilt und das Hauptfenster weiß gar nichts mehr vom Datenbankzugriff (sein ViewModel ebensowenig). Warum ich dann allerdings den Fehler nicht beim Bearbeiten der UserControls im Designer bekomme, bleibt mir unklar.

Ich habe jetzt allerdings ein neues Problem: mein Hauptfenster enthält ein TabControl mit zwei TabItems. Jedes TabItem wird ausgefüllt von einem UserControl mit eigenem ViewModel, beide ViewModels benutzen die in App.xaml.cs erzeugte Instanz von KrimiBAPI, die ihrerseits eine KrimiDB-Instanz enthält (und das ist der DbContext-Abkömmling). Ein UserControl zeigt den Inhalt einer Tabelle als Liste an, im anderen soll der gewählte Eintrag aus dieser Liste im Detail besichtigt und bearbeitet werden.

Der Fehler dabei: zwar wird der erste ausgewählte Eintrag auf der Detailseite richtig angezeigt, wähle ich auf der Listenseite aber etwas anderes aus, bleibt auf der Detailseite stur der erste Eintrag stehen. Egal, ob zwischen den zwei Selektionen der Inhalt der Liste einmal ganz ausgewechselt wird (Bücher eines anderen Autors) oder nicht.

Es wäre aber wahrscheinlich besser, aus der genaueren Beschreibung dieses neuen Problems auch einen neuen Thread zu machen, oder doch nicht?

212 Beiträge seit 2008
vor 8 Jahren

Es wäre aber wahrscheinlich besser, aus der genaueren Beschreibung dieses neuen Problems auch einen neuen Thread zu machen, oder doch nicht?

Unbedingt 😉

Das mit dem Konstruktor handle ich immer so:


if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
  //do something.....
}

Es ist doch immer wieder interessant wieviele Möglichkeiten es gibt.

Gruß
Christoph