sâmbătă, 26 martie 2016

C#19 Menu, dialoguri predefinite

Dialogurile predefinite sunt forme standardizate de dialog,  incorporate in .NET, care pot fi inglobate in aplicatia noastra. Exemple de dialoguri predefinite sunt dialogul OpenFile, SaveFile, FontColor, PrintDialog, etc. Ele vor functiona in applicatia noastra in exact aceeasi maniera ca si in Word sau Paint, de exemplu.

Vom face o aplicatie care utilizeaza un meniu si cateva dialoguri predefinite, prilej cu care vom lucra cu cateva dintre  metodele si proprietatile membru ale acestor controale.  Celelalte metode si proprietati se pot descoperi cu ajutorul help-ului mediului de programare.
Deschidem un proiect nou, pe care il denumim DialoguriPredefinite. Tragem pe suprafata formei Form1 un control de tipul MenuStrip. Facand click pe suprafata acestui control, el se expandeaza in jos si la dreapta, creand poziti pentru noi itemi. Vom crea doua meniuri  pe bara de meniu: Fisier si Format. Sub meniul Fisier vom crea alti  trei itemi: Deschide, Salveaza  si Iesire.  Sub meniul Format cream itemul Font si itemul Color. Vom crea pentru fiecare item in parte dialogul aferent,  insa nu vom executa efectiv si operatiile de deschidere si salvare de fisier.

Adăugăm formei dialogurile predefinite, prin drag&drop de la panoul Toolbox către suprafața formei. Observăm că dialogurile trase nu sunt localizate vizual pe suprafața formei, dar ele sunt înglobate. Sunt create obiectele aferente, cu numere de ordine începând cu 1. Vom avea astfel un obiect openFileDialog1, care are proprietăți ca Title, Filter, etc, a căror utilizare se va vedea mai jos.

Pentru tratarea evenimentului Click asupra unui item de meniu, facem dublu click pe acel item.

Meniul Deschide fisier

Introducem acest cod in handlerul evenimentului click:

        private void deschideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //titlul dialogului
            openFileDialog1.Title = "Deschide fisier";
            // seteaza tipurille de fisier
            openFileDialog1.Filter = "Fisiere text |*.txt| fisiere doc|*.doc|fisiere docx |*.docx";
            //in comboBox-ul File name nu vrem sa apara la deschiderea dialogului nici un nume
            openFileDialog1.FileName = "";
            //directorul care se deschide in mod implicit
            openFileDialog1.InitialDirectory = "MyDocuments";
            //atentionare daca numele nu exista
            openFileDialog1.CheckFileExists = true;
            //deschide dialogul OpennFileDialog
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            { //cod care deschide fisierul
            }
        }


Filtrul pentru deschiderea fisierului are  sintaxa urmatoare: explicatie | filtru |explicatie | filtru ...etc.

In mod asemanator, introducem handlerele petru click in celelalte optiuni ale meniului.
Aplicatia va arata in felul urmator:

namespace DialoguriPredefinite
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void deschideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //titlul dialogului
            openFileDialog1.Title = "Deschide fisier";
            // seteaza tipurille de fisier
            openFileDialog1.Filter = "Fisiere text |*.txt| fisiere doc|*.doc|fisiere docx |*.docx";
            //in comboBox-ul File name nu vrem sa apara la deschiderea dialogului nici un nume
            openFileDialog1.FileName = "";
            //directorul care se deschide in mod implicit
            openFileDialog1.InitialDirectory = "Desktop";
            //atentionare daca numele nu exista
            openFileDialog1.CheckFileExists = true;
            //deschide dialogul OpennFileDialog
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            { //cod care deschide fisierul
            }
        }


        private void salveazăCaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //titlul dialogului
            saveFileDialog1.Title = "salveaza fisierul";
            //extensia implicita de salvare
            saveFileDialog1.DefaultExt = ".txt";
            //atentionare de suprascriere
            saveFileDialog1.OverwritePrompt = true;
            //deschide dialogul de salvare fisier
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            { //cod care salveaza fisierul
            }
        }


        private void iesireToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void fontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // se deschide dialogul font
            if (fontDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            { //cod care reafiseaza documentul cu fontul ales de utilizator
            }
        }
        private void culoriToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //deschide dialogul ColorDialog
            if(colorDialog1.ShowDialog()==System.Windows.Forms.DialogResult.OK)
            {
                //cod care actualizeaza culorile in document
            }
        }
    }
}


duminică, 13 martie 2016

C#18 Forme, Dialoguri modale și nemodale

Crearea formelor la run time

O formă este un tip de control care reprezintă o fereastră. Este folosită ca suport pentru alte controale.
Crearea prin program a formelor:
                         
                            Form f = new Form();
                            f.Show();

sau se poate defini o clasa derivata din clasa Form:

                            class FormaMea:Form
                            {
                                public FormaMea() //constructorul
                                {
                                }
                                 // alti membri ai clasei (campuri, proprietati,metode)
                            }

Dintr-o alta metod a aplicatiei se face instantierea:

                             FormaMea f=new FormaMea();
                             f.Show();

Aplicatie de tipul consola care crează și deschide o fereasta la run-time.

  • Creăm un proiect nou, de tipul Console Application, Empty Project. Punem un nume proiectului, de pilda DialogModal. Facem click dreapta in Solution Explorer pe numele proiectului si alegem Add, apoi New Item.
  • In dialogul Add New Item selectam iconul Code File, apoi in caseta Name introducem numele fisierului: de exemplu Modal.cs.
  • Fisierul Modal.cs se deschide in editorul de cod.
  • Adaugam proiectului  referinte catre spatiile de nume System, System.Windows, System.Windows.Form, in felul urmator:
  • Click dreapta pe References (in panoul  Solution Explorer) si alegem Add. Din dialogul care se deschide, selectam cele trei spatii de nume scrise mai sus cu bold.
Introducem codul de mai jos, compilam si rulam.

using System;
using System.Windows;
using System.Windows.Forms;
class Forma: Form
{

}
class Program
{
    public static void Main()
    {
        Forma f = new Forma(); // instantiere
        //textul din bara de titlu
        f.Text = "Dialog modal";
        //dialogul modal devine vizibil
        f.ShowDialog();
        //lanseaza aplicatia
        Application.Run();
    }
}


Dialogul modal și nemodal


Un dialog modal este o fereastră de dialog cu utilizatorul care blochează orice altă activitate în aplicație până când nu se închide ferestra cu close. De exemplu, dialogul Open File din MS Word.
O fereastră de dialog modal se afișeză cu metoda ShowDialog().

Dialogul nemodal este o fereastă de dialog care nu blochează restul aplicației. De exemplu, Toolbox-urile din Paint și Word. Un dialog nemodal se afișează cu metoda Show().

Aplicația ModalDialogExemplu

  • Construiește un dialog modal care se deschide la apăsarea unui buton al formei părinte
  • Datele introduse într-un control al dialogului sunt transferate unui control al formei părinte
  1. Creăm un proiect nou de tipul WindowsFormsApplication
  2. Plasăm pe formă cu mousul un ListBox și două butoane. Setăm proprietatea Text a celor două butoane pe valorile Adauga și respectiv Iesire.
  3. Adăugăm o nouă formă proiectului la design-time: în Solution Explorer  click dreapta pe numele proiectului, alegem Add, apoi Windows Form.
  4. În Solution Explorer dublu click pe numele Form2.
  5. Aducem din Toolbox pe Form2 un TextBox și un buton, inscriptionat cu Ok.
  6. În Solution explorer facem click pe numele Form2, alegem View Code si in clasa Form2 definim noii membri:
           //câmp care  reține textul introdus în TextBox1
           private string item;
           /*proprietate care  returneaza valoarea textului; reamintim ca o proprietate este un fel             de  metoda
           care permite tratatea campurilor private ca si cum ar fi publice, dar numai pentru doua
           genuri de operatii: set si get.
          */
           public string Item
           {
               get{return item;}
           }

Tratam evenimentul Click generat de apasarea butonului Ok: introducem codul de mai jos in metoda handler a evenimentului click al lui button1:

           item = textBox1.Trim();
           //inchidem forma Form2:
            Close();

         7. In Form1 introducem o referinta catre Form2:
                           
            private Form2 f; //aceasta declaratie se scrie in clasa Form1, din fisierul Form1.cs.

         8. Tratam evenimentul Click al butonului Adauga aflat pe Form1.
         9. Pentru iesirea din aplicatie tratam  evenimentul click al butonului Iesire:
                     Application.Exit();
       10. Compilam si rulam aplicatia.


Codul pentru Form1 este  urmatorul:

namespace DialogModalWFA
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        private Form2 f;

        private void button1_Click(object sender, EventArgs e)
        {
            //cream forma form2
            f = new Form2();
            //afisare dialog modal
            f.ShowDialog();
            if(f.Item!="") //daca exista text introdus
            {
                //adauga itemul in listBox1
                listBox1.Items.Add(f.Item);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}


Codul pentru obiectele din Form2:

namespace DialogModalWFA
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }
        // camp care  retine textul introdus in textBox1
        private string item;
        //proprietate get item
        public string Item
        {
            get
            {
                return item;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //salvam textul introdus in control
            item = textBox1.Text.Trim();
            //inchidem forma Form2
            Close();
        }
    }
}

De reținut:

  • Dialogurile modale se afișează cu metoda ShowDialog, iar cele  nemodale cu Show.
  • La închiderea cu Close un dialog nemodal se distruge (se distruge instanta clasei).
  • Un dialog modal nu este distrus la închiderea cu Close.  Câmpurile instanței rămân, iar forma poate fi reafișată. A se vedea accesul la câmpul f.Item după închiderea cu Close a formei Form2.
  • Codul care urmează lui ShowDialog nu se execută până când forma nu se închide. După închiderea  dialogului modal, putem referi în continuare clasa Form2 și membrii ei.
  • Întrebare: la o a doua apăsare a butonului Form1.Button1 se  creează o nouă instanță a formei Form2? Dacă da, ce se întâmplă cu cea veche? Cum mai poate fi accesată?

luni, 7 martie 2016

C#17 Controlul TextBox

Inițiem un proiect de tip WFA. Tragem în forma Form1 trei controale TextBox, pe care le așezăm unul sub altul. În stânga fiecărui TextBox tragem câte un control  Label. Sub ele așezăm un buton. Redenumim controalele din panoul Properties după cum urmează:

TextBox1  redenumim user
TextBox2  redenumim parola
RextBox3 redenumim cnp
Button1     inscripționăm cu textul  autentif

schimbam textul afisat de etichetele label în:

label1... user name
label2... password
label3... CNP

Schimbăm numele Form1 în LogOn.
Dorim ca la incarcarea formei să nu se vada controalele CNP și autentif, iar controlul parola să fie inactiv. Codul pentru aceasta se introduce în metoda constructor a formei. Tot aici punem și codul care maschează cu * parola introdusă. Pentru a accesa editorul de cod aferent constructorului,  facem dublu click pe formă. Noi scriem doar ce este cu Bold.

        public Form1() //constructorul formei
        {
            InitializeComponent();
            //caracterul * mascheaza parola
            parola.PasswordChar = '*';
            //campul parola initial dezactivat
            parola.Enabled = false;
            //campul cnp si butonul autentif initial invizibile
            label3.Visible = false;
            cnp.Visible = false;
            autentif.Visible = false;
        }

Dorim să permitem  logon doar utilizatorului Gogu. În practică, se utilizează o bază de date cu utilizatori, dar exemplul următor descrie metoda de principiu. Se utilizează metoda membru PreviewKeyDown. Navigarea între câmpuri se face cu tasta Tab, nu enter. Se poate testa însă opțional/alternativ  și Enter.

        private void user_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            //daca tasta apasata este Tab
            if (e.KeyCode == Keys.Tab)
                if (user.Text == "Gogu")
                    //user corect, activare camp parola
                    parola.Enabled = true;
                else
                    MessageBox.Show("user incorect");

        }

Verificăm introducerea parolei. Vom verifica dacă s-a introdus textul "parolaMea". În practică nu se folosește această  metodă statică de verificare, în care valoarea parolei este fixată în sursa programului, deoarece este vulnerabilă la decodificare și în plus nu se permite schimbarea parolei.
dacă parola este corectă, se activează controlul cnp și autentif.
Metoda Focus selectează un control   pentru a primi intrare de date. Selectarea se poate face manual cu mous-ul, cu săgețile, cu Tab sau prin program. Mai jos se focusează prin program. Ordinea implicită de selecție a controalelor este ordinea adăugării lor pe formă, dar se poate schimba din meniul View, TabIndex.

        private void parola_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            //daca tasta apasata este Enter
            if (e.KeyCode == Keys.Enter)
                //daca s-a introdus textul "parolaMea"
                if (parola.Text == "parolaMea")
                {
                    //controlul CNP devine vizibil
                    label3.Visible = true;
                    cnp.Visible = true;
                    //controlul CNP primeste focusul
                    cnp.Focus();
                    //butonul autentif devine vizibil
                    autentif.Visible = true;
                }
            else
                {
                    MessageBox.Show("Parola incorecta");
                    //sterge textul introdus
                    parola.Clear();
                }

        }

Pentru verificarea CNP-ului dorim să impunem două restricții: să conțină numai cifre, și să fie de lungime fix 13 caractere. În practică se folosește un algoritm de verificare a cifrelor de control. Ultimele 4 caractere din CNP sunt cifre de control, restul conțin data nașterii, codul sexului, codul județului.

        private void cnp_KeyPress(object sender, KeyPressEventArgs e)
        {
            //daca nu e cifra, nu se proceseaza
            if (e.KeyChar < 0x30 || e.KeyChar > 0x39)
                e.Handled = true;

        }

Evenimentul Click al butonului autentif verifică dacă cnp-ul are 13 cifre.

        private void autentif_Click(object sender, EventArgs e)
        {
            //daca lungime CNP <>13
            if (cnp.Text.Length != 13)
            {
                MessageBox.Show("CNP eronat");
                //sterge textul introdus
                cnp.Clear();
            }
            else
                MessageBox.Show("Autentificare cu succes");
        }

    }

Programul complet este următorul:

namespace LogOn
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //caracterul * mascheaza parola
            parola.PasswordChar = '*';
            //campul parola initial dezactivat
            parola.Enabled = false;
            //campul cnp si butonul autentif initial invizibile
            label3.Visible = false;
            cnp.Visible = false;
            autentif.Visible = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void user_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            //daca tasta apasata este Tab
            if (e.KeyCode == Keys.Tab)
                if (user.Text == "Gogu")
                    //user corect, activare camp parola
                    parola.Enabled = true;
                else
                    MessageBox.Show("user incorect");
        }

        private void parola_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            //daca tasta apasata este Enter
            if (e.KeyCode == Keys.Enter)
                //daca s-a introdus textul "parolaMea"
                if (parola.Text == "parolaMea")
                {
                    //controlul CNP devine vizibil
                    label3.Visible = true;
                    cnp.Visible = true;
                    //controlul CNP primeste focusul
                    cnp.Focus();
                    //butonul autentif devine vizibil
                    autentif.Visible = true;
                }
            else
                {
                    MessageBox.Show("Parola incorecta");
                    //sterge textul introdus
                    parola.Clear();
                }
        }

        private void cnp_KeyPress(object sender, KeyPressEventArgs e)
        {
            //daca nu e cifra, nu se proceseaza
            if (e.KeyChar < 0x30 || e.KeyChar > 0x39)
                e.Handled = true;
        }

        private void autentif_Click(object sender, EventArgs e)
        {
            //daca lungime CNP <>13
            if (cnp.Text.Length != 13)
            {
                MessageBox.Show("CNP eronat");
                //sterge textul introdus
                cnp.Clear();
            }
            else
                MessageBox.Show("Autentificare cu succes");
        }
    }
}