Pages

Thursday, January 29, 2009

Project - Breakfast Bringer

Problem

We have a computer showing an excel document at work, which shows who has to get breakfast on the particular day. I thought it could be made a lot smarter, and that's why i started this fun mini project, but also to get a better understanding of Windows application, because they are relatively new for me.

Solution

Create a small windows application which will keep track on who has to get breakfast each day.


The language is Danish, so you will have to translate if you don't get the main functionality.


How it's made


Before I explain my method i have to say, that I have very little knowledge about Windows applications, because this is my second Windows application I've made.

Data

It runs on one computer, but i would still like it to store the data somehow, even when the program is closed. I solved this by making a Data.xml file, I communicate with this file using LINQ to XML. The structure looks like this:
<?xml version="1.0" encoding="utf-8"?>
<bringers>
   <bringer status="brought" lastDate="29-01-2009">
      <name>Thomas</name>

   </bringer>
   <bringer status="bring" lastDate="">
      <name>Christian</name>
   </bringer>
      <bringer status="bring" lastDate="">

      <name>Nikita</name>
   </bringer>
</bringers>
I could make the status to boolean, an id etc. but this is made very quickly and does what is has to do.
My only problem with the Data.xml file has how to include it into my project when i published it, it look a while but i found the solution in the Application Properties > Appliccation Files... > Include Data.xml


LINQ to XML

I used very simple linq to xml, actually just to create, update and delete.
DataAccess.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace BreakfastBringer
{
    class DataAccess
    {
        private static XElement doc = XElement.Load("Data.xml");

        public void CreateBringer(string status, string name)
        {
            XElement newBringer = new XElement("bringer",
              new XAttribute("status", status),
              new XAttribute("lastDate", ""),
                new XElement("name", name));

            doc.Add(newBringer);
            doc.Save("Data.xml");
        }

        public void UpdateBringer(string name, string status)
        {
            IEnumerable<XElement> bringerList = (from b in doc.Elements("bringer")
                                                 where b.Element("name").Value == name
                                                 select b);

            foreach (XElement singleBringer in bringerList)
            {
                singleBringer.SetAttributeValue("status", status);
                singleBringer.SetAttributeValue("lastDate", DateTime.Now.ToShortDateString());
            }

            doc.Save("Data.xml");
        }

        public void UpdateAllBringers(string status)
        {
            IEnumerable<XElement> bringerList = (from b in doc.Elements("bringer")
                                                 select b);

            foreach (XElement singleBringer in bringerList)
            {
                singleBringer.SetAttributeValue("status", status);
            }

            doc.Save("Data.xml");
        }

        public static List<string> GetBringers(string status)
        {
            return (from b in doc.Descendants("bringer")
                    where b.Attribute("status").Value == status
                    select b.Element("name").Value).ToList();
        }

        public static object GetTodaysBringer()
        {
            return doc.Descendants("bringer").FirstOrDefault(x => x.Attribute("lastDate").Value == DateTime.Now.ToShortDateString());
        }

        public static void DeleteBringer(string name)
        {
            IEnumerable<XElement> bringerList = (from b in doc.Elements("bringer")
                                                 where b.Element("name").Value == name
                                                 select b);
            foreach (XElement singleBringer in bringerList)
            {
                singleBringer.Remove();
            }
            doc.Save("Data.xml");
        }
    }
}

When the data access is handled, you can start on the fun bit, which is making the functionality.

Random function

I needed a random function on the bringer list because I wanted to make it both chooseable and random.
int listCount = LbxBring.Items.Count;
if (listCount != 0)
{
   Random random = new Random();

   int randomIndex = random.Next(0, listCount);
   LbxBring.SetSelected(randomIndex, true);
}

Load a file

I wondored how this could be achieved and the solution was very simple, you are able to see the xml file to backup xml or just to see how the data structure is:
System.Diagnostics.Process.Start("Data.xml");

Update application


This is why the application is in 1.1, it didn't have this function in the first build, and that was quite annoying. Because the application was open all the time so as soon as a day has passed the "Today message" was outdated, so i had to create a loop in the delegate which invoked the specific function:
// Starts the thread.
timerThread = new Thread(new ThreadStart(ThreadProc));
timerThread.IsBackground = true;
timerThread.Start();
// This Background Thread is called from the ThreadStart Delegate.
public void ThreadProc()
{
   MethodInvoker mi = new MethodInvoker(this.DatabindLbxs);
   while (true)
   {
      this.BeginInvoke(mi);
      //        every 3rd hour
      Thread.Sleep(10800000);
   }
}
I found this method in another blog, but i can't remember the link right now, but if i remember it, I'll be sure to post it here :)

No comments:

Post a Comment