Adresář stokrát jinak

Když člověk začíná s programováním, dělá roztodivné prográmky. Vzpomínám si, že jsem psal různé „užitečné“ aplikace, jako např. na zjišťování svátků nebo SPZ, různé hry a hříčky a tak – některé výtvory můžete najít na mých archaických (10 let starých) stránkách. Oblíbeným typem prográmků pak byly také různé „databáze“ – adresář s kontakty, evidence cédéček apod. Tehdy jsem složitě dělal načítání a ukládání ze/do souboru (nejlépe v každé verzi programu úplně jiný, často binární, formát), hlídání všech kontrolek na formuláři a ukládání změn atd. Protože od mých programátorských začátků uplynulo už dost času, napadlo mě, jak bych si s takovým prográmkem poradil dnes. Nejen díky tomu, že už toho umím víc, ale také protože docela postoupila technologie. Takže jsem si zkusil implementovat takový jednoduchý správce kontaktů – v C# ve WinForms.

No celé jsem to měl implementované během chviličky. Nejprve jsem implementoval třídu pro uložení jednoho kontaktu:

[Serializable]
public class Person
{

    public string FirstName
    {
        get;
        set;
    }

    public string LastName
    {
        get;
        set;
    }

    public string Address
    {
        get;
        set;
    }

    public string Email
    {
        get;
        set;
    }

    public string HomePage
    {
        get;
        set;
    }

    public string Phones
    {
        get;
        set;
    }

    public string NameForDisplay
    {
        get { return this.LastName + " " + this.FirstName; }
    }

    public override string ToString()
    {
        return this.NameForDisplay;
    }

} 

Jak je vidět, nic složitého. Property NameForDisplay je tam jen kvůli hezčímu zobrazení v ListBoxu.
Dále jsem si pak naklikal jednoduché GUI a pomocí databindingu jsem určil, jaké kontrolky mají být navázané na které properties (to se dělá také pomocí designeru). V samotném formu pak stačilo nakódit přidání nového kontaktu, smazání stávajícího a ukládání a načítání ze souboru. Ukládání a načítání jsem udělal přes (de)serializaci – stačilo třídu Person odekorovat atributem Serializable. Serializaci jsem zvolil do XML (pomocí třídy SoapFormatter), ale předělat to na ukládání do binárního souboru by byla otázka změny dvou řádků – zaměnit SoapFormatter za BinaryFormatter. Pouze se vyskytla taková drobná nepříjemnost – SoapFormatter neumí serializovat generické třídy, takže jsem ukládal pole jednoduše získané z Listu pomocí metody ToArray(). Kód formuláře vypadá takto:

public ContactsForm()
{
    InitializeComponent();
    this.Contacts = new List<Person>();
    this.personBindingSource.DataSource = this.Contacts;
}

public List<Person> Contacts
{
    get;
    protected set;
}

private void addButton_Click(object sender, EventArgs e)
{
    var p = (Person)this.personBindingSource.AddNew();
    p.FirstName = "Bob";
    p.LastName = "Newmann";
    this.personBindingSource.MoveLast();
    this.personBindingSource.ResetBindings(false);
}

private void removeButton_Click(object sender, EventArgs e)
{
    if (this.personBindingSource.Current is Person &&
        MessageBox.Show(string.Format("Do you want to delete contact '{0}' ?", ((Person)this.personBindingSource.Current).NameForDisplay),
            "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    {
        this.personBindingSource.RemoveCurrent();
    }
}

private void ContactsForm_FormClosed(object sender, FormClosedEventArgs e)
{
    using (var stream = System.IO.File.Create(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data.xml")))
    {
        new SoapFormatter().Serialize(stream, this.Contacts.ToArray());
    }
}

private void ContactsForm_Load(object sender, EventArgs e)
{
    var fn = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data.xml");
    if (System.IO.File.Exists(fn))
    {
        using (var stream = System.IO.File.OpenRead(fn))
        {
            this.Contacts.AddRange((Person[])new SoapFormatter().Deserialize(stream));
            this.personBindingSource.ResetBindings(false);
        }
    }
} 

Opravdu poslední kousek kódu, který jsem napsal, je obsažen v souboru Program.cs, kde se typicky dělá jen vytvoření formuláře a spuštění aplikace. Přidal jsem obsloužení všech výjimek v programu:

[STAThread]
static void Main()
{
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new ContactsForm());
}

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    if (e != null && e.Exception != null)
    {
        MessageBox.Show(e.Exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    if (e != null && e.ExceptionObject is Exception)
    {
        MessageBox.Show(((Exception)e.ExceptionObject).Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
} 

Celý projekt si můžete stáhnout zde (70,4 kB). Samozřejmě je to je spíš takový nástřel, protože jsem se nechtěl dělat s kdejakýma blbostma, ale myslím, že to pěkně ukazuje, jak rychle se dá vyvíjet s dnešníma technologiema…

2 thoughts on “Adresář stokrát jinak

Zanechat odpověď

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

Logo WordPress.com

Komentujete pomocí vašeho WordPress.com účtu. Odhlásit /  Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Odhlásit /  Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Odhlásit /  Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Odhlásit /  Změnit )

Připojování k %s

Tento web používá Akismet na redukci spamu. Zjistěte více o tom, jak jsou data z komentářů zpracovávána.