Posts Tagged ‘C#’

Jak w projekcie skorzystać z bazy SQLite

Author: Krzysztof Wawoczny (Krzysztof Wawoczny) | kwiecień 27th, 2010

Zazwyczaj w tworzonych projektach trzeba korzystać z bazy danych, wybór konkretnej zależy od rodzaju projektu – dla ćwiczebnych aplikacji, polecam SQLite. Cała konfiguracja nie powinna zająć więcej czasu niż ugotowanie jajek.

Po pierwsze należy ściągnąć i zainstalować pakiet ADO.NET z http://sqlite.phxsoftware.com/ (lub skorzystać z innego ;))

Po drugie do projektu dodajemy referencję do System.Data.SQLite z pakietu ADO.NET (kopiujemy do katalogu System.Data.SQLite.dll)

Po trzecie dodajemy do projektu plik *.config (opis na http://msdn.microsoft.com/en-us/library/ms184658%28VS.80%29.aspx) oraz w pliku *.config wpisujemy:



  
    
      
      
    
  

Po czwarte należy wyposażyć się w jakiegoś managera bazy danych, polecam wtyczkę do przeglądarki firefox http://code.google.com/p/sqlite-manager/

Po piąte wyklikujemy prostą bazę danych

Po szóste – gotowe ; )

Teraz test naszej bazy:

      DbProviderFactory fact = DbProviderFactories.GetFactory("System.Data.SQLite");
      using (DbConnection cnn = fact.CreateConnection())
      {
        cnn.ConnectionString = "Data Source=test.db3";
        cnn.Open();
      }

Jeśli nie dostaliśmy żadnego błędu to cała konfiguracja przebiegła pomyślnie.

Najprostszy sposób na zalogowanie użytkownika

Author: Krzysztof Wawoczny (Krzysztof Wawoczny) | kwiecień 26th, 2010

Obecnie, w niemal każdej aplikacji biznesowej wymagane jest zalogowanie się, by w pełni móc korzystać z możliwości, jakie taka aplikacja daje, lub by wogóle móc cokolwiek zrobić. Jakiś czas temu zrobiłem krótki research po sieci w poszukiwaniu jakiegoś sprytniejszego rozwiązania niż to, które używam w swoich aplikacjach. Cóż… Dziwni są ludzie, którzy zatrudniają do obrony swojego zamku legiony, a pozwalają do niej wejść zwykłym OR 1=1 (to tak na marginesie), nie rozumię też rozwiązania, które zostało pozytywnie ocenione na jednym z for programistycznych, a wygląda ono tak:
W aplikacji sprawdzamy, czy ustawiony jest w bazie znacznik informujący o zalogowaniu, jeśli nie, to po zalogowaniu generujemy go, a usuwamy, gdy użytkownik zamknie aplikację… A co, jeśli zwiesi się komp, zabraknie prądu albo wydarzy się coś innego? Przecież po wystąpieniu tak nieoczekiwanego zdarzenia wartość w bazie może się nie zmienić, a wtedy każdy, kto skorzysta z komputera będzie zalogowany. Naprawdę nie rozumię wielu tych wielkich idei, dlatego na razie nadal korzystam z bardzo prostego rozwiązania, które wygląda następująco:

W aplikacji w sekcji odpowiedzialnej za przechowanie predefiniowanych zmiennych globalnych (jak np. nazwa bazy, string wyświetlany w górnej belce aplikacji etc.) ustawiam sobie zmienną, określającą, czy użytkownik jest zalogowany (domyślnie ustawioną na false) oraz metodę pozwalającą zmienić wartość tej zmiennej:

public class GlobalAppVariables
{
    /// Globalna zmienna, której wartość jest ustwaiona na 1, gdy użytkownik się zaloguje.
    static int _logged = 0;

    /// Dostęp/zmiana wartości globalnej zmiennej _logged
    public static int Logged
    {
      get
      {
        return _logged;
      }
      set
      {
        _logged = value;
      }
    }
}

Samo logowanie polega na wywołaniu metody, która połączy się z bazą, sprawdzi, czy dla podanych parametrów istnieje wpis i na tej podstawie zwróci wynik pozytywny/negatywny, co z kolei pozwoli mi ustawić wartość zmiennej _logged w następujący sposób:

private void button1_Click(object sender, EventArgs e)
{
    object result = Queries.StartSession(this.loginTxt.Text, this.PasswordTxt.Text);
   //Queries to osobna klasa, w której przechowywane są metody odpowiedzialne za operacje na bazie
    if (result != null)
    {
        this.Close(); //zamknięcie okna logowania
        GlobalAppVariables.Logged = 1; // w tej chwili wiem, że już mam zalogowanego użytkownika
    }
    else
    {
       //info o nieudanym logowaniu
    }
}

Jeśli już mam zalogowanego użytkownika, mogę odblokować domyślnie wyłączone opcje, lub zrobić coś innego.
Jeśli nie potrzebujesz wymyślnego systemu logowania skorzystaj z przedstawionego sposobu. Jest on wystarczający dla wielu nieskomplikowanych aplikacji. AVE!

Dynamiczne generowanie kontrolek

Author: Krzysztof Wawoczny (Krzysztof Wawoczny) | kwiecień 24th, 2010

W czasie pracy nad swoim małym projektem w C#, stanąłem przed problemem dynamicznego generowania kontrolek na formie. Nie chciałem, aby cały kod za to odpowiedzialny znajdował się w zdarzeniu kliknięcia w button, wiec stworzyłem przykładową klasę, którą nazwałem ControlGenerator.
klasa
Generalnie, trzeba by ją jakoś połączyć z główną formą aplikacji (w projekcie Form1 – standardowe nazewnictwo, gdyż więcej form nie przewiduję). W klasie ControlGenerator utworzyłem zmienną typu Form1 służącą za łącznik klasa – forma:

public class ControlGenerator
{
    /// Prywatna zmienna typu Form1
    private Form1 pf;
   //...
}

Następnie, konstruktor klasy musi posiadać takie przypisanie zmienej pf, aby wskazywała ona na referencję instancji mojej Form1 (trochę to może zamieszane, więc kawałek kodu wyjaśni, co miałem na myśli):

public ControlGenerator(Form1 f1)
{
  pf = f1;
}

Tak właśnie wygląda konstruktor, o którym była mowa, a jak to wygląda ‘na żywo’ jest ukazane poniżej.

W formie głównej aplikacji (Form1) po kliknięciu w jeden z przycisków powinny wygenerować się kontrolki, inicjuję więc obiekt klasy ControlGenerator w następujący sposób:

private void button1_Click(object sender, EventArgs e)
{
    ControlGenerator generate = new ControlGenerator(this);
   // właśnie tu do konstruktora przekazuje referencję do Form1 za pomocą this
}

Skoro moje połączenie klasa – forma jest już aktywne, to pora napisać metodę generującą kontrolki. Do owej metody powinna być przekazana informacja jak wiele kontrolek utworzyć. W poniższym przykładzie ograniczę się do wygenerowania TextBoxów z Labelkami zawartymi w GroupBoxie (które mogą być oczywiście dodatkowo osadzone na jakimś panelu, czy czymkolwiek się chce).
Gotowa funkcja prezentuje się następująco:

    public void GenerateRegisterControls(int number, string text)
    {
      int[] textboxes = new int[number];
      string[] labels = { "Imię", "Nazwisko", "PESEL", "Ulica", "Numer budynku",
                              "Miasto", "Kod pocztowy", "Województwo", "Telefon" };
      int i = 0, move = 0;

      //tworzę GroupBoxa, do którego wrzucę tworzone kontrolki (opis metody w następnym listingu)
      GroupBox box = GenerateGroupBoxControl(text); 

      foreach (int element in textboxes)
      {
        TextBox textbox = new TextBox(); //tworzę nowego TextBoxa
        Label label = new Label(); //tworzę nowy Label
        //lokalizacja TextBoxa
        textbox.Location = new System.Drawing.Point(200, 70 + move);
        textbox.Name = "textbox" + i.ToString();
        textbox.Size = new System.Drawing.Size(360, 20 + move); //wymiary TextBoxa
        //Rozmiar czcionki w TextBoxie - funkcja nie zostanie przedstawiona
        //w tym wpisie
        textbox.Font = SetFontForElement(40, textbox.Font);
        textbox.TabIndex = i;
        textbox.Visible = true;
        //automatyczna zmiana rozmiarów TextBoxa przy zmianie rozmiaru okna
        textbox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
        textbox.BorderStyle = BorderStyle.FixedSingle; //styl ramki
        //lokalizacja Labela
        label.Location = new System.Drawing.Point(20, 80 + move);
        label.Name = "label" + i.ToString();
        //nazwa Labela wzięta z wcześniej utworzonej tablicy stringów
        label.Text = labels[i];
        label.Font = SetFontForElement(28, label.Font);
        label.Size = new System.Drawing.Size(160, 28);
        label.Visible = true;

        box.Controls.Add(textbox); //dodaję do GroupBoxa utworzone TextBoxy
        box.Controls.Add(label); //dodaję do GroupBoxa utworzone Labele

        i++;
        move += 50;
      }
      //dodaję GroupBoxa z kontrolkami do panelu w kontenerze Form1
      pf.splitContainer1.Panel2.Controls.Add(box);
    }

Jak widać funkcja nie jest specjalnie skomplikowana, a tablicę z nazwami labelek można by przekazać jako parametr – jednak nie ma potrzeby w tym wpisie rozmieniać się na drobne. Tworzenie TextBoxów i Labelek można by dodatkowo zostawić osobnym funkcjom wywołanym w GenerateRegisterControls, jak np. GenerateGroupBoxControl, która wygląda następująco:

    private GroupBox GenerateGroupBoxControl(string text)
    {
      GroupBox box = new GroupBox();

      box.Name = "GroupBoxRegister";
      box.Text = text;
      box.Location = new System.Drawing.Point(1, 9);
      box.Size = new System.Drawing.Size(pf.splitContainer1.Panel2.Width - 20, pf.splitContainer1.Panel2.Height - 20);
      box.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;

      return box;
    }

Samo wygenerowanie kontrolek po kliknięciu w jeden z przycisków wygląda następująco:

    private void button1_Click(object sender, EventArgs e)
    {
      ControlGenerator generate = new ControlGenerator(this);
      //9 TextBoxów i 9 Labelek, GroupBox będzie opatrzony tekstem Rejestracja
      generate.GenerateRegisterControls(9, "Rejestracja");
    }

Efekt:
efekt

Jeśli ktoś dopiero zaczyna swoją przygodę z C#, to informacje, które przedstawiłem z pewnością się przydadzą, albo przynajmniej wskażą drogę poszukiwań w google. AVE!

Pobranie parametrów metody w C# wraz z wartościami

Author: Mateusz Kubiczek (madmatt) | październik 12th, 2009

Dosyć długo szukałem w jaki sposób pobrać nazwy parametrów metody wraz z ich wartościami w sposób uniwersalny.

Ułatwiłoby to logowanie wszystkiego, co zachodzi w aplikacji. Wywołując metodę:

public void CountPrice(int bar, string baz)
{

}

chciałbym otrzymać w logach wpis:

Method’s Foo arguments >> bar: 1, baz: zzz

(więcej…)