none
Will nur drei Spalten einer Tabelle in ein Datagrid schreiben RRS feed

  • Frage

  • Hallo,
    ich habe mir die beiden Microsoft Videotutorials

    "Wie kann ich mit WCF Data Services auf eine bestehende Datenbank zugreifen" und
    "Wie kann ich WCF Data Services in einer Silverlight-Anwendung benutzen" angesehen und nach gemacht.
    Hat super funktioniert. Konnte auf meine Datenbank und die darin enthaltene Tabelle "Gruppen" zugreifen.

    Es wurden alle Spalten der Tabelle "Gruppen" im silverlight Datagrid angezeigt. Nun wollte ich aber das nur bestimmte Spalten der Tabelle angezeigt werden.
    In SQL wäre das ein simples "select Spalte1, Spalte2 from Gruppen" Statemant. In Silverlight ist das leider nicht so einfach.
    Habe unter folgendem Link ein Beispiel gefunden wie man das in silverlight machen kann.

    http://msdn.microsoft.com/en-us/libr...8VS.95%29.aspx

    Habe das Beispiel auf meine Übung umgemünzt aber nicht mit dem Erfolg den ich mir erhofft habe.

    Hier nun mein Quellcode. Wenn ich den so laufen lasse werden alle Spalten der Tabelle "Gruppen" angezeigt.
    Wenn ich nun die Zeilen 1, 2 und 3 ausmarkiere und die ausmakierungen bei a, b und c weg nehme sollten eigentlich nur die
    drei Spalten "CustomerID, Ort und VName im Datagrid angezeigt werden. Wenn ich den Code starte erscheint das Datagrid mit den drei
    Spaltenüberschriften CustomerID, Ort und VName aber die Spalten bleiben leer (Keine Daten zu sehen).
    In der Zeile c ist zu sehen das ich nur die CustomerID den Ort und VName haben will. Fuktioniert aber irgendwie nicht.

    namespace Client
    {
      public partial class MainPage : UserControl
      {
      a //private DataServiceCollection<GruppenAddress> binding;
      1.  private DataServiceCollection<Gruppen> binding;
        CollectionViewSource cavs;
        nochmalEntities context;
     
        public MainPage()
        {
          InitializeComponent();
          this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
     
        //nochmalEntities ctx = new nochmalEntities(new Uri("/NochmalService.svc", UriKind.Relative));
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
       b  //binding = new DataServiceCollection<GruppenAddress>();
       2.  binding = new DataServiceCollection<Gruppen>();
          context = new nochmalEntities(new Uri("/NochmalService.svc", UriKind.Relative));
          binding.LoadCompleted += new System.EventHandler<LoadCompletedEventArgs>(binding_LoadCompleted);
       c  //var query = (from p in context.Gruppen select new GruppenAddress { CustomerID = p.CustomerID, Ort = p.Ort, VName = p.VName });
       3.  var query = (from p in context.Gruppen select p);
          binding.LoadAsync(query);
     
        }
     
        void binding_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
          if (e.Error == null)
          {
            if (binding.Continuation != null)
            {
              binding.LoadNextPartialSetAsync();
            }
            else
            {
              cavs = (CollectionViewSource)this.Resources["cavs"];
              cavs.Source = binding;
            }
     
          }
     
        }
      }
    


    So sieht meine GruppenAddress.cs aus.

     

    namespace Client
    {
      [DataServiceKey("CustomerID")]
      public partial class GruppenAddress
      {
        private string _customerID;
     
        private string _Ort;
        private string _VName;
     
     
        public string CustomerID
        {
          get
          {
            return this._customerID;
          }
     
          set
          {
            this._customerID = value;
          }
        }
     
        public string VName
        {
          get
          {
            return this._VName;
          }
          set
          {
            this._VName = value;
          }
        }
     
     
        public string Ort
        {
          get
          {
            return this._Ort;
          }
          set
          {
            this._Ort = value;
          }
        }
     
      }
     
      public class GruppenAddressNonEntity
      {
        private string _Ort;
        private string _VName;
     
     
        public string Ort
        {
          get
          {
            return this._Ort;
          }
          set
          {
            this._Ort = value;
          }
        }
        public string VName
        {
          get
          {
            return this._VName;
          }
          set
          {
            this._VName = value;
          }
        }
     
      }
     
    }
    

    Weis vielleicht jemand was ich falsch mache?

    Ich weis das es ein silverlight-Forum hier gibt aber da habe ich schon letzte Woche gepostet und immer noch keine Antwort bekommen.

    Weis vieleicht jemand eine andere Lösung für mein Problem. Ich muss das ja nicht so Lösen.

    Ich will doch nur anstat einem "select * from Tabelle" ein "select Spalte1, Spalte2, Spalte3 from Tabelle" ausführen.

    Bin für jeden Hinweis dankbar.

     

    silberlicht

     

    Sonntag, 5. September 2010 20:49

Antworten

  • Hallo,

    das tut mir leid, dass Du noch nicht weiter gekommen bist!
    Allerdings machen es einem die DataServices auch nicht immer leicht :-()
    So sind die Links die Dir Frank im Silverlight Forum gegeben hatte,
    wohl nur die halbe Wahrheit (wie die eine oder Ausnahme belegte).

    Da mir Dein Model nicht vorliegt, habe ich noch mal auf das Beispiel aus:
    Ein vorheriger LoadAsync-Vorgang wurde noch nicht ... zurückgegriffen.

    Ich habe dort die zweite Abfrage (productsHighPrice) durch folgendes ersetzt:

          var productsInfos = new DataServiceCollection<ProductInfo>(ctx);
          var productsInfosQuery = 
            from p in ctx.Product
            where p.ListPrice > 1000
            orderby p.ListPrice descending
            select new ProductInfo() 
            { 
              ProductID = p.ProductID, 
              ProductNumber = p.ProductNumber, 
              Name = p.Name
            };
          productsInfos.LoadCompleted += ((obj, args) => { this.HighPriceGrid.ItemsSource = productsInfos; });
          productsInfos.LoadAsync(productsInfosQuery);
    
    
    u nd dazu die ProductInfo-Klasse:

    using System;
    using System.Collections.ObjectModel;
    using System.Data.Services.Common;
    
    namespace Client
    {
      [DataServiceKey("ProductID")]
      public class ProductInfo : System.ComponentModel.INotifyPropertyChanged
      {
        public ProductInfo() { }
        public ProductInfo(int id, string number, string name)
        {
          this.ProductID = id;
          this.ProductNumber = number;
          this.Name = name;
        }
    
        public int ProductID { get; set; }
        public string ProductNumber { get; set; }
        public string Name { get; set; }
    
        // Nicht verwendet nur um DataServices glücklich zu machen
        event System.ComponentModel.PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        {
          add { ; }
          remove { ; }
        }
      }
    }
    
    
    Erforderlich ist neben dem DataServiceKey auch die Implementation der INotifyPropertyChanged Schnittstelle.
    Das gilt auch wenn man niemals beabsichtigt die Daten zu aktualisieren, wie ich für das Beispiel angenommen habe
    (und den Eventhandler totgelegt habe)

    Das Setzen der DataService.MergeOption auf NoTracking erwies sich gar als kontraproduktiv,
    da nur eine Zeile geliefert wurde (warum muß ich noch rausfinden).
    Positiv laut SQL Profiler ist: Es werden auch nur die Spalten abgefragt.

    Solltest Du Schwierigkeiten haben, es auf Dein Model anzuwenden,
    und könntest Du das Projekt bereitstellen, könnte ich es mir näher ansehen.

    Gruß Elmar

    Montag, 6. September 2010 17:05
    Beantworter
  • Hallo,

    wie schon eingangs angedeutet, stellen die DataServices präzise Anforderungen an die Klasse.

    Beim Übertragen meines Beispiels hast Du eine Kleinigkeit ausgelassen,

    nämlich die ProductInfo Klasse als public zu kennzeichnen, in meinen Beispiel steht:

     

     [DataServiceKey("ProductID")]
     public class ProductInfo : System.ComponentModel.INotifyPropertyChanged
     {
       // ...
     }
    
    Bei Dir steht:

     

     

      [DataServiceKey("ProductID")]
    
      class ProductInfo : System.ComponentModel.INotifyPropertyChanged
      {
      }
    
    Da kein Zugriffsmodifizier angegeben ist, wird die Klasse als internal gekennzeichnet,
    da es für Klassen die Standardeinstellung ist.
    Wohingegen die Data Services eine public Klasse sowie einen public Konstruktor benötigen -
    hier wegen des Zugriffs über Reflektion, die intern zur Erstellung verwendet wird..

     

    Das Resultat ist eine Ausnahme. Um sie selbst zu sehen, ändere Deinen Code für MainPage_Loaded wie folgt ab:

     

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          //var products = new DataServiceCollection<Product>(ctx);
          //products.LoadCompleted += ((o, args) => { grid1.ItemsSource = products; });
          //products.LoadAsync(from p in ctx.Product select p);
          var productsInfos = new DataServiceCollection<ProductInfo>(ctx);
          var productsInfosQuery =
           from p in ctx.Product
           where p.ListPrice > 1000
           orderby p.ListPrice descending
           select new ProductInfo()
           {
             ProductID = p.ProductID,
             ProductNumber = p.ProductNumber,
             Name = p.Name
           };
          productsInfos.LoadCompleted += ((source, eargs) =>
          {
            var list = source as DataServiceCollection<ProductInfo>;
            if (eargs.Error == null)
            {
              if (list.Continuation != null)
              {
                list.LoadNextPartialSetAsync();
              }
              else
              {
                this.grid1.ItemsSource = productsInfos;
              }
            }
            else
            {
              MessageBox.Show("Fehler beim Abruf:\r\n" + eargs.Error);
            }
          }); 
          productsInfos.LoadAsync(productsInfosQuery);
        }
    
    

     

    Falls Du Firefox verwendest, starte die Anwendungs als Out Of Browser Applikation
    (unter Projekt-Eigenschaften->Silverlight)

    Gruß Elmar
    Donnerstag, 9. September 2010 11:05
    Beantworter
  • Hallo Elmar,

        > public class ProductInfo

    das weiss er schon - hatte ich ihm schon vor ner halben Stunde gesagt - ist aber ok, wenn Du das wiederholst. Auch das mit dem Loaded-Event findest Du ja in meinem Beispiel und hatte ich ihm auch bereits gesagt. Aber doppelt hält ja hier auch besser.



    ciao Frank
    Donnerstag, 9. September 2010 11:10
  • Hallo S.,

    mach die Klasse ProductInfo public!

    Hättest Du gleich meinen Loaded-EventHandler aus meinem Beispiel genommen, hättest Du auch die entsprechende Meldung bekommen, die Dir den Weg gezeigt hätte ;-)


    ciao Frank

    Donnerstag, 9. September 2010 10:43

Alle Antworten

  • Hallo S.,

         > Wenn ich den so laufen lasse werden alle Spalten der Tabelle "Gruppen" angezeigt.

    Im XAML ist ja noch die Zahl der Columns des DataGrid vorgegeben.
    Durch AutoGenerateColumns="true" würde man die automatisch aus dem ItemsSource generieren lassen - wobei man dann noch Maßnahmen unternehmen muss.
    Ansonsten halt im XAML die Columns manuell oder über Code anpassen (->Columns.Remove...) - das geht immer. Also etwa in meinem Beispiel einfach mal City und Country in der MainPage.xaml wegnehmen. Bei mir funktioniert das.

    Allerdings .. will man das mit  [AutoGenerateColumns="true"] schaffen, muss man entweder einen eigenen Typ (nebst zusätzlicher Service-Query) dafür erstellen, oder mit ICustomTypeDescriptor den ursprünglichen quasi nachahmen, sodass quasi beliebig dynamische Szenarien denkbar sind. Das hatte ich Dir ja auch schon in dem vorherigen Thread gesagt. Aber es ist natürlich auch kein triviales Thema.


    ciao Frank

     

    Montag, 6. September 2010 06:28
  • Hallo,

    das tut mir leid, dass Du noch nicht weiter gekommen bist!
    Allerdings machen es einem die DataServices auch nicht immer leicht :-()
    So sind die Links die Dir Frank im Silverlight Forum gegeben hatte,
    wohl nur die halbe Wahrheit (wie die eine oder Ausnahme belegte).

    Da mir Dein Model nicht vorliegt, habe ich noch mal auf das Beispiel aus:
    Ein vorheriger LoadAsync-Vorgang wurde noch nicht ... zurückgegriffen.

    Ich habe dort die zweite Abfrage (productsHighPrice) durch folgendes ersetzt:

          var productsInfos = new DataServiceCollection<ProductInfo>(ctx);
          var productsInfosQuery = 
            from p in ctx.Product
            where p.ListPrice > 1000
            orderby p.ListPrice descending
            select new ProductInfo() 
            { 
              ProductID = p.ProductID, 
              ProductNumber = p.ProductNumber, 
              Name = p.Name
            };
          productsInfos.LoadCompleted += ((obj, args) => { this.HighPriceGrid.ItemsSource = productsInfos; });
          productsInfos.LoadAsync(productsInfosQuery);
    
    
    u nd dazu die ProductInfo-Klasse:

    using System;
    using System.Collections.ObjectModel;
    using System.Data.Services.Common;
    
    namespace Client
    {
      [DataServiceKey("ProductID")]
      public class ProductInfo : System.ComponentModel.INotifyPropertyChanged
      {
        public ProductInfo() { }
        public ProductInfo(int id, string number, string name)
        {
          this.ProductID = id;
          this.ProductNumber = number;
          this.Name = name;
        }
    
        public int ProductID { get; set; }
        public string ProductNumber { get; set; }
        public string Name { get; set; }
    
        // Nicht verwendet nur um DataServices glücklich zu machen
        event System.ComponentModel.PropertyChangedEventHandler System.ComponentModel.INotifyPropertyChanged.PropertyChanged
        {
          add { ; }
          remove { ; }
        }
      }
    }
    
    
    Erforderlich ist neben dem DataServiceKey auch die Implementation der INotifyPropertyChanged Schnittstelle.
    Das gilt auch wenn man niemals beabsichtigt die Daten zu aktualisieren, wie ich für das Beispiel angenommen habe
    (und den Eventhandler totgelegt habe)

    Das Setzen der DataService.MergeOption auf NoTracking erwies sich gar als kontraproduktiv,
    da nur eine Zeile geliefert wurde (warum muß ich noch rausfinden).
    Positiv laut SQL Profiler ist: Es werden auch nur die Spalten abgefragt.

    Solltest Du Schwierigkeiten haben, es auf Dein Model anzuwenden,
    und könntest Du das Projekt bereitstellen, könnte ich es mir näher ansehen.

    Gruß Elmar

    Montag, 6. September 2010 17:05
    Beantworter
  • Hallo Elmar,

    ich denke, dass Du da eine "mögliche" Umsetzung postest, aber diese ist IMHO von den dreien die ich genannt habe, die aufwändigste von den unflexibilen Lösungs-Varianten. Ich würde eher zu den Column-Änderungen über Code raten, oder bei ultra-flexiblen Lösungen über den ICustomTypeDescriptor gehen.


    ciao Frank

    Dienstag, 7. September 2010 05:37
  • Hallo Frank,

    es geht hier dabei darum, die übertragende Datenmenge zu reduzieren,
    was in Netzwerkszenarien den Unterschied ausmacht zu einer
    "angenehmen Benutzererfahrung", um den Microsoft Jargon zu bemühen.

    Das erreichst Du nicht durch Anpassungen der Anzeige, egal wie kreativ Du dort bist.
    Denn die DataServiceCollection ruft das ab, was man ihr angibt -
    von einer Datenbindung weiss sie naturgemäß gar nichts.

    Schon bei der obigen simplen AdventureWorks werden laut SSMS Client Statistiken
    vom SQL Server übertragen
    Im einen Falle:
      Vom Server empfangene Bytes    58674        58674.0000
    Im anderen Falle:
      Vom Server empfangene Bytes    715188       715188.0000

    (unter Auslassen der WHERE Klausel zur Vergleichbarkeit => 295 Zeilen)
    Dazu darfst Du noch den Netzwerk-Overhead hinzurechnen, was ich
    (hier lokal) wegen mangelnder Vergleichbarkeit unterlassen habe.
    Als kleiner Hinweis: TDS benötigt einmal 15, das andere mal 785 Pakete.

    Gruß Elmar

    Dienstag, 7. September 2010 08:12
    Beantworter
  • Hallo Elmar,

        - übertragende Datenmenge zu reduzieren

    "wenn" das das "Hauptziel" wäre ..., dann würde ich auch diesen Weg wählen, oder ICustomTypeDescriptor (je nach Flexibilitäts-Anforderungen). Das habe ich seiner Frage allerdings nicht entnehmen können.
    Zudem wird man in jeder professionellen App ein Paging durchführen, wodurch dieser Netz-Aufwand quasi vernachlässigbar klein ist!
    Ich sehe hier in der Frage eben mehrere Möglichkeiten, deren Wahl je nach Szenario abgewägt werden müssen.

    Das von mir erwähnte "Columns.Remove" ist hier zum Beispiel mit Abstand die einfachste Methode.
    Man wird nicht gern in Szenarien reine Spalten-Reduktions-Semantiken immer neue Typen dafür entwerfen wollen.


    ciao Frank
    Dienstag, 7. September 2010 08:23
  • Hallo Frank,

    die Datenmenge zu reduzieren ist immer das Ziel einer erfolgreichen (skalierbaren) Anwendung[1]

    Fragst Du Daten ab, die die Anwendung (zu dem Zeitpunkt) nicht benötigt, ist das ineffizient -
    (im professionellen Umfeld) ohne Wenn und ohne Aber.
    Ein Paging kann zur Unterstützung hinzukommen, was eine horizontale Projektion wäre,
    siehe auch Partionierung.

    Gruß Elmar

    [1] Für WCF DataService (aka OData) siehe
    http://meta.stackoverflow.com/questions/43991/implement-odata-api-for-stackoverflow
    und praktisch: http://odata.stackexchange.com/stackoverflow/queries
    (Begehrlich: Und was ist mit den Micorosoft Foren?)
    Dienstag, 7. September 2010 09:33
    Beantworter
  • Hallo Elmar,

    nein, die Datenmenge ist nur "ein" Sub-Ziel, das Ziel jeden professionellen App ist normal, die Anforderungen der App vorteilhaft in der Gesamtheit zu erfüllen. [Qualitätsmanagement – Wikipedia]
    Zusatzaufwand, der in Deinem Fall ggf. unnütz gross ist, sollte in einigen Szenarien eben nicht gewählt werden!

    Zudem wird man in jeder professionellen App ein Paging durchführen, wodurch dieser Netz-Aufwand quasi vernachlässigbar klein ist!

    Weiterhin gibt es gerade bei Silverlight eben Caching Strategien schon im Standard, sodass nochmals die Erstellung solcher unnützen Zusatz-Typen nicht angebracht sind. Wie gesagt - mal so mal so, das heisst nicht, dass Dein Vorschlag schlecht ist, ich würde ihn je nach Anforderung ggf. auch wählen. 

    Ich denke, der überwiegende Teil der Entwickler wird keine zusätzlichen Typen (Dein Vorschlag) benutzen, wenn der Performance-Zusatz marginal ist. Es ist nicht nur der initiale Code-Aufwand zu rechnen, sondern der Wartungs-Aufwand, der exponentiell in Deiner Lösung mit den Filtern wächst.
    Wenn man den Gesamt-Aufwand andenkt ist das ggf. keine empfehlenswerte Variante. 

    Beachte ggf. auch, dass Lösungen über ICustomTypeDescriptor ebenfalls die gleiche geringe Netzlast haben, als wenn man diese Typen explizit definiert. Zudem sind sie flexibler, aber im initialen (einmaligen) Aufwand größer.

    Aber dann sind wir hier halt anderer Meinung. 


    ciao Frank
    Dienstag, 7. September 2010 09:51
  •  

    Hallo Frank,

    "meine Lösung" ist nichts weiter als das Umsetzen der Dokumentation
    Abfrageprojektionen (WCF Data Services) (sollte Dir bekannt vorkommen)
    in eine funktionierende Lösung (=> beseitigen einiger Stolpersteine).

    "Cachen" kann man nichts, was nicht mindestens einmalig geladen wurde.
    Serverseitiges Cachen nützt auf dem Übertragungswege nichts.

    Die Projektion (horizontal wie vertikal aka Paging) ist nur eine der Möglichkeiten [1].
    Ebenso wie das verfügbar machen eines EF Models nur eine der Möglichkeiten ist[2]

    Daraus einen "Code-Aufwand" hochzurechnen geht am Thema vorbei -
    niemand würde sich real auf die Weise die Finger wundtippen.

    Der von Dir reklamierte "Zusatzaufwand" stellt gerade bei Silverlight den Unterschied dar
    (ebenso wie vor Jahren die Unterschiede sichtbar wurden, wenn man eine LAN vs Modem
    verglich, gilt das heute für Inhouse Gigabit Netzwerk vs. z. B. Windows Phone 7 via UTMS).

    Einem Entwickler sollten alle Möglichkeiten bekannt und vertraut sein,
    so dass er die im konkreten Szenario approbate auswählen kann -
    sich der Bequemlichkeit hinzugeben, ist IMO keine akzeptable Alternative.

    Gruß Elmar

    [1] Für den Bereich Reflektion würde ich auf Reflektionsanbieter (WCF Data Services) hinweisen
    (anstatt erst italienisch lernen zu müssen ;-)

    [2] Was ich praktisch kaum wählen würde bei größeren Datenvolumina,
    aber IMO ansonsten eines der besseren APIs der letzten Jahre.

    Dienstag, 7. September 2010 10:42
    Beantworter
  • Elmar,

    Da ich jetzt meine Argumte nicht widerlegt sehe, denke ich, kann man die bei Bedarf ja oben nachlesen, anstatt jetzt weiter diese zu wiederholen.
    Es gibt hier mehrere Lösungen. Ich würde den QM-mäßig besten für meine App wählen. Das ist sicher in vielen Fällen das Column.Remove. In einigen eigene zusätzliche Typen entwerfen (mit dem entsprechend hohen Aufwand). Oder auch noch mehr initialer Aufwand dafür mehr Flexibilität über den ICustomTypeDescriptor und gleiche Netzwerklast wie bei neuen eigenen Typen.
     

         > ich auf Reflektionsanbieter (WCF Data Services) hinweisen

    kannst Du machen, das auch nur als Hinweis, das ist nicht das gleiche, wie mein Artikel. Aber gut, wenn Du Dich in diese Richtung informierst. Mir schien, dass Du da nur ein Verfahren kanntest.


    ciao Frank
    Dienstag, 7. September 2010 11:33
  • Wow, Wow, Wow,

     

    so viele neue Informationen.

    Da muss ich mich erstmal durchkämpfen.

    Erstmal vielen Dank an alle. Sobald ich die Tipps ausprobiert habe melde ich mich wieder.

     

    silberlicht

    Dienstag, 7. September 2010 13:56
  • Hallo Elmar,

    habe das AdventureWorks noch mal komplett neu gemacht und dann Deine Änderungen durchgeführt.

    Im Datagrid werden die Spalten ProductID, ProductNumber und Name angezeigt aber die Spalten bleiben leer.

    Könnte durchdrehen.

    Ich würde Dir gerne mal meine Projektmappe bereitstellen aber wie?

    Die Projektmappe ist 9MB goss.

    Sehe hier keine möglichkeit Dateien hoch zu laden.

    Wenn du mir deine email-Adresse geben würdest so könnte ich dir das Projekt schicken.

     

    Wäre um jede Hilfe dankbar.

     

    silberlicht

    • Bearbeitet silberlicht Donnerstag, 9. September 2010 09:41
    Mittwoch, 8. September 2010 20:40
  • Hallo,

    Du kannst das Projekt zippen und auf SkyDrive abstellen,
    denn es mag den einen oder anderen mehr interessieren.

    Gruß Elmar

    Mittwoch, 8. September 2010 20:59
    Beantworter
  • Hallo Elmar,

    so habe die Projektmappe gezip und bei SkyDrive hochgeladen.

     

    Wie kommst du nun da dran? Wie findest Du das bei SkyDrive?

    Habe gerade bei SkyDrive gesehen das ich jemandem einen link senden kann.

     

    silberlicht

    Mittwoch, 8. September 2010 21:15
  • Hallo Elmar,

     

    am 6.9.10 hast Du geschrieben "Solltest Du Schwierigkeiten haben, es auf Dein Model anzuwenden,
    und könntest Du das Projekt bereitstellen, könnte ich es mir näher ansehen."

    Nun schreibst Du "denn es mag den einen oder anderen mehr interessieren."

    Willst Du es dir mal ansehen oder nicht?

     

    Muss jetzt schluss machen. Bis morgen.

     

    silberlicht

    Mittwoch, 8. September 2010 21:29
  • Hallo,

    wenn Du Dir Informationen anzeigen lässt, siehst Du dort u. a. die  Web-Adresse.
    Diesen kannst Du hier als Link einfügen. Achte darauf, dass jeder Zugriff darauf hat.

    Gruß Elmar

    P. S.: In Deinem vorherigen Beitrag solltest Du die E-Mail-Adresse entfernen,
    denn ansonsten könntest Du unerwünschtem Spam bekommen,
    siehe FAQ Wie vermeide ich Spam?

     

    Mittwoch, 8. September 2010 21:40
    Beantworter
  • Hallo S.,

     >  ... könnte ich es mir näher ansehen."Nun schreibst Du "denn es ...

    sonst maile es mir einfach. -> Post<Add>FranksSeite.de
    Werde mich aber erst Abends mich damit beschäftigen können.
    Aber eigentlich sollten meine Hinweise und mein downloadbares Beispiel ja ausreichend sein.



    ciao Frank
    Donnerstag, 9. September 2010 04:46
  • Hallo,

    da hat sich meine Antwort zum "Wie bereitstellen" mit Deiner Folgenachricht überschnitten.

    Wenn ich es mir nicht ansehen wollte oder könnte, hätte ich es geschrieben.
    Die Aussage denn es mag den einen oder anderen mehr interessieren
    bezog sich auf weitere Teilnehmer des Forums - Herr Dzaebel hat sich bereits gemeldet.

    In dem Du das Projekt bereitstellst, können von Deiner Frage und dem Lösungsweg
    mehr Teilnehmer jetzt und in Zukunft profitieren.

    Deine Frage ist weder aussergewöhnlich  und ein Forum lebt von der Gemeinschaftsarbeit
    der Mitglieder -  frei nach dem Motto: Vier, sechs oder mehr Augen sehen mehr als zwei,
    siehe auch Paarprogrammierung
    Auf dem E-Mail Wege wäre das eine Solo-Veranstaltung.

    Gruß Elmar

    Donnerstag, 9. September 2010 08:04
    Beantworter
  • Hallo,

    super das Ihr euch das mal ansehen wollt.

    Hier der Link und dann auf Projektmappe.

    http://cid-1e9fcc7b99ea36e1.skydrive.live.com/home.aspx

    silberlicht

    Donnerstag, 9. September 2010 09:43
  • Hallo Elmar,

    ich bin auch für öffentliche Projekt-Downloads, so wie S. es jetzt gemacht hat, aus dem selben Grund. Mein Email-Angebot bezog dann eher auf den Fall, wenn es Probleme mit SkyDrive gibt - scheint ja jetzt aber zu laufen.


        > ... Herr Dzaebel

    in Foren verwendet wir ja normal die Vornamen, ich bevorzuge das zumindest, aber wenn Du dazu übergehen willst, kein Problem.



    ciao Frank
    Donnerstag, 9. September 2010 09:54
  • Hallo S.,

    mach die Klasse ProductInfo public!

    Hättest Du gleich meinen Loaded-EventHandler aus meinem Beispiel genommen, hättest Du auch die entsprechende Meldung bekommen, die Dir den Weg gezeigt hätte ;-)


    ciao Frank

    Donnerstag, 9. September 2010 10:43
  • Hallo,

    wie schon eingangs angedeutet, stellen die DataServices präzise Anforderungen an die Klasse.

    Beim Übertragen meines Beispiels hast Du eine Kleinigkeit ausgelassen,

    nämlich die ProductInfo Klasse als public zu kennzeichnen, in meinen Beispiel steht:

     

     [DataServiceKey("ProductID")]
     public class ProductInfo : System.ComponentModel.INotifyPropertyChanged
     {
       // ...
     }
    
    Bei Dir steht:

     

     

      [DataServiceKey("ProductID")]
    
      class ProductInfo : System.ComponentModel.INotifyPropertyChanged
      {
      }
    
    Da kein Zugriffsmodifizier angegeben ist, wird die Klasse als internal gekennzeichnet,
    da es für Klassen die Standardeinstellung ist.
    Wohingegen die Data Services eine public Klasse sowie einen public Konstruktor benötigen -
    hier wegen des Zugriffs über Reflektion, die intern zur Erstellung verwendet wird..

     

    Das Resultat ist eine Ausnahme. Um sie selbst zu sehen, ändere Deinen Code für MainPage_Loaded wie folgt ab:

     

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          //var products = new DataServiceCollection<Product>(ctx);
          //products.LoadCompleted += ((o, args) => { grid1.ItemsSource = products; });
          //products.LoadAsync(from p in ctx.Product select p);
          var productsInfos = new DataServiceCollection<ProductInfo>(ctx);
          var productsInfosQuery =
           from p in ctx.Product
           where p.ListPrice > 1000
           orderby p.ListPrice descending
           select new ProductInfo()
           {
             ProductID = p.ProductID,
             ProductNumber = p.ProductNumber,
             Name = p.Name
           };
          productsInfos.LoadCompleted += ((source, eargs) =>
          {
            var list = source as DataServiceCollection<ProductInfo>;
            if (eargs.Error == null)
            {
              if (list.Continuation != null)
              {
                list.LoadNextPartialSetAsync();
              }
              else
              {
                this.grid1.ItemsSource = productsInfos;
              }
            }
            else
            {
              MessageBox.Show("Fehler beim Abruf:\r\n" + eargs.Error);
            }
          }); 
          productsInfos.LoadAsync(productsInfosQuery);
        }
    
    

     

    Falls Du Firefox verwendest, starte die Anwendungs als Out Of Browser Applikation
    (unter Projekt-Eigenschaften->Silverlight)

    Gruß Elmar
    Donnerstag, 9. September 2010 11:05
    Beantworter
  • Hallo Elmar,

        > public class ProductInfo

    das weiss er schon - hatte ich ihm schon vor ner halben Stunde gesagt - ist aber ok, wenn Du das wiederholst. Auch das mit dem Loaded-Event findest Du ja in meinem Beispiel und hatte ich ihm auch bereits gesagt. Aber doppelt hält ja hier auch besser.



    ciao Frank
    Donnerstag, 9. September 2010 11:10
  • Hey echt super Ihre zwei.

    Es funktioniert. Vielen, vielen Dank an euch. Bin super zufrieden. Toll.

     

    silberlicht

    Montag, 13. September 2010 13:47