Reputation: 97
i am currently attempting to add isolated storage to a simple pet shop app on Windows Phone / C#. (Please note that this is my 1st attempt at isolated storage so i may be WAY off)
I just want to add the isolated storage to my 'basket' so that when you add an item to your basket and then close the app the item will still be in my basket when you re launch the app.
Firstly here is the code where i add an 'Animal item' to the basket.
private void list_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
Shop selectedPet = list.SelectedItem as Shop;
//thisApp.tempItem = selectedPet;
String photo = selectedPet.Photo;
String breed = selectedPet.Breed;
String name = selectedPet.Name;
DateTime age = selectedPet.Age;
double price = selectedPet.Price;
NavigationService.Navigate(new Uri("/Profile.xaml?&breed=" + breed + "&age=" + age + "&price=" + "€" + price + "&name=" + name + "&" + "photo=" + photo, UriKind.Relative));
}
This piece of code passes the individual pieces of information of the selected item to a 'profile page'
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
try
{
//String temp1 = thisApp.tempItem.Name;
string photo;
string name;
string age;
string breed;
string price;
if (NavigationContext.QueryString.TryGetValue("photo", out photo))
{
imgPhotoHolder.Source = null;
BitmapImage myimage = new BitmapImage
(new Uri("/Assignment 1;component/Images/" + photo, UriKind.RelativeOrAbsolute));
imgPhotoHolder.Source = myimage;
}
if (NavigationContext.QueryString.TryGetValue("name", out name))
{
nameTxtBlock.Text = name;
}
if (NavigationContext.QueryString.TryGetValue("age", out age))
{
ageTxtBlock.Text = age;
}
if (NavigationContext.QueryString.TryGetValue("breed", out breed))
{
breedTxtBlock.Text = breed;
}
if (NavigationContext.QueryString.TryGetValue("price", out price))
{
priceTxtBlock.Text = price;
}
Find(photo);
}
catch
{
MessageBox.Show("Image did not load...");
}
}
This then adds the pieces of information to the profile page but the problem arised where instead of passing the object i passed individual pices of info, therefore essentially breaking down the object, so to rectify this i used the below code and was able to pass it into my basket on a button pressed event.
private void Find(String str)
{
foreach (Shop pet in thisApp.myshop)
{
if (pet.Photo == str)
{
index = thisApp.myshop.IndexOf(pet);
}
}
}
private void btnAddToBasket_Click(object sender, RoutedEventArgs e)
{
bool found = false;
try
{
foreach (Shop pet in thisApp.basket)
{
if(thisApp.myshop[index].Photo == pet.Photo)
{
found = true;
}
}
if (found)
{
MessageBox.Show("Item already in Basket");
}
else
{
thisApp.basket.Add(thisApp.myshop.ElementAt(index));
}
}
catch
{
MessageBox.Show("That didn't work...");
}
}
Now to where the problem arises, i have put the isolated storage code into the App.xaml as seen here.
public void WriteBasketToStorage()
{
using (IsolatedStorageFile cart = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("Cart.xml",
FileMode.Create, cart))
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(isoStream, settings))
{
writer.WriteStartElement("Pets");
foreach (Shop currPet in basket)
{
writer.WriteStartElement("Pet");
writer.WriteElementString("Name", currPet.Name);
writer.WriteElementString("Age", currPet.Age.ToString());
writer.WriteElementString("Breed", currPet.Breed);
//writer.WriteElementString("Type", currPet.Type);
//writer.WriteElementString("Stock", currPet.Stock.ToString());
writer.WriteElementString("Price", currPet.Price.ToString());
writer.WriteElementString("Photo", currPet.Photo);
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
}
}
}
}
public void RetrieveBasketData()
{
try
{
using (IsolatedStorageFile cart = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream isoStream = cart.OpenFile("Basket.xml", FileMode.Open))
{
try
{
XmlReader reader = XmlReader.Create(isoStream);
reader.ReadToDescendant("Pet");
basket.Clear();
while (reader.Read())
{
//reader.MoveToFirstAttribute();
reader.ReadToFollowing("Name");
string name = reader.ReadElementContentAsString();
reader.ReadToFollowing("Age");
string age = reader.ReadElementContentAsString();
reader.ReadToFollowing("Breed");
string breed = reader.ReadElementContentAsString();
//reader.ReadToFollowing("Type");
//string type = reader.ReadElementContentAsString();
//reader.ReadToFollowing("Stock");
//string stock = reader.ReadElementContentAsString();
reader.ReadToFollowing("Price");
string price = reader.ReadElementContentAsString();
reader.ReadToFollowing("Photo");
string photo = reader.ReadElementContentAsString();
DateTime date = DateTime.Parse(age);
decimal price1 = Decimal.Parse(price);
//basket.Add(new Shop(name, age, breed, type, stock, date, price1, photo ));
basket.Add(new Shop(photo, breed, name, date, price1));
}
}
catch
{
}
}
}
catch (IsolatedStorageException ise)
{
MessageBox.Show(ise.Message);
}
}
and i have tried to retrieve it in my basket page with this code
public void ReadBasketDetailsFromStorage()
{
try
{
using (IsolatedStorageFile petStore = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream isoStream = petStore.OpenFile("Basket.xml", FileMode.Open))
{
try
{
XmlReader reader = XmlReader.Create(isoStream);
reader.ReadToDescendant("Pet");
while (reader.Read())
{
//reader.MoveToFirstAttribute();
reader.ReadToFollowing("Name");
string name = reader.ReadElementContentAsString();
reader.ReadToFollowing("Age");
string age = reader.ReadElementContentAsString();
reader.ReadToFollowing("Breed");
string breed = reader.ReadElementContentAsString();
//reader.ReadToFollowing("Type");
//string type = reader.ReadElementContentAsString();
//reader.ReadToFollowing("Stock");
//string stock = reader.ReadElementContentAsString();
reader.ReadToFollowing("Price");
string price = reader.ReadElementContentAsString();
reader.ReadToFollowing("Photo");
string photo = reader.ReadElementContentAsString();
DateTime date = DateTime.Parse(age);
decimal price1 = Decimal.Parse(price);
//basket.Add(new Shop(name, age, breed, type, stock, date, price1, photo ));
thisApp.basket.Add(new Shop(photo, breed, name, date, price1));
}
}
catch
{
}
}
}
catch (IsolatedStorageException ise)
{
MessageBox.Show(ise.Message);
}
}
The error that i am being presented with is that it doesn't contain a constructor that takes 5 arguements. I have tried to fix it by using the fields that aren't required like 'Type' and 'Stock' but it then says is doesn't contain a constructor that takes 7 arguements etc etc.
I am unsure what to do with this at the moment and would greatly appreciate some advice/help with this problem. If you require any more of the code to understand fully my problem please ask for it and i will add it to the post.
Thanks in advance, Jason
Upvotes: 0
Views: 184
Reputation: 29792
There are couple of things which you can improve in your code:
//first of all lets make classes for your Shop and Basket:
public class Basket
{
public List<Shop> Items = new List<Shop>();
}
public class Shop
{
public String photo { get; set; }
public String breed { get; set; }
public String name { get; set; }
public String age_value // for serialization
{
get { return age.ToString("D"); }
set { age = DateTime.Parse(value); }
}
public double price { get; set; }
[XmlIgnore]
public DateTime age { get; set; }
}
As you can see I've added one additional filed for Serialization. It will be easier to serialize your basket rather than reading/writing all elements manually. You can read about Serialization here, and probably at many tutorials. With this your Save and Load can look far more simpler:
// somewhere in your code (for example MainPage class)
Basket basket = new Basket();
// and upon click, there were some items added:
basket.Items.Add(new Shop { photo = "aaa.png", breed = "bbb", age = new DateTime(2000, 11, 20, 20, 12, 10), name = "turtle", price = 100 });
public void SaveBasket()
{
using (IsolatedStorageFile cart = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream isoStream = cart.CreateFile("Cart.xml"))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Basket));
xmlSerializer.Serialize(isoStream, basket);
}
}
public void LoadBasket()
{
using (IsolatedStorageFile cart = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream isoStream = cart.OpenFile("Cart.xml", FileMode.Open))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Basket));
basket = (Basket)xmlSerializer.Deserialize(isoStream);
}
}
As for passing data between Pages - it's a long story and if you search for 'Pass data between Pages', then you will surely find many hits. The easiest way would be to make your basket
static and then access it from other Page like this: MainPage.basket
. In case you want to pass data, I would advise to use PhoneApplicationService.State Property like this:
// when Navigating:
if (PhoneApplicationService.Current.State.ContainsKey("data")) PhoneApplicationService.Current.State["data"] = basket;
lse PhoneApplicationService.Current.State.Add("data", basket);
// in constructor of next page, or OnNavigatedTo event:
Basket passedOne = PhoneApplicationService.Current.State["data"] as Basket;
These are only simple examples and there are a lot of ways you can achieve your goal. Hopefuly this answer will show you some new possibilities.
Upvotes: 1