logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C#] Jak zapisać tablicę string[,] w Settings File aplikacji?

LED5W 22 Maj 2010 18:48 3668 24
REKLAMA
  • #1 8106276
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Witam
    Mam jedno pytanie. Używam "Settings File" do zapisywania ustawień aplikacji. Czy da się w tym zapisać tablicę string[,]? Próbowałem rzutować ją na object, ale nic się nie zapisuje.
    Fragment kodu:
    Settings1.Default.Folders = (object)Folders;
    Settings1.Default.Save();
    gdzie:
    - Settings1.Default.Folders to object
    - Folders - string[,]
  • REKLAMA
  • Pomocny post
    #2 8106388
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Najprościej będzie przejść po tablicy i zapisywać jej pojedyncze elementy. Aczkolwiek chyba jest coś takiego, jak serializacja zmiennych. Ale na .NET to ja się nie znam :(
  • REKLAMA
  • #3 8110677
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Dzięki za podpowiedź.
    Serializacja w C# jest, tylko nie wiem jak ją połączyć z tym "Settings".
    Bardzo proszę osobę znającą C# o odpowiedź.
  • Pomocny post
    #4 8110758
    Dżyszla
    Poziom 42  
    Posty: 7077
    Pomógł: 1095
    Ocena: 226
    Z tego co doczytałem, to sprawa wyglada tak (będę posługiwał się zapisem Delphi):
    1. Tworzysz strumień plikowy (FileStream.Create)
    2. Tworzysz obiekt serializacji (np. SoapFormatter.Create z System.Runtime.Serialization.Formatters.Soap).
    3. Wykonujesz metodę Serialize podając strumień plikowy i obiekt (tablicę).

    Serializowana klasa (a więc tablica chyba powinna znajdować się w klasie) musi dodatkowo implementować interfejs ISerializable).

    Proszę traktować te uwagi sceptycznie. Jak coś się uda na tej podstawie wyczaić - to dobrze ;)
  • REKLAMA
  • #5 8111035
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Dżyszla napisał:
    1. Tworzysz strumień plikowy (FileStream.Create)

    I tu się zaczyna problem, bo jeżeli strumień plikowy to musi być plik. ;)
    Do zapisu ustawień wykorzystuję gotową klasę, która obsługuje zapis/odczyt zmiennych do pliku xml (chociaż nawet nie wiem jak - w programie - sprawdzić gdzie ten plik jest).
    Robi się to tak:
    Settings1.Default.Name = textBox1.text // Name to string (można to sobie zdefiniować na stronie konfiguracji obiektu Settings1)
    więc trzeba by chyba wyserializować(?) to do stringa. Może spróbuję najpierw na strumień, a strumień do stringa, ale czy to coś da...
    :|

    Dodano po 8 [minuty]:

    LED5W napisał:
    Może spróbuję najpierw na strumień, a strumień do stringa, ale czy to coś da...
    Tak się nie da... :(
  • Pomocny post
    #7 8111634
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Nie wiem czy plik Settings może przechowywać tablicę, bo w opcjach typu pola nie ma takowej, jest natomiast kolekcja stringów. Zdefiniuj Folder jako System.Collecions.Specialized.StringCollection, a będziesz mógł zrobić tak:

             string[] tabl_stringow = new string[5];
    			tabl_stringow[0] = "aaa";
    			tabl_stringow[1] = "bbb";
    			tabl_stringow[2] = "ccc";
    			tabl_stringow[3] = "ddd";
    			tabl_stringow[4] = "eee";
    
    			System.Collections.Specialized.StringCollection myCol = new System.Collections.Specialized.StringCollection();
    			myCol.AddRange(tabl_stringow);
    
    			Settings1.Default.Folder = myCol;
    			Settings1.Default.Save();
    
    			
    			MessageBox.Show(Settings1.Default.Folder[1].ToString());

    Pozdrawiam
  • #8 8113451
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    marcinj12 Wszystko fajnie, ładnie, tylko taki szczegół, że mi chodziło o tablicę dwuwymiarową. Jej się chyba tutaj nie da "wcisnąć"?
  • Pomocny post
    #9 8113502
    marcinj12
    Poziom 40  
    Posty: 3404
    Pomógł: 1024
    Ocena: 250
    Jedyne co mi przychodzi do głowy to jeden wymiar - wspomniana kolekcja, i tyle "zmiennych" ile drugi wymiar np. Folder_1 = (.....), Folder_2 = (....)

    Ewentualnie każdy wymiar tablicy możesz rozdzielić jakimś separatorem, np. # tak żeby stworzyły jeden ciąg znaków, a po odczytaniu - w drugą stronę, rozdzielić po # i wpisać do tablicy.

    Albo zapisuj te dane do pliku tekstowego jak ich masz dużo, w końcu plik z ustawieniami raczej został zaprojektowany do przechowywania pojedynczych wartości.
  • #10 8124314
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    To już chyba lepiej zrobić tak jak napisał Dżyszla...
  • #11 8124353
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    Możesz to zrobić tylko na piechotę, bo generalnie ta klasa do tego nie służy... wygląda to, jak próba złapania komara obcęgami za lewe wiesz co ;) Settings, czyli ogólnie pliki INI, mają konstrukcję NAZWA = WARTOŚĆ - a Ty chcesz dwuwymiarową tablicę tu wcisnąć ;)
  • #12 8124457
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    utak3r napisał:
    Settings, czyli ogólnie pliki INI, mają konstrukcję NAZWA = WARTOŚĆ - a Ty chcesz dwuwymiarową tablicę tu wcisnąć ;)
    INI sobie wymyślił... Settings wykorzystuje pliki o rozszerzeniu config i formatowanie xml.
  • #13 8125056
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    a w xmlu myślisz, że coś innego dostajesz tak naprawdę?...

    
    <ustawienia>
    <globalne>
    <pliki nazwa="abcd" sciezka="gdzies" rozmiar="5"/>
    </globalne>
    </ustawienia>
    


    Tak czy inaczej - do zapisu tablicy się to nie nadaje. Nie - że XML się nie nadaje, tylko Settings - czego masz zresztą przykład, jak widać w postach powyżej.
  • #14 8125264
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    utak3r napisał:
    a w xmlu myślisz, że coś innego dostajesz tak naprawdę?...
    W ini nie ma znaczników, więc taką kombinację jak np. sam niżej napisałeś trudniej będzie zrobić (gdy jest wiele elementów zagnieżdżonych).
  • Pomocny post
    #15 8125350
    utak3r
    Poziom 25  
    Posty: 741
    Pomógł: 60
    Ocena: 5
    Prawda, że w xmlu dostajemy więcej możliwości - dlatego też zostały te pliki wprowadzone :) W INI mieliśmy tylko jednopoziomowe sekcje - tutaj możemy schodzić sobie drzewiaście w dół...

    Niemniej, wracając do meritum - wciąż ma to swoje ograniczenia. Zawsze możesz stworzyć pliki binarne i za pomocą serializacji zrzucać tam dowolne swoje obiekty :) Choćby całe struktury czy nawet bardziej skomplikowane obiekty.
  • #16 8134634
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Jeszcze mam takie jedno pytanie z ciekawości:
    Jak sprawdzić, gdzie zapisuje się ten plik user.config?
    Znajduje się on w
    C:\Documents and Settings\Nazwa użytkownika\Ustawienia lokalne\Dane aplikacji\Nazwa projektu\Nazwa projektu.v_Url_32losoweznaki\1.0.0.0
  • #17 8172561
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Jestem zmuszony użyć serializacji i mam z tym problem.
    Plik tworzę tak:
            Sync sync = new Sync();
            XmlSerializer syncSerializer = new XmlSerializer(typeof(Sync));
    [...]
                    StreamWriter syncWriter = new StreamWriter(settingsFilePath + "\\user.config");
                    syncSerializer.Serialize(syncWriter, sync);


    Klasa do wyserializowania:
        [XmlRoot]
        public class Sync
        {
            [XmlElement]
            List<GroupOfSyncFolders> Groups = new List<GroupOfSyncFolders>();
    
            [XmlElement]
            OptionsOfComparingFiles DefaultOptions = new OptionsOfComparingFiles();
        }

    Wynik:
    <?xml version="1.0" encoding="utf-8"?>
    <Sync xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />


    Co robię źle?

    Czy elementom klasy OptionsOfComparingFiles też muszę przypisywać odp. atrybut?
  • REKLAMA
  • Pomocny post
    #18 8173704
    x3r
    Poziom 18  
    Posty: 126
    Pomógł: 32
    Ocena: 2
    W klasie, której obiekty będą serializowane nie musisz nawet dawać znaczników XmlElement ponieważ samo oznaczenie jej jako XmlRoot spowoduje że domyślnie serializowane będzie każde publiczne property. Ale do meritum:

    :arrow: Oznaczyłeś elementy klasy jako prywatne (domyślny modyfikator) a żeby podlegały serializacji muszą być publiczne

    :arrow: Klasy GroupOfSyncFolders oraz OptionsOfComparingFiles musisz oznaczyć jako XmlRoot

    W razie wątpliwości możesz sprawdzić przykładowy kod który kiedyś napisałem do celów dydaktycznych Serializacja

    pozdrawiam
  • #19 8174295
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    x3r napisał:
    W klasie, której obiekty będą serializowane nie musisz nawet dawać znaczników XmlElement ponieważ samo oznaczenie jej jako XmlRoot spowoduje że domyślnie serializowane będzie każde publiczne property.
    W takim razie jak wykluczyć wybrane elementy z serializacji?

    x3r napisał:
    :arrow: Oznaczyłeś elementy klasy jako prywatne (domyślny modyfikator) a żeby podlegały serializacji muszą być publiczne
    Aaa. Ustawiłem tak, bo miałem 1 błąd. Teraz się skapnąłem o co chodzi. :)

    x3r napisał:
    W razie wątpliwości możesz sprawdzić przykładowy kod który kiedyś napisałem do celów dydaktycznych Serializacja
    O, ten projekt przeglądałem.

    Ogólnie to mam 4 swoje klasy i zrobione z nich takie drzewko i się w nim pogubiłem. Teraz już działa.

    Dziękuję bardzo.
  • Pomocny post
    #20 8175775
    x3r
    Poziom 18  
    Posty: 126
    Pomógł: 32
    Ocena: 2
    LED5W napisał:
    W takim razie jak wykluczyć wybrane elementy z serializacji

    Musisz oznaczyć pole atrybutem XmlIgnore.

    pozdrawiam
  • #21 8175921
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    No tak. Im starszy jestem tym głupsze pytania zadaje. :P

    A może przypadkiem znasz odpowiedź na pytanie parę postów wyżej <tutaj>?
  • #22 8185040
    x3r
    Poziom 18  
    Posty: 126
    Pomógł: 32
    Ocena: 2
    LED5W napisał:
    A może przypadkiem znasz odpowiedź na pytanie parę postów wyżej <tutaj>?


    Nie bardzo rozumiem to pytanie. Plik user.config to ten plik który sam tworzysz (do którego serializujesz swoje obiekty)?
  • #23 8186524
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    Gdy dodamy do projektu (przez "Add New Item") "Settings File" to po uruchomieniu programu powstanie plik user.config we wspomnianym wyżej folderze. Ino jak ten folder odnaleźć w programie?
  • Pomocny post
    #24 8186649
    x3r
    Poziom 18  
    Posty: 126
    Pomógł: 32
    Ocena: 2
    Dodaj referencję na System.Configuratiion a potem:

    
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
    string path = config.FilePath;
    


    Btw, jesteś świadom tego że podczas serializacji obiektów którą wykonujesz nie potrzebujesz config-a generowanego przez Settings-y? Jeżeli tak i przechowujesz ustawienia w dwóch miejscach (część w Settings a część we własnym xml-u) to powinieneś wybrać jeden sposób przechowywania ustawień i się go trzymać.

    pozdrawiam
  • #25 8187372
    LED5W
    Poziom 34  
    Posty: 2302
    Pomógł: 264
    Ocena: 162
    x3r napisał:
    Btw, jesteś świadom tego że podczas serializacji obiektów którą wykonujesz nie potrzebujesz config-a generowanego przez Settings-y? Jeżeli tak i przechowujesz ustawienia w dwóch miejscach (część w Settings a część we własnym xml-u) to powinieneś wybrać jeden sposób przechowywania ustawień i się go trzymać.
    Jako, że potrzebuję zapisywać listy w ustawieniach zdecydowałem się na "ręczną" serializację i oczywiście wiem, że mi ten settings nie jest potrzebny - tak jak wcześniej pisałem - pytanie z ciekawości. A tak w ogóle to ta ścieżka jest zapisana tylko w exe, czy jeszcze gdzieś indziej?

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik pyta, jak zapisać dwuwymiarową tablicę string[,] w pliku ustawień aplikacji w C#. Odpowiedzi sugerują, że bezpośrednie zapisanie tablicy w pliku ustawień jest niemożliwe, ponieważ klasa Settings nie obsługuje tablic. Proponowane rozwiązania obejmują serializację tablicy do formatu string, użycie kolekcji System.Collections.Specialized.StringCollection lub zapisanie danych do pliku tekstowego. Użytkownicy podkreślają, że pliki ustawień są zaprojektowane do przechowywania pojedynczych wartości, a nie złożonych struktur danych. Dodatkowo, poruszono temat lokalizacji pliku user.config oraz możliwości serializacji obiektów w XML.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA