Pokazywanie postów oznaczonych etykietą Isolated Storage. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Isolated Storage. Pokaż wszystkie posty

sobota, 11 lipca 2009

Prototyp aplikacji w Silverlight 3.0 w kilka minut?

Jedną z nowości która ukazała się przy okazji wydania najnowszej wersji Silverlight 3.0 jest budowa prototypu aplikacji przy pomocy tzw. SketchFlow (w wolnym tłumaczeniu "szkic przepływu"). Taka możliwość pojawiła w dzięki wydaniu nowej wersji programu Expression Blend 3, która to wspiera tworzenie tego typu aplikacji.

W niniejszym artykule spróbuje opisać podstawowe funkcje jakie daj nam to rozwiązanie, zbudujemy prosty prototyp aplikacji oraz wygenerujemy dla niego dokumentację.

Ale o co tu chodzi?

Otóż mamy do dyspozycji narzędzie dzięki któremu jesteśmy w stanie stworzyć prototyp interfejsu aplikacji oraz zobrazować nawigację pomiędzy oknami na czytelnym diagramie.

Potrzebne instalacje

Aby rozpocząć pracę musimy zainstalować pakiet SDK do pracy z Silverlight 3.0, a więc Microsoft® Silverlight™ 3 Tools for Visual Studio 2008 SP1 oraz Expression Blend 3 + SketchFlow RC do tworzenia naszego prototypu.

Budujemy własny prototyp

1. Tworzenie nowego projektu

Uruchamiamy Blenda, wybieramy "New Project" i następnie "Silverlight 3.0 SketchFlow Application".

Powinniśmy zobaczyć typowy dla Blenda widok nowego projektu oraz dodatkowy dolny panel z niebieskim kwadracikiem "Screen 1". Ten niebieski kwadracik reprezentuje widoczne powyżej okno aplikacji, a cały panel nazywa się "SketchFlow Map" i służy właśnie do modelowania nawigacji pomiędzy kwadracikami (czyt. Oknami aplikacji).

2. Dodajemy nowe okno

Zanim dodamy nowe okno i zdefiniujemy połączenie pomiędzy nimi, dodajmy jakiś opis do okna "Screen 1" aby móc je później rozróżnić. W tym celu otwórzmy boczne menu i wybierzmy zakładkę ">>" -> " SketchFlow" -> "Styles". W zakładce znajdziemy dużo zdefiniowanych kontrolek z przypisanymi stylami, dzięki czemu będzie nam łatwiej opisywać tworzony interfejs. Wybierzmy i przeciągnijmy na aplikację np. "TextBox" który nazywa się w tym wypadku "Note-Sketch". Możemy także nadać mu jakiś domyślny tekst.

Teraz kiedy nasze pierwsze okno jest już podpisane, dodajmy nowe. Przechodzimy do zakładki "SketchFlow Map" i najeżdżamy kursorem na niebieski kwadracik "Screen 1". W tym momencie powinno rozwinąć się menu w którym mamy do wyboru cztery opcję.

Idąc od prawej, pierwsza opcja z rozwiniętego menu to zmiana koloru kwadracika. W ten sposób możemy grupować je, zwiększając czytelność całego diagramu.

Drugą opcją od prawej jest dodanie komponentu do okna, a więc zagnieżdżenie innego okna wewnątrz tego. Sprowadza się to do stworzenia elementów w aplikacji które w prosty sposób możemy ponownie używać na wielu ekranach (np. menu, stopka).

Trzecią opcją od prawej, jest połączenie z istniejącym oknem. Kiedy nasz prototyp będzie miał wiele okien, będzie to idealny wybór aby stworzyć dodatkowe połączenia pomiędzy nimi.

Ostatnim przyciskiem od prawej, a pierwszym od lewej jest przycisk dodania nowego okno aplikacji który będzie połączony z obecnym. Właśnie tej opcji musimy użyć.

Najlepiej kliknąć prawym myszki i przeciągnąć nowo utworzony kwadracik obok. Po tej operacji utworzy się nowe puste okno "Screen 2" oraz połączenie pomiędzy nim i poprzednim oknem "Screen 1".

3. Komunikacja pomiędzy oknami

Zanim stworzymy komunikację pomiędzy oknami, dodajmy tak jak poprzednio, jakiś opis do okna "Screen 2" w celu odróżnienia go (wystarczy textbox) i wróćmy do okna "Screen 1" (np. klikając w kwadracik "Screen 1"). Na tym ekranie dodajmy przycisk który przeniesie nas do okna "Screen 2".

Aby zrealizować komunikację pomiędzy oknami, najłatwiej kliknąć prawym klawiszem myszki na przycisku, wybrać opcję "Navigate to" oraz okno do którego chcemy stworzyć połączenie.

W tym momencie uruchommy nasz prototyp i zobaczmy co otrzymaliśmy (klawisz F5).

Powinniśmy zobaczyć pierwsze okno powitalne.

Oraz drugiego okno do którego zostaliśmy przekierowani po wciśnięciu przycisku "Take me to Screen 2".

4. Modyfikacja prototypu

Na pewno wszyscy z Was zdążyli zauważyć że oprócz stworzonej aplikacji mamy także dodatkowe menu "SKETCHFLOW PLAYER". Służy ono do zaznaczania uwag do aplikacji. Do dyspozycji mamy pole tekstowe do wpisywania komentarzy do okien jak i zestaw "mazaków" do malowania bezpośrednio po interfejsie. Jeśli poruszanie się po interfejsie nie będzie dość wygodne, zawsze można użyć mapy ekranów "Map" i bezpośrednio przejść do wybranego widoku.

Co więcej, jeśli będziemy działać na raz skompilowanej wersji aplikacji (czyt. nieuruchamianej z Visual Studio), pozostawione zmiany i uwagi zostaną zapisane w przestrzeni Isolated Storage i będą widoczne gdy następny raz uruchomimy aplikację na tym samym komputerze.

Jeżeli chcemy dokonywać zmian na odległość, np. wysłać prototyp klientowi aby wprowadził na nim swoje uwagi, wystarczy że prześlemy mu aplikację, a on za pomocą opcji exportu, stworzy plik z rozszerzeniem feedback który później możemy zaimportować do Expression Blenda (przez import rozumiem tutaj dodanie pliku do projektu - "Add Existing Item.." ).

Aby wygenerować wersję aplikacji którą możemy przekazać klientowi, najłatwiej wybrać opcję "File" w menu w Expression Blend 3 i kliknąć "Package SketchFlow Project..". Stworzony projekt jest gotowy do uruchomienia (TestPage.html).

Demo: link

Source Code: link

Dokumentacja papierowa

Jeśli mimo wszystko łatwiej jest nam pracować na "papierowej wersji aplikacji", czyli po prostu print screeny z aplikacji, powinniśmy zwrócić uwagę na opcję "Export to Microsoft Word..". Opcja ta pozwala na wygenerowanie pełnej dokumentacji okien prototypu. Powstały Word zawiera spis treści, spis obrazków oraz mapkę połączeń pomiędzy ekranami (SketchFlow Map). Co więcej możemy także zastosować wordowy template który ma być użyty do wygenerowania dokumentacji.

Jeszcze kilka miesięcy temu pamiętam jak robiłem print screeny okien i mapę nawigacji aby przenieść je do Worda, wydrukować i później w grupie znajomych nanosić ręcznie sugerowane poprawki do aplikacji. Teraz wiem że już nie będę musiał tego robić ręcznie. :)

Przykład takiego dokumentu znajdziecie tutaj: link

Podsumowanie

Jak widzicie, mając tak doskonałe narzędzie jesteśmy w stanie tworzyć prototyp aplikacji oraz zmieniać go bez większego nakładu pracy. Ustalanie zawartości jak i wyglądu interfejsu nigdy nie było tak łatwe, a mnogość opcji jakie daje nam nowy Expression Blend 3 wspiera nas na każdym kroku.

Oczywiście SketchFlow dostarcza o wiele więcej innych opcji, jak chociażby animację pomiędzy oknami, czy też tworzenie i zagnieżdżanie własnych "kompozycji" elementów w innych oknach, z którymi także polecam się zapoznać.

References

sobota, 13 grudnia 2008

Isolated Storage Memory w Silverlight 2.0 RTW

W artykule tym postaram się możliwie krótko i zrozumiale opisać zagadnienie izolowanej przestrzeni pamięci dla aplikacji, czyli Isolated Storage.

Na co mi to?

Miejsce to, odnosi się do kawałka dysku na komputerze po stronie klienta, w którym aplikacja ma prawo przetrzymywać swoje pliki i informacje. Do użytku mamy z defaultu 1MB ale wielkość pamięci może być zmieniona przez usera (o tym za chwilę).

Taka ilość miejsca oraz wyjątkowa łatwość dostępu, daje nam duże możliwości. Wielokrotnie wykorzystywałem tą przestrzeń, jako miejsc do przechowywania informacji o ustawieniach użytkownika, jako lokalny high scores dla gry lub też informacje dla ankiety, o tym czy użytkownik już dziś głosował. Zastosowań jest naprawdę wiele i warto pamiętać o tym rozwiązaniu.

Zróbmy sobie przykład

Jako przykład aplikacji zróbmy prosty program, w którym podajemy swoje imię, a program będzie je pamiętał i wyświetlał przy każdym kolejnym uruchomieniu.

Zacznijmy od dodania kontrolek do wprowadzenia danych

<TextBox Height="32" x:Name="EnterName" Width="192" Text="Enter your name here" TextWrapping="Wrap"/> 

<Button Height="28" x:Name="SubmitButton" Width="106" Foreground="#FF313131" Content="Submit" Click="SubmitButton_Click">

oraz TextBlocka do wyświetlania zapamiętanego imienia

<TextBlock Height="91" x:Name="NameTextBlock" Width="284" TextWrapping="Wrap">

<Run x:Name="UserName" FontFamily="Comic Sans MS" FontSize="36" FontWeight="Bold" Text="" />

</TextBlock>

Następnie w kodzie wywołujemy metodę do odczytu imienia oraz zapisu. Aby odczytać coś z przestrzeni aplikacji, należy stworzyć obiekt IsolatedStorageFile

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

który przyda nam się do sprawdzenia czy plik istnieje

if (!isf.FileExists("nasz_zapisany_plik.txt"))

oraz do utworzenia FileStream-era

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("nasz_zapisany_plik.txt", FileMode.Open, isf);

Teraz wystarczy podłączyć np. StreamReader i możemy robić odczyty jak na zwykłym pliku txt w aplikacji desktopowej.

StreamReader sr = new StreamReader(isfs);

userName = sr.ReadToEnd();

sr.Close();

Aby zapisać coś w Isolated Storage, otwieramy plik z innym FileMode, np.

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("nasz_zapisany_plik.txt", FileMode.Create, isf);

oraz zamiast StreamReadera, podłączamy StreamWriter

StreamWriter sw = new StreamWriter(isfs);

Cała reszta jest analogiczna do operacji na zwykłych plikach.

Kompletna metoda zapisu:

private void SaveUserName(string name)

{
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Create, isf);

StreamWriter sw = new StreamWriter(isfs);
try

{

sw.WriteLine(String.Format("{0}", name));

}

catch (Exception ee) { }

finally

{

sw.Close();

isfs.Close();

isfs.Dispose();

isf.Dispose();

sw.Dispose();

}

}

Kompletna metoda odczytu:

private string ReadNameIfExist()

{

string userName = String.Empty;

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

if (!isf.FileExists(FILE_NAME))

return userName;

IsolatedStorageFileStream isfs = new IsolatedStorageFileStream(FILE_NAME, FileMode.Open, isf);

try

{

StreamReader sr = new StreamReader(isfs);

userName = sr.ReadToEnd();

sr.Close();

}

catch (Exception e) { }

finally

{

isf.Dispose();

}

return userName;

}

W powyższym "przykładzie", nie umieszczałem całego kodu z przygotowanego dema, ponieważ zrobił się trochę za długi (szczególnie generowany xaml), dlatego też po całość zapraszam do części source code.

Gotowa aplikacja wygląda tak: link. (Nie zapomnijcie o odświeżaniu strony => F5).

Można łatwiej? [edit 29-08-2008]

Tak jak Kuba słusznie zauważył (Kuba Florczyk), w swoim artykule pominąłem kwestie klasy IsolatedStorageSettings. IsolatedStorageSettings jest to klasa która zapewnie łatwiejszą obsługę Isolated Storage. Nie musimy deklarować IsolatedStorageFile i IsolatedStorageFileStream, wszystko mamy opakowane w klasie, a wszelkie operacji przeprowadzamy jak na Dictionary, czy też ASP-owej sesji (klucz-wartość).

A więc podajemy klucz i przypisujemy wartość. Aby odczytać wartość, wystarczy podać klucz i otrzymujemy obiekt z zapisaną wcześniej wartością.

Przykład użycia

Deklaracja
private IsolatedStorageSettings isolatedSettings = IsolatedStorageSettings.ApplicationSettings;
Zapis danych
try
{
isolatedSettings.Add("imie", name);
}
catch (ArgumentException ex)
{
// message z bledem
}
Odczyt danych
string name = String.Empty;
try
{
name = (string)isolatedSettings["name"];
}
catch (System.Collections.Generic.KeyNotFoundException)
{
// blad i wartosc domyslna dla name
name = "anonymous";
}
Aktualizacja danych
isolatedSettings["name"] = "nowe imie";

Usuwanie danych
isolatedSettings.Remove("name");

Czyszczenie wszystkich ustawień
isolatedSettings.Clear();

Liczba ustawień
isolatedSettings.Count();

Lista dostępnych kluczy
isolatedSettings.Keys;

Lista dostępnych wartości
isolatedSettings.Values;

Jak widać, IsolatedStorageSettings zapewnia prace jak ze zwykłym słownikiem. Rozwiązanie to zaoszczędzi nam dużo czasu i uprości kod.

I na końcu, jeszcze raz dzięki Kubie za pomocny komentarz!!! :)

Jak zwiększyć wielkość dostępnej pamięci?

Otóż zwiększanie potrzebnej pamięci jest wyjątkowo proste ale musi zgodzić się na to użytkownik. W związku z tym, musimy go zapytać i jeśli się zgodzi, wtedy możemy zapisywać na jego dysk więcej danych. Limit pamięci do jakiej możemy zwiększyć jest ograniczony tylko przez wielkość typu ""long", a więc mniej więcej 8,589,934,592Gb :)

A więc wystarczy wywołać kod:

private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
Int64 sizeNeeded = 1024 * 1024 * 100;
if (sizeNeeded > isf.AvailableFreeSpace)
{
Int64 newValue = isf.Quota - isf.AvailableFreeSpace + sizeNeeded;
if (isf.IncreaseQuotaTo(newValue))
{
// np. zapis danych
}
}
}
}


Efekt:

User zobaczy ładne zapytanie i po jego akceptacji możemy zapisywać dane. Niestety, nie znalazłem możliwości modyfikacji treści zapytania, a więc informacja w okienku musi zostać taka jak jest. Dodatkowo, zapytanie może być wywołane tylko z eventów, a więc nie odpytamy użytkownika o zwiększenie ilości pamięci podczas inicjalizacji aplikacji. Możemy to zrobić dopiero gdy wciśnie jakiś przycisk w aplikacji (kwestie bezpieczeństwa).

uwaga bug:
Ponieważ zapytanie jest zawsze w języku angielskim, to w przypadku gdy użytkownik nie posiada systemu operacyjnego w tym języku, zapytanie o zwiększenie ilości danych nigdy się nie pojawi i zawsze będzie zwracać "false". Bug jest zgłoszony do MS i można poczytać o nim więcej tutaj: http://silverlight.net/forums/p/51485/135114.aspx

Gdzie to jest?

Aby znaleźć dokładne miejsce przetrzymywania informacji, najłatwiej jest użyć debugera.



Zmienna "m_AppFilePath" podpowie nam, że jest to gdzieś w przestrzeni naszego użytkownika oraz w przestrzeni assembly naszej aplikacji. Taka ścieżka nie jest łatwa do zapamiętania i może wyglądać np. tak:

"C:\\Users\\ToJaUser\\AppData\\LocalLow\\Microsoft\\Silverlight\\is\\3tumcpvn.hf1\\wrelfaen.uut\\1\\s\\rtqyd4tgtuurqnzlqaf3otinrvcefdf4aeqlkxhw0dltde2t2uaaaeaa\\f"

Jak to usunąć?

Aby zobaczyć ile miejsca zajmuje aplikacja i ewentualnie wyczyścić wgrane pliki, wystarczy że klikniemy prawym na aplikacji Silverlight i wybierzemy "Silverlight Configuration"



Następnie przejdziemy do zakładki "Application Storage".



W zakładce tej mamy komplet informacji o aplikacjach, łącznie z ilością miejsca jakie zajmują na naszych dyskach.

Source code

Working demo

Reources

  • MSDN System.IO.IsolatedStorage Namespace - link
  • Blog trzech panów: "Switch On The Code" linktrochę nieaktualne, ale to tu znalazłem kiedyś pierwsze wzmianki o Isolated Storage Memory


Pozdrawiam,

Jacek Ciereszko