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…
To kódíš celej den takovýhle píčoviny? 🙂
To se mi líbíTo se mi líbí
Ale neee, něco podobnýho jsem musel kódil jen jednou 🙂
To se mi líbíTo se mi líbí