先來點廢話,剛拿到這個項目的時候你是怎么想的,上來就悶頭寫,還是構想思路......
項目需求:
影院售票系統可以銷售每天不同時段的電影票,不同時段的電影票有不同的優惠政策,還有使用兌換券的免費票。選擇某個時段的一場電影,
單擊放映廳未售出的座位並選擇一個種類的電影票,創建電影票,計算價格並打印,座位設置為紅色表示已經售出。
思想:
使用面向對象思想編寫影院售票系統
看完這個你有沒有點思路呢,我想你是有的 ......
下面先來點圖片,先刺激一下視覺:
窗體搭建:
程序運行時發生的,來看清楚了:
是不是該選擇你要看的電影列表了
好了,該你選擇電影了,
挑選你喜歡的座位:
掏錢吧,要不你選擇的就是別人的了
這個座位是你的了,還想看別的么?
選擇贈票吧,免費的:
再來張學生票:
這樣看是不是特別不爽,我感覺也是,看圖片沒感覺,接下來代碼吧!
先把我們所需要的幾個類創建出來吧!
/// <summary> /// 電影票父類 /// </summary> public class Ticket { public Ticket() { } public Ticket(ScheduleItem scheduleItem, Seat seat) { ScheduleItem = scheduleItem; Seat = seat; } //播放場次 public ScheduleItem ScheduleItem { get; set; } //所屬座位對象 public Seat Seat { get; set; } //票價 public int Price { get; set; } //計算票價的虛方法 public virtual void CalcPrice() { Price =ScheduleItem.Movie.Price; } //打印售票信息的虛方法 public virtual void Print() { string fileName = ScheduleItem.Time.Replace(":", "-") + " " + Seat.SeatNum + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("***************************"); sw.WriteLine(" 青鳥影院(普通) "); sw.WriteLine("---------------------------"); sw.WriteLine(" 電影名:\t{0}", ScheduleItem.Movie.MovieName); sw.WriteLine(" 時間: \t{0}", ScheduleItem.Time); sw.WriteLine(" 座位號:\t{0}", Seat.SeatNum); sw.WriteLine(" 價格: \t{0}", Price.ToString()); sw.WriteLine("***************************"); sw.Close(); fs.Close(); } //顯示當前售出票信息的虛方法 public virtual void Show() { MessageBox.Show("已售出"); } }
/// <summary> /// 學生票子類 /// </summary> public class StudentTicket : Ticket { //折扣 public int Discount { get; set; } public StudentTicket() { } public StudentTicket(ScheduleItem scheduleItem, Seat seat, int discount) : base(scheduleItem, seat) { Discount = discount; } //重寫計算票價的方法 public override void CalcPrice() { Price = ScheduleItem.Movie.Price * Discount / 10; } //重寫打印售票信息的方法 public override void Print() { string fileName = ScheduleItem.Time.Replace(":", "-") + " " + Seat.SeatNum + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("***************************"); sw.WriteLine(" 青鳥影院 (學生) "); sw.WriteLine("---------------------------"); sw.WriteLine(" 電影名:\t{0}", ScheduleItem.Movie.MovieName); sw.WriteLine(" 時間: \t{0}", ScheduleItem.Time); sw.WriteLine(" 座位號:\t{0}", Seat.SeatNum); sw.WriteLine(" 價格: \t{0}", Price.ToString()); sw.WriteLine("***************************"); sw.Close(); fs.Close(); } //重寫當前顯示出售票信息的方法 public override void Show() { MessageBox.Show("已售出!\n\n " + Discount + "折學生票!"); } }
/// <summary> /// 贈票類 /// </summary> public class FreeTicket : Ticket { public FreeTicket() { } public FreeTicket(ScheduleItem scheduleItem, Seat seat, string customerName) : base(scheduleItem, seat) { CustomerName = customerName; } //贈票者名字 public string CustomerName { get; set; } //重寫計算票價的方法 public override void CalcPrice() { Price = 0; } //重寫打印售票信息的方法 public override void Print() { string fileName = ScheduleItem.Time.Replace(":", "-") + " " + Seat.SeatNum + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.WriteLine("***************************"); sw.WriteLine(" 青鳥影院 (贈票)"); sw.WriteLine("---------------------------"); sw.WriteLine(" 電影名:\t{0}", ScheduleItem.Movie.MovieName); sw.WriteLine(" 時間: \t{0}", ScheduleItem.Time); sw.WriteLine(" 座位號:\t{0}", Seat.SeatNum); sw.WriteLine(" 姓名: \t{0}", CustomerName); sw.WriteLine("***************************"); sw.Close(); fs.Close(); } //重寫當前顯示出售票信息的方法 public override void Show() { MessageBox.Show("已售出!\n\n 贈送者:" + CustomerName); } }
/// <summary> /// 座位信息類 /// </summary> public class Seat { //座位號 public string SeatNum { get; set; } //賣出座位顏色 public Color Color { get; set; } public Seat() { } public Seat(string seatNum,System.Drawing.Color color) { this.SeatNum = seatNum; this.Color = color; } }
/// <summary> /// 保存放映計划信息類 /// </summary> public class ScheduleItem { public ScheduleItem() { Movie = new Movie(); } //播放時間 public string Time { get; set; } //播放電影屬性 public Movie Movie { get; set; } }
/// <summary> /// 放映計划類 /// </summary> public class Schedule { public Schedule() { items = new Dictionary<string, ScheduleItem>(); } //放映場次 private Dictionary<string, ScheduleItem> items; public Dictionary<string, ScheduleItem> Items { get { return items; } set { items = value; } } //讀取Xml文件的方法 public void LoadItems() { XmlDocument doc = new XmlDocument(); doc.Load("ShowList.xml"); XmlNode root=doc.DocumentElement; foreach (XmlNode item in root.ChildNodes) { foreach (XmlNode child in item["Schedule"]) { ScheduleItem sch = new ScheduleItem(); sch.Movie.MovieName = item["Name"].InnerText; sch.Movie.Poster = item["Poster"].InnerText; sch.Movie.Director = item["Director"].InnerText; sch.Movie.Price = Convert.ToInt32(item["Price"].InnerText); sch.Movie.Actor = item["Actor"].InnerText; sch.Movie.MovieType = (MovieType)Enum.Parse(typeof(MovieType), item["Type"].InnerText); sch.Time = child.InnerText; items.Add(sch.Time, sch); } } } }
/// <summary> /// 電影類 /// </summary> public class Movie { //電影名 public string MovieName { get; set; } //海報圖片名 public string Poster { get; set; } //導演名 public string Director { get; set; } //主演 public string Actor { get; set; } //電影類型 public MovieType MovieType { get; set; } //定價 public int Price { get; set; } public Movie() { } public Movie(string movieName, string poster, string director, string actor, MovieType movieType, int price) { MovieName = movieName; Poster = poster; Director = director; Actor = actor; MovieType = movieType; Price = price; } } public enum MovieType { //喜劇 Comedy, //戰爭 War, //愛情 Romance, //動作 Action, //卡通 Cartoon, //恐怖 Thriller, //冒險 Adventure }
/// <summary> /// 影院類 /// </summary> public class Cinema { public Cinema() { Seats = new Dictionary<string, Seat>(); SoldTickets = new List<Ticket>(); Schedule = new Schedule(); } //座位集合 public Dictionary<string,Seat> Seats { get; set; } //放映計划 public Schedule Schedule { get; set; } //已出售電影票的集合 public List<Ticket> SoldTickets { get; set; } //保存售票信息的方法 public void Say() { FileStream fs = new FileStream("soldTickets.txt", FileMode.OpenOrCreate); StreamWriter writer = new StreamWriter(fs, Encoding.Default); for (int index = 0; index < SoldTickets.Count; index++) { Ticket ticket = SoldTickets[index]; string info = "|" + ticket.ScheduleItem.Movie.MovieName + "|" + ticket.ScheduleItem.Movie.Poster + "|" + ticket.ScheduleItem.Movie.Director + "|" + ticket.ScheduleItem.Movie.Actor + "|" + ticket.ScheduleItem.Movie.MovieType.ToString() + "|" + ticket.ScheduleItem.Movie.Price + "|" + ticket.ScheduleItem.Time + "|" + ticket.Seat.SeatNum + "|" + ticket.Seat.Color + "|" + ticket.Price + "|"; if (ticket is FreeTicket) { string customerName = ((FreeTicket)ticket).CustomerName; writer.WriteLine("free" + info + customerName); } else if (ticket is StudentTicket) { writer.WriteLine("student" + info + ""); } else { writer.WriteLine("" + info + ""); } } writer.WriteLine("The End"); writer.Close(); fs.Close(); } //讀取售票信息的方法 public void Load() { try { //創建一個讀取對象 //路徑 //轉換格式 StreamReader reader = new StreamReader("soldTickets.txt", Encoding.GetEncoding("GB2312")); string line = reader.ReadLine(); //聲明一個數組 存儲 soldTickets.txt 的數據 string[] values; //聲明一個電影票對象 Ticket ticket = null; while (line.Trim() != "The End") { values = line.Split('|'); string type = values[0]; Movie movie = new Movie(values[1], values[2], values[3], values[4], (MovieType)Enum.Parse(typeof(MovieType), values[5]), int.Parse(values[6])); ScheduleItem scheduleItem = new ScheduleItem(); scheduleItem.Time = values[7]; scheduleItem.Movie = movie; string color = values[9]; string endColor = color.Substring(color.IndexOf("[") + 1, color.Length - 1 - color.IndexOf("[") - 1); Seat seat = new Seat(values[8], Color.FromName(endColor)); int discount = 10; switch (type) { case "student": discount = 7; ticket = TicketUtil.CreateTicket(scheduleItem, seat, discount, "", type); break; case "free": discount = 0; ticket = TicketUtil.CreateTicket(scheduleItem, seat, discount, values[11], type); break; default: discount = 10; ticket = TicketUtil.CreateTicket(scheduleItem, seat, discount, "", ""); break; } this.SoldTickets.Add(ticket); line = reader.ReadLine(); } reader.Close(); } catch (Exception ex) { Console.WriteLine("出錯了:" + ex.Message); SoldTickets = new List<Ticket>(); } } }
/// <summary> /// 工具類 /// </summary> public class TicketUtil { public static Ticket CreateTicket(ScheduleItem scheduleItem, Seat seat, int discount, string customerName, string type) { Ticket ticket = null; switch (type) { case "student": ticket = new StudentTicket(scheduleItem, seat, discount); break; case "free": ticket = new FreeTicket(scheduleItem, seat, customerName); break; case "putong": ticket = new Ticket(scheduleItem, seat); break; } return ticket; } }
我去,這么多類,你有沒有這個感覺,反正我是有的,這些類的創建不是瞎弄的,要把自己的思路理清楚了!
具體的代碼實現:
public Cinema cinema; //加載座位 Dictionary<string, Label> labels = new Dictionary<string, Label>(); int tickets = 0; string key = null; /// <summary> /// 程序剛啟動時 窗體加載的數據 /// </summary> private void FrmMain_Load(object sender, EventArgs e) { label1.Text = ""; label2.Text = ""; label3.Text = ""; label4.Text = ""; label5.Text = ""; label6.Text = ""; label8.Text = ""; rb01.Checked = true; //初始化一個影院類對象 cinema = new Cinema(); InitInfo(); //調用顯示售票信息的方法 cinema.Load(); } /// <summary> /// 點擊新播放列表時觸發 /// </summary> private void 新放映列表ToolStripMenuItem_Click(object sender, EventArgs e) { cinema.Schedule.LoadItems(); cinema.SoldTickets.Clear(); InitTreeView(); } /// <summary> /// 綁定ListView /// </summary> private void InitTreeView() { tvList.Nodes.Clear(); string movieName = ""; TreeNode tn = null; foreach (ScheduleItem item in cinema.Schedule.Items.Values) { if (movieName != item.Movie.MovieName) { tn = new TreeNode(); tn.Text = item.Movie.MovieName; tvList.Nodes.Add(tn); } TreeNode node = new TreeNode(item.Time); tn.Nodes.Add(node); movieName = item.Movie.MovieName; } } Label label; /// <summary> /// 加載座位 /// </summary> private void InitInfo() { int seatRow = 8; int seatLine = 5; for (int i = 0; i < seatRow; i++) { for (int j = 0; j < seatLine; j++) { label = new Label(); //設置背景顏色 label.BackColor = Color.Yellow; //設置字體 label.Font = new System.Drawing.Font("宋體",14.25F,System.Drawing.FontStyle.Regular,System.Drawing.GraphicsUnit.Point, 134); //設置尺寸 label.AutoSize = false; label.Size = new System.Drawing.Size(50, 25); label.Text = (j + 1).ToString() + "-" + (i + 1).ToString(); label.TextAlign = ContentAlignment.MiddleCenter; //設置位置 label.Location = new Point(60+(i*70),40+(j*50)); //所有標簽都綁定到同一個事件 label.Click += new System.EventHandler(labSeat_Click); tp01.Controls.Add(label); //labels集合存儲以座位號為key值 labels.Add(label.Text, label); Seat seat = new Seat((j + 1).ToString() + "-" + (i + 1).ToString(), Color.Yellow); //保存的座位集合 cinema.Seats.Add(seat.SeatNum, seat); } } } /// <summary> /// 選擇座位時做出的判斷 /// </summary> private void labSeat_Click(object sender, EventArgs e) { if (label8.Text=="") { MessageBox.Show("您還沒選擇電影!", "提示"); return; } tickets++; try { string seatNum = ((Label)sender).Text.ToString(); string customerName =txt01.Text.ToString(); int discount = 0;//折扣 string type = "";//類型 if (rb03.Checked) { type = "student"; if (cbo01.Text == "") { MessageBox.Show("請輸入折扣數!", "提示"); return; } else { discount = Convert.ToInt32(cbo01.Text); } } else if (rb02.Checked) { if (txt01.Text=="") { MessageBox.Show("請輸入贈票者姓名!", "提示"); return; } else { type = "free"; } } else if(rb01.Checked) { type = "putong"; } //調用工具類創建票 Ticket Ticket = TicketUtil.CreateTicket(cinema.Schedule.Items[key], cinema.Seats[seatNum],discount, customerName, type); if (cinema.Seats[seatNum].Color == Color.Yellow) { //打印 DialogResult result = MessageBox.Show("是否購買?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (result == DialogResult.Yes) { cinema.Seats[seatNum].Color = Color.Red; UpdateSeat(); Ticket.CalcPrice(); cinema.SoldTickets.Add(Ticket); label6.Text = Ticket.Price.ToString(); Ticket.Print(); } else if (result == DialogResult.No) { return; } } else { //顯示當前售出票的信息 foreach (Ticket item in cinema.SoldTickets) { //判斷是否為同場次、同電影、同座位號 if (item.Seat.SeatNum == seatNum && item.ScheduleItem.Time == tvList.SelectedNode.Text && item.ScheduleItem.Movie.MovieName == tvList.SelectedNode.Parent.Text) { item.Show(); } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } } /// <summary> /// Treeview選擇時做出的判斷 /// </summary> private void tvList_AfterSelect(object sender, TreeViewEventArgs e) { TreeNode node = tvList.SelectedNode; if (node == null) { return; } if (node.Level != 1) { return; } key = node.Text; //將詳細信息顯示 label8.Text = cinema.Schedule.Items[key].Movie.MovieName; label1.Text = cinema.Schedule.Items[key].Movie.Director; label2.Text = cinema.Schedule.Items[key].Movie.Actor; label5.Text = cinema.Schedule.Items[key].Movie.Price.ToString(); label4.Text = cinema.Schedule.Items[key].Time; label3.Text = cinema.Schedule.Items[key].Movie.MovieType.ToString(); pic01.Image = Image.FromFile(cinema.Schedule.Items[key].Movie.Poster); label6.Text = ""; //清空座位 ClearSeat(); //遍歷該場電影的座位銷售情況 foreach (Ticket ticket in cinema.SoldTickets) { foreach (Seat seat in cinema.Seats.Values) { if ((ticket.ScheduleItem.Time == key) && (ticket.Seat.SeatNum == seat.SeatNum)) { seat.Color = Color.Red; } } } UpdateSeat(); } /// <summary> /// 清空座位 /// </summary> private void ClearSeat() { foreach (Seat seat in cinema.Seats.Values) { seat.Color = Color.Yellow; } } /// <summary> /// 更新座位狀態 /// </summary> private void UpdateSeat() { //根據影院類里面的座位來更新座位的顏色 foreach (string key in cinema.Seats.Keys) { labels[key].BackColor = cinema.Seats[key].Color; } } /// <summary> /// 選擇贈票 /// </summary> private void rb02_CheckedChanged(object sender, EventArgs e) { cbo01.Enabled = false; txt01.Enabled = true; cbo01.Text = ""; label6.Text = "0"; } /// <summary> /// 選擇學生票 /// </summary> private void rb03_CheckedChanged(object sender, EventArgs e) { txt01.Enabled = false; txt01.Text = ""; cbo01.Enabled = true; } /// <summary> /// 選擇普通票 /// </summary> private void rb01_CheckedChanged(object sender, EventArgs e) { cbo01.Enabled = false; txt01.Text = ""; txt01.Enabled = false; cbo01.Text = ""; label6.Text = "0"; } private void 繼續銷售ToolStripMenuItem_Click(object sender, EventArgs e) { //判斷放映列表是否為空 if (cinema.Schedule.Items.Count == 0) { cinema.Schedule.LoadItems(); } InitTreeView(); } /// <summary> /// 選擇下拉列表時框 /// </summary> private void cbo01_SelectedIndexChanged(object sender, EventArgs e) { //根據當前選中的電影,設置“優惠價” if (label5.Text != "") { int price = Convert.ToInt32(label5.Text); int discount = Convert.ToInt32(cbo01.Text); label6.Text = (price * discount / 10).ToString(); } } private void 保存ToolStripMenuItem_Click(object sender, EventArgs e) { DialogResult result = MessageBox.Show("是否保存當前銷售狀態?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (result == DialogResult.Yes) { //退出時保存Cinema對象 cinema.Say(); } } private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) { cinema.Say(); Dispose(); }
這沒有多少文字解說,思想在其中。
其實寫這些都是枯燥的,但是寫完的那一刻,運行的那一刻,你就會覺得這些都是值得的,雖然這是一個特小的項目。
人的信心就是從一點一滴積累起來的,我是這樣告訴自己的,不要局限自己,編程是思想,不是Copy!
希望我的文章能給你提供一種方法,而不是讓你作弊!
要想人前顯貴,就要背后受罪,我覺得說的真好!啰嗦了,我只是想提醒自己!