none
WPF Designer zeigt Fehlermeldung bei Datenbindung an Objekt aus Datenbank RRS feed

  • Frage

  • Hallo,

    ich habe eine Anwendung die ein POCO-Objekt über das EF aus der Datenbank mit Daten füllt. An dieses Objekt (genauer eine Objektliste) binde ich nun meine Steuerelemente (TextBlock) über WPF-Datenbindung. Wenn ich das Programm ausführe funktioniert auch alles Prima, und ich kann mir die Daten aus der Datenbank anschauen.

    Nur der WPF-Designer zeigt mir eine Fehlermeldung: "Problem beim Laden...". Unten in der Fehlerliste steht: "Fehler    2    Die angegebene benannte Verbindung wurde entweder nicht in der Konfiguration gefunden, ist nicht für die Verwendung mit dem EntityClient-Anbieter gedacht oder ist ungültig.    ..."

    Ich kann ja verstehen wenn der WPF-Designer keine Lust hat, sich zur Datenbank zu verbinden nur um das GUI Design anzuzeigen aber kann er dann nicht wenigstens leere Elemente anzeigen? Gibt es hier einen funktionierenden Workaround damit ich den Designer weiterhin nutzen kann?

    Mein Projekt sieht etwa so aus:

    Meine Liste von POCO-Objekten:

      public class BenutzerListe
      {
        private List<Benutzer> _BenutzerListe = null;
    
        public BenutzerListe()
        {
          InitListe();
        }
    
        public void InitListe()
        {
          MyEntities ctx = new MyEntities();
          _BenutzerListe = (from c in ctx.Benutzer
                   select new Benutzer()
                   {
                     BenutzerKonto = c.BenutzerKonto,
                     BenutzerName = c.BenutzerName,
                     // ...
                   }).ToList();
        }
    
        public List<Benutzer> GetListe()
        {
          return _BenutzerListe;
        }
      }
    

    und mein XAML:

      <StackPanel>
        <StackPanel.Resources>
          <!-- die folgende Zeile wird als Fehler markiert: -->
          <ObjectDataProvider x:Key="benutzer" ObjectType="{x:Type svc:BenutzerListe}" MethodName="GetListe" ></ObjectDataProvider>
          <DataTemplate x:Key="benutzerLayout" DataType="Benutzer">
            <!-- Datenformatierung (weggelassen) -->
          </DataTemplate>
          <CollectionViewSource x:Key="benutzerView" Source="{Binding Source={StaticResource benutzer}}">
            <!-- Sortierung (weggelassen) -->
          </CollectionViewSource>
        </StackPanel.Resources>
        <TextBlock></TextBlock>
        <ListBox x:Name="lbBenutzer" ItemsSource="{Binding Source={StaticResource benutzerView}}" ItemTemplate="{DynamicResource benutzerLayout}" MouseDoubleClick="Window_MouseDoubleClick"/>
    
      </StackPanel>
    

    Liebe Grüße,

    glibber

    Freitag, 23. April 2010 09:16

Antworten

  • Wenn der Designer eine Instanz deiner Klasse BenutzerListe aufruft, steht der ConnectionString in der config noch nicht zur Verfügung und der ObjectContext kann das Connection-Objekt nicht erstellen. Als einfache umgehungslösung steht da ein try/catch in der Datenklasse zur Verfügung, z.B. so:

    XAML-Demo:

    <Window x:Class="MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="MainWindow" Height="350" Width="525"
        xmlns:my="clr-namespace:WpfApplication1">
     <Window.Resources>
      <ObjectDataProvider x:Key="benutzer" ObjectType="{x:Type my:ViewModel}" MethodName="GetListe" />
     </Window.Resources>
     <StackPanel DataContext="{Binding Source={StaticResource benutzer}}">
      <ListView ItemsSource="{Binding}" Name="Anzeige">
       <ListView.View>
        <GridView>
         <GridViewColumn Header="Datum" Width="70" DisplayMemberBinding="{Binding Datum}" />
         <GridViewColumn Header="Wert" Width="50" DisplayMemberBinding="{Binding Wert}" />
         <GridViewColumn Header="Bemerkungen" DisplayMemberBinding="{Binding Bemerkungen}" />
        </GridView>
       </ListView.View>
      </ListView>
     </StackPanel>
    </Window>

    Der Code der Datenklasse (ModelView) dazu in einer überschaubaren Programmiersprache :-):

    Imports System.Collections.ObjectModel
    Imports System.ComponentModel
    
    Public Class ViewModel
    
     ''' <summary>
     ''' Eigenschaft mit der Liste mit Datenobjekten (unsortiert)
     ''' </summary>
     ''' <value></value>
     ''' <returns></returns>
     ''' <remarks></remarks>
     Public Property Liste As List(Of Datenobjekt)
    
     Public Function GetListe() As List(Of Datenobjekt)
      Return Liste
     End Function
    
     ''' <summary>
     ''' Im Konstruktor Demo-Daten erzeugen
     ''' </summary>
     ''' <remarks></remarks>
     Public Sub New()
      Try
       Dim ctx As New Database1Entities
       Liste = (From el In ctx.Tab1 _
           Select New Datenobjekt With {.Bemerkungen = el.Bemerkungen, _
                          .Datum = el.Datum, _
                          .Wert = el.Wert}).ToList
      Catch ex As Exception
      End Try
     End Sub
    End Class
    
    ''' <summary>
    ''' Datenobjekt-Klasse
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Datenobjekt
     Property Datum As Date
     Property Wert As Integer
     Property Bemerkungen As String
    End Class
    --
    Peter
    • Als Antwort vorgeschlagen Peter Fleischer Samstag, 24. April 2010 09:27
    • Als Antwort markiert glibber Dienstag, 27. April 2010 15:18
    Samstag, 24. April 2010 09:27

Alle Antworten

  • Wenn der Designer eine Instanz deiner Klasse BenutzerListe aufruft, steht der ConnectionString in der config noch nicht zur Verfügung und der ObjectContext kann das Connection-Objekt nicht erstellen. Als einfache umgehungslösung steht da ein try/catch in der Datenklasse zur Verfügung, z.B. so:

    XAML-Demo:

    <Window x:Class="MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="MainWindow" Height="350" Width="525"
        xmlns:my="clr-namespace:WpfApplication1">
     <Window.Resources>
      <ObjectDataProvider x:Key="benutzer" ObjectType="{x:Type my:ViewModel}" MethodName="GetListe" />
     </Window.Resources>
     <StackPanel DataContext="{Binding Source={StaticResource benutzer}}">
      <ListView ItemsSource="{Binding}" Name="Anzeige">
       <ListView.View>
        <GridView>
         <GridViewColumn Header="Datum" Width="70" DisplayMemberBinding="{Binding Datum}" />
         <GridViewColumn Header="Wert" Width="50" DisplayMemberBinding="{Binding Wert}" />
         <GridViewColumn Header="Bemerkungen" DisplayMemberBinding="{Binding Bemerkungen}" />
        </GridView>
       </ListView.View>
      </ListView>
     </StackPanel>
    </Window>

    Der Code der Datenklasse (ModelView) dazu in einer überschaubaren Programmiersprache :-):

    Imports System.Collections.ObjectModel
    Imports System.ComponentModel
    
    Public Class ViewModel
    
     ''' <summary>
     ''' Eigenschaft mit der Liste mit Datenobjekten (unsortiert)
     ''' </summary>
     ''' <value></value>
     ''' <returns></returns>
     ''' <remarks></remarks>
     Public Property Liste As List(Of Datenobjekt)
    
     Public Function GetListe() As List(Of Datenobjekt)
      Return Liste
     End Function
    
     ''' <summary>
     ''' Im Konstruktor Demo-Daten erzeugen
     ''' </summary>
     ''' <remarks></remarks>
     Public Sub New()
      Try
       Dim ctx As New Database1Entities
       Liste = (From el In ctx.Tab1 _
           Select New Datenobjekt With {.Bemerkungen = el.Bemerkungen, _
                          .Datum = el.Datum, _
                          .Wert = el.Wert}).ToList
      Catch ex As Exception
      End Try
     End Sub
    End Class
    
    ''' <summary>
    ''' Datenobjekt-Klasse
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Datenobjekt
     Property Datum As Date
     Property Wert As Integer
     Property Bemerkungen As String
    End Class
    --
    Peter
    • Als Antwort vorgeschlagen Peter Fleischer Samstag, 24. April 2010 09:27
    • Als Antwort markiert glibber Dienstag, 27. April 2010 15:18
    Samstag, 24. April 2010 09:27
  • Hallo Peter,

     

    vielen Dank für Deine Antwort.

    Leider ändert auch der try-catch-Block nichts an der Situation. Deinen Code habe ich prinzipiell übernommen. Es sieht - in einer für mich persönlich und ganz subjektiv empfunden ebenfalls überschaubaren Programmiersprache ;-) - folgendermaßen aus:

     

     

        private MyEntities _ctx = null;
    
        private List<IBenutzer> _BenutzerListe = null;
        private IQueryable<TestBewohner> _TestBewohnerListe = null;
    
        public BenutzerRepository()
        {
          _ctx = new MyEntities();
        }
    
        public List<IBenutzer> GetAll()
        {
          try
          {
            if (_TestBewohnerListe == null || _TestBewohnerListe.Count() == 0)
            {
              _TestBewohnerListe = (from c in _ctx.TestBewohner select c);
            }
            _BenutzerListe = new List<IBenutzer>();
            foreach (TestBewohner tb in _TestBewohnerListe)
            {
              IBenutzer b = new Benutzer()
              {
                BenutzerKonto = tb.BenutzerKonto,
                BenutzerName = tb.BenutzerName,
                // ...
     } as IBenutzer; _BenutzerListe.Add(b); } return _BenutzerListe; } catch (Exception ex) { return null; } }

     

    Ich habe auch probiert im catch-Statement dummy Daten zu erzeugen:

          catch (Exception ex)
          {
            IBenutzer b = new Benutzer()
                      {
                        BenutzerKonto = "BenutzerKonto",
                        BenutzerName = "BenutzerName",
                        // ...
                      } as IBenutzer;
            return new List<IBenutzer>() { b };
          }
    

    Ich bekomme immer die gleiche Fehlermeldumg bei der Anzeige des Wpf-Designers: "Die angegebene benannte Verbindung wurde entweder nicht in der Konfiguration gefunden, ist nicht für die Verwendung mit dem EntityClient-Anbieter gedacht oder ist ungültig".

    Laufen tut das Programm aber erwartungsgemäß - es geht nur um die grafische Anzeige der Xaml-Datei.

     

    Liebe Grüße,

    glibber

     

    Montag, 26. April 2010 17:12
  •  
    Deinen Code habe ich prinzipiell übernommen

    Hast du leider nicht, da du die Instanzierung des Connection-Objektes nicht in try/catch eingebettet hast. C# scheint für dich wohl doch keine so überschaubaren Programmiersprache zu sein. Versuche es mal mit der Beginner-Sprache BASIC :-)

    --
    Peter

    Montag, 26. April 2010 18:08
  •  

    Stöhn - ja natürlich, Du hast Recht.

    Ich muss das Erstellen des Kontextes in einem try-catch Block Kapseln.

    Jetzt funktioniert es.

     

     - Kaum macht man's richtig schon geht's -

     

    Danke für die Hilfe.

      > Versuche es mal mit der Beginner-Sprache BASIC

    Das lass' ich mir mal durch den Kopf gehen ;-)

     

    Liebe Grüße,

    glibber

     

    Dienstag, 27. April 2010 15:18