Ergebnis 1 bis 19 von 19
-
entwickelt Apps
- 18.12.2011, 21:12
- #1
Hi Leute, ich entwickle gerade 'ne Automanger App um den Tankverlauf von Autos zu "loggen".
Aus irgendeinem Grund bekomme ich aber 'nen InvalidOperationException Fehler und weiß nicht, wie ich diesen beheben kann.
Ich hab 'n MainViewModel, welches die Eigenschaft Auto hat (mit NotifyPropertyChanged Event)
Wenn ich nun das MainViewModel bei der Autoauswahl wechseln will und das MainViewModel neu setzen will, bekomme ich den Hinweis "Cannot change ObservableCollection during a CollectionChanged or PropertyChanged event." bei der Zeile wo das Kommentar ist.
Code:public class MainViewModel : INotifyPropertyChanged { [...] public void Save() { ObservableCollection<Auto> collection = new ObservableCollection<Auto>(); if (IsolatedStorageSettings.ApplicationSettings.Contains("Autos")) { collection = (ObservableCollection<Auto>)IsolatedStorageSettings.ApplicationSettings["Autos"]; if (collection.Contains(this.aktuellesAuto)) { Debug.WriteLine("Auto aktualisiert: " + collection.IndexOf(this.aktuellesAuto)); // Fehler collection[collection.IndexOf(this.aktuellesAuto)] = this.aktuellesAuto; // <----- hier tritt der Fehler auf. } else { collection.Add(this.aktuellesAuto); Debug.WriteLine("1. Neues Auto erstellt: " + collection.IndexOf(this.aktuellesAuto).ToString()); AppSettings.aktuelleAutoId = collection.IndexOf(this.aktuellesAuto); } } else { collection.Add(this.aktuellesAuto); Debug.WriteLine("2. Neues Auto erstellt: " + collection.IndexOf(this.aktuellesAuto).ToString()); AppSettings.aktuelleAutoId = collection.IndexOf(this.aktuellesAuto); } IsolatedStorageSettings.ApplicationSettings["Autos"] = collection; IsolatedStorageSettings.ApplicationSettings.Save(); } [...] }
Der Aufruf der Save()-Methode kommt aus der AutoListPage.xaml
Code:public partial class AutoListPage : PhoneApplicationPage { [...] private void ListBox_Autos_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ListBox_Autos.SelectedIndex != AppSettings.aktuelleAutoId) { App.ViewModel.Save(); AppSettings.aktuelleAutoId = ListBox_Autos.SelectedIndex; App.ViewModel = new MainViewModel(); } //NavigationService.Navigate(new Uri("/../MainPage.xaml", UriKind.Relative)); NavigationService.GoBack(); } [...] }
-
Fühle mich heimisch
- 18.12.2011, 22:09
- #2
Hallo Erdnuss
Ich sehe den Fehler zwar nicht, aber evtl. hilft es wenn du den Typ der Collection z.B. in List änderst, oder zeigst du diese Collection auf dem GUI an?
Des weiteren bin ich mir überhaupt nicht sicher, ob der Block welcher den Fehler verursacht Sinn macht. Contains überprüft ja, ob genau das Element in der Liste ist, falls ja müsste man es gar nicht mehr anpassen, da das aktuellesAuto und das Auto in der Liste auf das selbe Object im Speicher referenzieren und somit wird der Inhalt automatisch angepasst.
Ich hoffe du Verstehen worauf ich hinaus will
Gruss
Cr3dos
-
entwickelt Apps
- 18.12.2011, 23:03
- #3
Hi,
nein diese collection, die in der Methode da erzeugt wird, wird nicht auf der gui angezeigt. Ich werds morgen mal probieren
Ne, nicht so ganz.
Wenn ich das aktuellesAuto verändere, dann wird es doch nicht gleichzeitig im isostorage aktualisiert.? Und das will ich aber mit der save Methode ja machen.
Gruß
ErdnussFlipS
PS: ich bin noch ein relativer anfänger in Sachen wp7 app Entwicklung. Damit meine ich, dass ich noch nicht so ganz hinter das mvvm Konzept gestiegen bin und auch noch nicht so richtig das notify Zeugs verstanden habe.
Mit der kostenlosen PocketPC.ch App von meinem HD7 T9292 aus geschrieben.
-
Fühle mich heimisch
- 19.12.2011, 18:06
- #4
Hallo,
Da hast du recht, dass es nicht gleichzeitig aktualisiert wird.
Dieses Contains wird meiner Meinung nach immer false zurückgeben, da das Aktuelle Auto nicht auf das selbe referenziert im Speicher wie die Liste, die aus dem Storage geholt wurde.
Aber ich kann es auch nicht 100% sagen, da ich nicht direkt mit dem IsolatedStorage(oder IsolatedStorageSettings) arbeite. Ich benutze das RapidRepository. Würde dir empfehlen dies mal anzuschauen, falls du noch nicht allzu viel gemacht hast.
Gruss
Cr3dos
-
entwickelt Apps
- 19.12.2011, 18:21
- #5
Hi,
also ich habs jetzt mal mit na Liste probiert, so das funktioniert aber auch nicht, da die collection im isostorage ja auch ne observablecollection ist und ich die ja dann umwandeln müsste (bekomme demzufolge nen invalidcastexeption). Und ich weiß jetzt nicht auf de schnelle wie ich das umwandle.
und normalerweise funktioniert das ja auch mit de speichern, also der muss das Objekt schon irgendwie finden (id? Ka.). Er gibt mir ja nur nem Error wenn ich das Auto das zweite mal bei einem app Start wechsele. Wenn ich mehrere neu Autos erstelle wird die save Methode auch augeführt und der hat keine Probleme..
Mit dem rapidrepository schau ich mir mal an.
Gruß
ErdnussFlipS
Mit der kostenlosen PocketPC.ch App von meinem HD7 T9292 aus geschrieben.
-
Fühle mich heimisch
- 19.12.2011, 18:50
- #6
Umwandeln ist ganz einfach:
List<Auto> collection = new List<Auto>();
foreach(Auto auto in (ObservableCollection<Auto>)IsolatedStorageSettings.ApplicationSettings["Autos"]){
collection.Add(auto);
}
-
entwickelt Apps
- 19.12.2011, 19:17
- #7
Danke.
Hmm, aber so Performance orientiert ist das jetzt auch nicht.:/
Ich lade die collection ja nur, um das da zu speichern. Also müsste ich jetzt die collection laden, dann eine neue liste anlegen und diese mit den Objekten aus dem isostorage füllen, um dann herauszufinden, ob ein Objekt vorhanden ist, und am ende die liste wieder zur collection umwandeln um sie dann verändert zu speichern. Ist doch doof, hast du ne andere Idee?
Mit der kostenlosen PocketPC.ch App von meinem HD7 T9292 aus geschrieben.
-
Fühle mich heimisch
- 19.12.2011, 20:52
- #8
Performance mässig spielt dies keine grosse Rolle, da der User in deiner App vermutlich nicht mehr als 10 Autos eintragen wird.
In meiner App MySchool mache ich diese Umwandlung auch und ich bekam noch nie eine Beschwerde wegen Performance-Problemen.
Natürlich kann man auch eine normale Liste nehmen um auf dem GUI anzuzeigen und muss dann nicht jedes mal das Umwandeln machen.
-
- 19.12.2011, 23:34
- #9
Ich bin mir nicht 100% sicher, ob ich verstanden habe, was du mit dem Code im ersten Post eigentlich machen willst. Ein paar Anmerkungen habe ich aber trotzdem:
- Bei jedem SelectionChanged Event auf den Isolated Storage zuzugreifen ist auch nicht gerade performace-orientiert. Den Aufwand für die Umwandlung einer Liste kannst du völlig vernachlässigen gegenüber Zugriffen auf Isolated Storage.
- Eigentlich sagt die Exception "Cannot change ObservableCollection during a CollectionChanged or PropertyChanged event." ziemlich genau, was das Problem ist. Es geht zwar aus deinem Codebeispiel nicht hervor, aber ich nehme stark an, dass die ListBox_Autos an die ObservableCollection gebunden ist, die du in den IsolatedStorageSettings speicherst? Du kannst die ObservableCollection nicht ändern in einem Event Handler, der von einem potenziell die ObservableCollection ändernden Ereignis ausgeht, da du andernfalls eine "Endlosschleife" produzieren würdest. Du würdest die Collection ändern als Reaktion auf eine Änderung.
Ich hoffe, das war halbwegs verständlich
Eine einfache Lösung habe ich leider gerade nicht parat. Aber mal so ins blaue gefragt: wieso willst du bei jedem SelectionChanged Event den Zustand gleich persistieren?
-
entwickelt Apps
- 20.12.2011, 15:00
- #10
Also ich bin jetzt ein wenig verwirrt.^^
Ist es nun besser ne Liste zu binden oder ne ObservableCollection ?
Desweiteren habe ich jetzt nochmal den Speicherzeitpunkt geändert. Es wird nur noch gespeichert, wenn der Nutzer die App richtig schließt.
Nun werden auch am Anfang alle Autos ins MainViewModel in eine ObservableCollection Autos geladen.
Aus dieser wird dann das aktuellesAuto geholt.
Code:public void LoadData() { if (AppSettings.aktuelleAutoId < 0) { this.aktuellesAuto.Automarke = "Kein Auto geladen"; this.aktuellesAuto.Modeltyp = ""; this.aktuellesAuto.Kennzeichen = "-"; } if (IsolatedStorageSettings.ApplicationSettings.Contains("Autos")) { this.Autos = (ObservableCollection<Auto>)IsolatedStorageSettings.ApplicationSettings["Autos"]; this.aktuellesAuto = (Auto)Autos[AppSettings.aktuelleAutoId]; this.aktuellesAuto.Tankvorgaenge = new ObservableCollection<Tankvorgang>(); this.aktuellesAuto.Tankvorgaenge.Add(new Tankvorgang() { Liter = 45, Preis = 60, GesamtKilometer = 550, Tankdatum = DateTime.Now, Verbrauch = 6 }); this.aktuellesAuto.Fahrten = new ObservableCollection<Fahrt>(); this.aktuellesAuto.Fahrten.Add(new Fahrt() { Name = "Fahrt X", Beschreibung = "Nach Berlin", Kilometer = 500 }); this.IsDataLoaded = true; } }
Code:private void ListBox_Autos_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ListBox_Autos.SelectedIndex != AppSettings.aktuelleAutoId) { App.ViewModel.Autos[AppSettings.aktuelleAutoId] = App.ViewModel.aktuellesAuto; AppSettings.aktuelleAutoId = ListBox_Autos.SelectedIndex; App.ViewModel.aktuellesAuto = App.ViewModel.Autos[AppSettings.aktuelleAutoId]; } //NavigationService.Navigate(new Uri("/../MainPage.xaml", UriKind.Relative)); NavigationService.GoBack(); }
So und naja sie war nicht gebunden, nein. Die Collection war nur in der SaveMethode lokal vorhanden.
Jetzt ist das ganze ViewModel (MainViewModel) an die ListBox_Autos gebunden, weil irgendwie bei ViewModel.Autos ich immer gesagt bekomme in der Ausgabe, dass der Pfad nicht stimmt. :/
-
Fühle mich heimisch
- 20.12.2011, 15:48
- #11
Ich weiss nicht wie sehr du dich mit der OO-Programmierung / C# bis jetzt befasst hast.
Das Item in der ObservableCollection beinhaltet eine Referenz auf den Speicher. Im Speicher sind die genau Daten abgelegt z.B. die genau Tankvorgang, Fahrten etc. Weist du einer anderen Variable das Auto zu, also in deinem Fall "this.aktuellesAuto = (Auto)Autos[AppSettings.aktuelleAutoId];" sagst du nichts anderes als "Die Variable aktuellesAuto zeigt auf die selbe Position im speicher wie das Auto an der Position AppSettings.aktuelleAutoId" (Anmerkung: den cast ("(Auto)") kann man weglassen)
-
entwickelt Apps
- 20.12.2011, 16:49
- #12
Ja doch, das mit dem Speicher hatte ich eig schonmal gelesen. Aber ich nehm das noch nicht so richtig für voll.
Nur was bedeutet das dann im Endeffekt?
EDIT: Das komische an der Ganzen Sache ist nur, dass ich das Auto ja einmal wechseln kann. Also "ListBox_Autos_SelectionChanged" wir ja einmal ausgeführt, nur nach einem weiteren Wechsel oder einem weiteren Versuch des Wechselns, bekomme ich die Exception.
-
Fühle mich heimisch
- 20.12.2011, 17:07
- #13
Nur was bedeutet das dann im Endeffekt?
-
entwickelt Apps
- 20.12.2011, 17:30
- #14
Ah okay.. Dann müsste das ja funktionieren. Und die Collection ist dann ja auch aktuell.
EDIT: Also das mit dem wechseln funktioniert jetzt.
Noch ne andere Frage, egal was ich nun mache die ListBox_Autos_SelectionChanged-Methode ist jetzt nur noch am rummeckern. -.- Also die will sich jetzt immer aufrufen, immer wenn sich die gebundene Collection ändern, also im Moment wenn ich alle Autos lösche. Kann ich diesen Aufruf irgendwie stoppen, also das Event?
Code:private void ListBox_Autos_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ListBox_Autos.SelectedIndex != AppSettings.aktuelleAutoId && ListBox_Autos.SelectedIndex >= 0) { AppSettings.aktuelleAutoId = ListBox_Autos.SelectedIndex; App.ViewModel.aktuellesAuto = App.ViewModel.Autos[AppSettings.aktuelleAutoId]; } NavigationService.GoBack(); }
-
Fühle mich heimisch
- 20.12.2011, 17:58
- #15
Meiner Meinung nach, wenn du sicher gehen willst kannst du ja debuggen
-
entwickelt Apps
- 20.12.2011, 22:59
- #16
Hi, ich hab jetzt ein ganz anderes Problem.
Ich hatte den Code n bisschen umgeschrieben, nun schmiert mir die App immer ab, wenn ich "IsolatedStorageSettings.ApplicationSettings.Save();" aufrufe. Der Debugger gibt mir auch nichts aus. Habt ihr ne Idee, wie ich herausfinden kann warum es abschmiert?
Das ist die Methode
Code:public void Save() { Debug.WriteLine("Save(): " + AppSettings.aktuelleAutoId); if (AppSettings.aktuelleAutoId >= 0) { Debug.WriteLine("Fehler nach setzen."); IsolatedStorageSettings.ApplicationSettings["Autos"] = this.Autos; try { Debug.WriteLine("Fehler vor Save()"); IsolatedStorageSettings.ApplicationSettings.Save(); Debug.WriteLine("Kein Fehler"); } catch (IsolatedStorageException) { Debug.WriteLine("Fehler"); throw; } } }
-
Fühle mich heimisch
- 21.12.2011, 16:32
- #17
try
{
Debug.WriteLine("Fehler vor Save()");
IsolatedStorageSettings.ApplicationSettings.Save();
Debug.WriteLine("Kein Fehler");
}
catch (Exception e)
{
Debug.WriteLine(e);
}
-
entwickelt Apps
- 21.12.2011, 20:07
- #18
Hab ich versucht. Er catcht die Exeption nicht.
Hab das So drinne:
Code:Debug.WriteLine("Save(): " + AppSettings.aktuelleAutoId); if (AppSettings.aktuelleAutoId >= 0) { Debug.WriteLine("Fehler nach setzen."); IsolatedStorageSettings.ApplicationSettings["Autos"] = this.Autos; try { Debug.WriteLine("Fehler vor Save()"); IsolatedStorageSettings.ApplicationSettings.Save(); Debug.WriteLine("Kein Fehler"); } catch (Exception e) { Debug.WriteLine("Exception: " + e); } }
Save(): 0
Fehler nach setzen.
Fehler vor Save()
Der Thread '<Kein Name>' (0x27790dee) hat mit Code 0 (0x0) geendet.
Der Thread '<Kein Name>' (0x260e08fa) hat mit Code 0 (0x0) geendet.
Der Thread '<Kein Name>' (0x264c0766) hat mit Code 0 (0x0) geendet.
Das Programm "[647564254] UI Task: Verwaltet" wurde mit Code 0 (0x0) beendet.
-
entwickelt Apps
- 23.12.2011, 17:24
- #19
Problem gelöst. War ein Fehler in der Klasse Auto.^^
Funktioniert jetzt.
Ähnliche Themen
-
Wie bekomme Ich Bilder und Video auf meinem PC
Von alex190 im Forum Samsung Galaxy SAntworten: 2Letzter Beitrag: 27.12.2010, 07:42 -
Neues Handy, aber weiß nicht wie ich Spiele laden kann :S
Von Syrius94 im Forum HTC WildfireAntworten: 3Letzter Beitrag: 07.12.2010, 07:30 -
wie bekomme ich videos, bilder und lieder auf das X10
Von s3rk im Forum Android AllgemeinAntworten: 5Letzter Beitrag: 17.07.2010, 00:06 -
Wie bekomme ich die obere und untere Taskbar transparent?
Von die_braut im Forum HTC HD2 InterfaceAntworten: 20Letzter Beitrag: 17.05.2010, 00:13 -
Was ist das für ein Fehler und wie bekomme ich den weg
Von rennsemmel im Forum HTC HD2 ROM UpgradeAntworten: 30Letzter Beitrag: 26.02.2010, 06:46
Besucher haben diese Seite mit folgenden Suchbegriffen gefunden:
,
invalidoperationexception,
isolated storage operation was bedeutet,
,
htc wildfire s recovery invalid operation,
,
,
c# das ereignis kann nur links von oder verwendet werden,
,
,
c# xaml invalidoperationexception,
kann nur links von = oder -= verwendet werden.,
kann nur links von = oder -= verwendet werden,
wie bekommer ich die fehlermeldung beim auto auf null,
propertychanged kann nur links von = oder -= verwendet werden.,
kann nur links von = oder -= c# property -=,
csharp programm beenden invalidoperation,
invalidoperationexception raise collectionchanged,
wp7 loaded eventhandler invalidoperationexception,
collectionchanged kann nur links von = oder -= verwendet werden,
,
c# propertychanged kann nur links von = oder -= verwendet werden,
Cannot change ObservableCollection during a CollectionChanged event,
NavigationService,
wp7 invalid operation exception navigation
Pixel 10 Serie mit Problemen:...