Ustawienia aplikacji w C#

Wszystkie bardziej rozbudowane aplikacje mają to do siebie, że przechowują wprowadzone przez użytkownika dane. Chyba nikt nie wyobraża sobie ustawiania swoich indywidualnych preferencji np. w przeglądarce internetowej, czy w grach po każdym ich restarcie. Byłoby to bardzo niewygodne i denerwujące. Rozwiązać problem zapisu ustawień aplikacji można na różne sposoby. Po co jednak się trudzić, skoro .NET daje nam to „za darmo” 😉

Plik ustawień aplikacji

Tak jak już wspomniałem .NET oferuje nam bardzo przyjemną formę zapisywania ustawień naszych programów. Są one przechowywane w formie pliku XML, który zapisywany jest domyślnie w lokalizacji C:\Users\Użytkownik\AppData\Local\NazwaAplikacji. Nowy plik ustawień jest generowany zawsze, kiedy zmienimy lokalizację pliku *.exe lub uruchomimy jego nowszą wersję. Oczywiście do takiej samej sytuacji dochodzi, kiedy aplikację uruchomi inny użytkownik – dzięki temu każdy może dysponować własnymi ustawieniami. Tyle teorii, jak używać tego mechanizmu w praktyce? Pisząc aplikację (czy to WPF, czy też Windows Forms) domyślnie w Solution Explore’rze odnajdziemy pozycję Properties -> Settings.settings. Jeżeli z jakiegoś powodu plik nie istnieje – można go po prostu dodać, klikając PPM na naszym rozwiązaniu i wybierając Add -> New Item -> Settings File. Po jego otwarciu powinien powitać nas taki widok:

settings

W tym miejscu możemy dodawać nowe elementy, które w istocie są właściwościami. Możemy wybrać ich typ (int, string, bool, itd) oraz ustawić ich wartość domyślną. Oprócz tego można zdefiniować, czy dane ustawienie ma być tylko do odczytu (scope: application), czy też ma być modyfikowalne (scope: user). W ramach testu dodajmy tutaj sobie dwa elementy o nazwach: WindowHeight oraz WindowWidth – typu double. Oczywiście nie mają być „tylko do odczytu” 😉

Odczytywanie i zapisywanie ustawień

Odczytywanie ustawień jest banalnie proste. Przedstawię to na przykładzie aplikacji WPF. Poniższy kod ustawi rozmiar okna uruchamianej aplikacji na taki, jaki jest przechowany w pliku z ustawieniami:

Tylko tyle… Jak widać to naprawdę proste 😉

Co do zapisywania ustawień wygląda to bardzo podobnie, jedyną różnicą jest konieczność wywołania metody Save(), która zapisze zmienione ustawienia do pliku. Oczywiście zapisu najlepiej dokonywać kiedy aplikacja jest zamykana:

Czasami przydatna jest też wiedza, gdzie konkretnie znajduje się plik z naszymi ustawieniami. Możemy uzyskać jego ścieżkę wykonując taki oto kod:

Do jego działania niezbędne jest dodanie referencji do przestrzeni nazw System.Configuration.

Dynamiczne dodawanie ustawień

W tym momencie mógłbym zakończyć ten wpis. Jednak pisząc mojego Cleaner’a napotkałem na problem z dynamicznym dodawaniem nowych ustawień. Ustawienia musiały być w nim tworzone na bieżąco z uwagi na obecność pluginów. Nie mogę przecież dodać na sztywno pozycji do pliku Settings.settings, kiedy nie wiem ile i jakich pozycji potrzebuję. Oczywiście i ten problem da się rozwiązać. Wystarczy dodawać nowe ustawienia z poziomu kodu:

Nadmienię jeszcze, że aby można dodać w ten sposób nowe elementy, musimy „dopisać” przynajmniej jeden element bezpośrednio do pliku Settings, w innym przypadku uraczy nas swoją obecnością wyjątek. W dużym uproszczeniu będzie chodzić (z tego co pamiętam) o to, że próbujemy dodać nowy element do nieistniejącej kolekcji. Teoretycznie można to rozwiązać z poziomu kodu, jednak znacznie prościej jest po prostu wrzucić tam jakieś (nawet puste) ustawienie.

Po wykonaniu takiego kodu zostanie dodana do pliku z ustawieniami nowa pozycja o nazwie „Text”, typu string i wartości „a”. Tylko jak ją teraz odczytać? Teoretycznie tak:

W praktyce jednak kod ten będzie działał tylko do ponownego uruchomieniu programu. Dlaczego? Wydaje mi się, że po prostu metoda ta szuka ustawienia o takiej nazwie w pliku Settings.settings, zamiast w wyjściowym pliku config aplikacji. Problem w tym, że nasze ustawienie po restarcie programu istnieć będzie tylko w pliku config, a w Settings.settings nie będzie po nim śladu 😉 Jednakże temu też da się zaradzić. Można po prostu odczytać lokalizację naszego configa, który w istocie jest plikiem xml i odczytać go właśnie w ten sposób:

Używam przy tym prostej klasy przeznaczonej do tego zadania:

Należy zwrócić szczególną uwagę na linijkę: XmlNodeList Shops = XmlDoc.SelectNodes(„//userSettings//WpfApplication1.Properties.Settings//setting[@name = ‚” + Name + „‚]//value”); Wszystkie nazwy muszą się zgadzać. Tj. nazwa aplikacji, oraz pliku ustawień. Czemu zmienna nazywa się Shops? Nie pytajcie… Powiedzmy, że to kod z recyklingu – właśnie teraz to zauważyłem 😉

Jeżeli ktoś ma jakieś niejasności co do działania tej klasy to zachęcam do przejrzenia tego wpisu dotyczącego odczytywania plików xml, tam wszystko jest w miarę jasno wyjaśnione.

Cóż… to byłoby chyba na tyle. Jeżeli macie jakieś uwagi/pytania to jak zwykle zachęcam do komentowania 🙂

892 total views, 1 views today