zoukankan      html  css  js  c++  java
  • 影院售票系统

    这个影院售票的项目比较的复杂,共需要九个类.

    No.1首先第一个类,座位类。该项目的座位默认为黄色,被售出的状态下默认为红色。需要导入命名空间 Using.System.Drawing.Color

     public class Seat
        {
            public Color Color { get; set; }//座位颜色
            public string Num { get; set; }//座位号
            public Seat()
            {
            }
            public Seat(Color color,string num)
            {
                this.Color = color;
                this.Num = num;
            }
        }

    No.2电影类,没啥说的。按照面向对象的思想封装一堆属性。

      [Serializable]//可序列化的标识!
       public class Movie
        {
            public string Name { get; set; }
            public string DaoYan { get; set; }
            public string Star { get; set; }
            public string MovieType { get; set; }
            public string Url { get; set; }
            public int Price { get; set; }
            public Movie()
            {
            }
            public Movie(string name,string daoyan,string star,string type,string url,int price)
            {
                this.Name = name;
                this.DaoYan = daoyan;
                this.Star = star;
                this.MovieType = type;
                this.Url = url;
                this.Price = price;
            }
        }

    No.3放映计划类,保存每天放映计划的集合,有一个解析XML文件的方法!

    [Serializable]//可序列化标识
        public class Schedule
        {
            public Dictionary<string, ScheduleItems> Items { get; set; }
            public Schedule()
            {
                this.Items = new Dictionary<string, ScheduleItems>();
            }
            public Schedule(Dictionary<string, ScheduleItems> item)
            {
                this.Items = item;
            }
            public void Show()
            {
                XmlDocument myxml = new XmlDocument();
                myxml.Load("ShowList.xml");
                XmlNode root = myxml.DocumentElement;
                foreach (XmlNode item in root.ChildNodes)
                {
                    Movie movie = new Movie();
                    foreach (XmlNode child in item.ChildNodes)
                    {
                        switch (child.Name)
                        {
                            case "Name":
                                movie.Name = child.InnerText;
                                break;
                            case "Poster":
                                movie.Url = child.InnerText;
                                break;
                            case "Director":
                                movie.Star = child.InnerText;
                                break;
                            case "Actor":
                                movie.DaoYan = child.InnerText;
                                break;
                            case "Price":
                                movie.Price = Convert.ToInt32(child.InnerText);
                                break;
                            case "Type":
                                movie.MovieType = child.InnerText;
                                break;
                            case "Schedule":
                                foreach (XmlNode childs in child.ChildNodes)//解析并赋值
                                {
                                    ScheduleItems sch = new ScheduleItems(movie, childs.InnerText);
                                    this.Items.Add(childs.InnerText, sch);
                                }
                                break;
                        }
                    }
    
                }
            }

    No.4影院每天放映计划的场次,保存每场电影的信息,所以有一个Movie类型的movie属性

      [Serializable]
       public class ScheduleItems
        {
            public Movie Movie { get; set; }
            public string Time { get; set; }
            public ScheduleItems(Movie movie,string time)
            {
                this.Movie = movie;
                this.Time = time;
            }
            public ScheduleItems()
            {
            }
        }

    No.5电影票父类,保存电影票的信息和放映场次,里面有2个虚方法,用于计算价格,打印电影票.

     [Serializable]
       public class Tickey
        {
            public ScheduleItems Item { get; set; }
            public Seat Seat{ get; set; }
            public int Price { get; set; }
    
            public virtual int CalcPrice()
            {
                int money = this.Item.Movie.Price;
                return money;
            }
            public Tickey()
            {
            }
            public Tickey(ScheduleItems item,Seat seat)
            {
                this.Item = item;
                this.Seat = seat;
                this.Price = CalcPrice();
            }
            public virtual void Print()
            {
                string path = (this.Item.Time + " " + this.Seat.Num).Replace(":","-") +".txt";//文件名
                MessageBox.Show(path);
                FileStream fs = new FileStream(path, FileMode.Create);
                
                     StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                    
                        sw.WriteLine("*******************************");
                        sw.WriteLine("          青鸟影院             ");
                        sw.WriteLine("-------------------------------");
                        sw.WriteLine("电影名:" + Item.Movie.Name);
                        sw.WriteLine("时间:" + this.Item.Time);
                        sw.WriteLine("座位号:" + this.Seat.Num);
                        sw.WriteLine("价格:" + this.Price);
                        sw.WriteLine("*******************************");
                        sw.Close();
                        fs.Close();
                    
             }
             
       
            }

    No.6学生票子类,继承电影票类,保存特殊的信息(折扣),并且重写父类的虚方法

    public int DicCount { get; set; }
            public override int CalcPrice()
            {
                int money = this.Item.Movie.Price*DicCount/10;
                return money;
            }
            public StudentTickey() 
            {
            }
            public StudentTickey(ScheduleItems Item, Seat seat, int discount)
                : base(Item, seat)
            {
                this.DicCount = discount;
                this.Price = CalcPrice();
            }
            public override void Print()
            {
                string path = (this.Item.Time + " " + this.Seat.Num).Replace(":", "-") + ".txt";//文件名
                FileStream fs = new FileStream(path, FileMode.Create);
    
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
    
                sw.WriteLine("*******************************");
                sw.WriteLine("          青鸟影院             ");
                sw.WriteLine("-------------------------------");
                sw.WriteLine("电影名:" + Item.Movie.Name);
                sw.WriteLine("时间:" + this.Item.Time);
                sw.WriteLine("座位号:" + this.Seat.Num);
                sw.WriteLine("价格:" + this.Price);
                sw.WriteLine("*******************************");
                sw.Close();
                fs.Close();
    
            }
        }

    No.7免费票子类,获取获赠者的名字,重写父类的虚方法,将计算价格方法的返回值改为0

     public class FreeTickey:Tickey
        {
            public string FreeName { get; set; }
            public override int CalcPrice()
            {
                int money = 0;
                return money;
            }
            public FreeTickey() 
            {
            }
            public FreeTickey(ScheduleItems Item, Seat seat,string name)
                : base(Item, seat)
            {
                this.FreeName = name;
                this.Price = CalcPrice();
            }
            public override void Print()
            {
                string path = (this.Item.Time + " " + this.Seat.Num).Replace(":", "-") + ".txt";//文件名
                FileStream fs = new FileStream(path, FileMode.Create);
    
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
    
                sw.WriteLine("*******************************");
                sw.WriteLine("          青鸟影院             ");
                sw.WriteLine("-------------------------------");
                sw.WriteLine("电影名:" + Item.Movie.Name);
                sw.WriteLine("时间:" + this.Item.Time);
                sw.WriteLine("座位号:" + this.Seat.Num);
                sw.WriteLine("价格:" + this.Price);
                sw.WriteLine("*******************************");
                sw.Close();
                fs.Close();
            }
        }

    No.8电影院类,可以看作是以上几个类的集合。定义座位集合Dictionary<string,Seat>;放映计划和已售出票的集合list<Tickey>

       [Serializable]
       public class Cinema
        {
            public Dictionary<string,Seat> Seats { get; set; }
            public Schedule Dule { get; set; }
            public List<Tickey> SoldTickeys { get; set; }
          
            public Cinema()
            {
                this.Seats = new Dictionary<string, Seat>();
                this.SoldTickeys = new List<Tickey>();
                this.Dule = new Schedule();
            }

    接下来我们要研究一下Form窗体中的代码了!!!!

    1:首先:初始化TreeView树状图中的电影信息及播放场次

     public void Show()
            {
                cinema.Dule.Show();
    
                TreeNode root = null;
                foreach (ScheduleItems item in cinema.Dule.Items.Values)
                {
                    if (root == null || root.Text != item.Movie.Name)
                    {
    
                        root = new TreeNode(item.Movie.Name);
                        this.TvList.Nodes.Add(root);
                    }
    
                    root.Nodes.Add(item.Time);
                }
            }

    通过调用在放映计划类中的(Schedule)中写好的解析XML文档的方法解析。为什么要使用影院类的对象来调用这个方法呢?因为在cinema中封装好了3个自定义类型的字段,可以直接通过cinema对象调用,避免了多次创建其他类的对象,统一调配。 树状图以电影名为父节点,播放时间为子节点,首先创建出父节点对象,遍历播放时间集合,做出一道判断,将电影名放到父节点上,则将播放时间赋给子节点。

    2.展示电影和电影票的信息,在树状结构被选中的事件上。

     private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
            {
                
                TreeNode node = TvList.SelectedNode;
                if (node.Nodes==null || node.Nodes.Count==0)
                {
                    
             
                this.label1.Text = cinema.Dule.Items[node.Text].Movie.Name;
                this.label2.Text = cinema.Dule.Items[node.Text].Movie.DaoYan;
                this.label3.Text = cinema.Dule.Items[node.Text].Movie.DaoYan;
                this.label4.Text = cinema.Dule.Items[node.Text].Movie.MovieType;
                this.label5.Text = cinema.Dule.Items[node.Text].Time;
                this.label6.Text = cinema.Dule.Items[node.Text].Movie.Price.ToString();
                this.label7.Text = "";
                this.picMovie.Image = Image.FromFile(cinema.Dule.Items[node.Text].Movie.Url);
    
                string key = node.Parent.Text + node.Text;        
                ColorYellow();//将控件变成黄色
               
                
            }
    
            public void ColorYellow()
            {
                foreach (Control itemC in this.tabCon.Controls)
                {
                    itemC.BackColor = Color.Yellow;
                }
            }

    首先记录下被选中节点(基本上在树状类型被选中的事件中都要有这么的一句话)判断如果被选中的节点下没有子节点了,开始将界面上的label标签赋值。首先被选中的节点是父节点电影名称,之后被选中的节点是放映时段,根据此时段加载出该电影的信息和票价,并且将控件变为黄色。因为每一种电影的每一个播放场次均有座位(各有自己的一套座位)。

    3:实现买票功能:首先动态加载出一堆的label控件,即座位。确定几种买票的方式,通过单选按钮的事件实现。

    private void rb02_CheckedChanged(object sender, EventArgs e)
            {
                this.textBox1.Enabled = true;
                this.comboBox1.Enabled = false;
                this.comboBox1.Text = "";
                this.label7.Text = "0";
            }
    
            private void rb03_CheckedChanged(object sender, EventArgs e)
            {
                this.textBox1.Enabled = false;
                this.textBox1.Text = "";
                this.comboBox1.Enabled = true;
                this.comboBox1.Text = "7";
                if (this.label6.Text != "")
                {
                    int price = Convert.ToInt32(label6.Text);
                    int discount = Convert.ToInt32(comboBox1.Text);
                    this.label7.Text = (price * discount / 10).ToString();
                }
            }
    
            private void rb01_CheckedChanged(object sender, EventArgs e)
            {
                this.textBox1.Enabled = false;
                this.textBox1.Text = "";
                this.comboBox1.Enabled = false;
                this.comboBox1.Text = "";
                int price = Convert.ToInt32(label6.Text);
                this.label7.Text = price.ToString();
            }
    
            private void FrmMain_Load(object sender, EventArgs e)
            {
                Init(5,7);
            }
            public void Init(int row, int line)
            {
                for (int i = 0; i < row; i++)
                {
                    for (int j = 0; j < line; j++)
                    {
                        Label lb = new Label();
                        lb.BackColor = Color.Yellow;
                        lb.Location = new Point(20 + j * 100, 50 + i * 70);
                        lb.Font = new Font("宋体", 11);
                        lb.Name = (i + 1) + "-" + (j + 1);
                        lb.Size = new Size(80, 30);
                        lb.TabIndex = 0;
                        lb.Text = (i + 1) + "-" + (j + 1);
                        lb.TextAlign = ContentAlignment.MiddleCenter;
                        lb.Click += new System.EventHandler(lb_Click);
                        this.tabCon.Controls.Add(lb);
                        Seat seat = new Seat( Color.Yellow,lb.Text);
                        cinema.Seats.Add(seat.Num, seat);
                    }
                }
            }
            private void lb_Click(object sender, EventArgs e)
            {
                if (this.TvList.Nodes.Count == 0 || this.TvList.SelectedNode.Level == 0)
                {
                    return;
                }
    
                lbl = sender as Label;//object基类型转化为Label类型
                if (lbl.BackColor == Color.Red)
                {
                    MessageBox.Show("已售出");
                }
                else
                {
                    if (DialogResult.OK == MessageBox.Show("是否购买", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                    {
    
                        //用于判断如何得到Cinema
                        bool flag = true;
                        Cinema cinema2 = null;
       
                        string text = TvList.SelectedNode.Text;
                        string txt = TvList.SelectedNode.Parent.Text;
                        string key = txt + text;
                        foreach (string itemKey in dic.Keys)
                        {
                            if (key.Equals(itemKey))
                            {
                                cinema2 = dic[itemKey];
                                flag = false;
                            }
                        }
                        if (flag)
                        {
                            cinema2 = new Cinema();
                            cinema2.Seats = cinema.Seats;
                            cinema2.Dule = cinema.Dule;
                        }
                      
                        string time = this.TvList.SelectedNode.Text;
                        ScheduleItems item = cinema2.Dule.Items[time];
                        string type =this.rb01.Checked ? "normal" : rb02.Checked ? "free" : "student";
                        Tickey tic = null;
                        switch (type)
                        {
                            case "normal":
                                tic = new Tickey(item, cinema2.Seats[lbl.Text]);
                                 tic.Print();
                                
                                break;
                            case"free":
                                tic = new FreeTickey(item, cinema2.Seats[lbl.Text], textBox1.Text);
                                tic.Print();
                               
                                break;
                            case"student":
                                tic = new StudentTickey(item, cinema2.Seats[lbl.Text], Convert.ToInt32(comboBox1.Text));
                                tic.Print();
                                
                                break;
                        }
    
    
                        
                        
                        dic.Add(key, cinema2);
    
                        lbl.BackColor = Color.Red;
                        cinema.Seats[lbl.Text].Color = Color.Red;
                     
                    }
    
                }
            }

     创建一个双列集合Dictionary(string,Ciname)如果被选中的节点的文本与其父节点的文本与该集合的key值相等,cinema对象等于dic[key];因为Cinema保存的是播放时段,座位和被卖出去的票。

    通过电影名称和选中的时间段来确定这三个属性。然后判断被买的票的类型,将其加入到dic集合中。最后将控件的颜色变成红色。

    4:通过序列化和反序列化来实现保存和继续销售的功能。

    private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
            {
    
                //直接序列化 Dictionary dic 这样 在反序列化时就啥都不用干了。
                BinaryFormatter bf = new BinaryFormatter();
                FileStream fs = new FileStream("YingPianInfo.bin", FileMode.Open);
                bf.Serialize(fs, dic);
    
                fs.Close();
                MessageBox.Show("保存成功");
            }
    
    
    
          
            private void 继续销售ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Show();
                BinaryFormatter bf = new BinaryFormatter();
                FileStream fs = new FileStream("YingPianInfo.bin", FileMode.Open);
                dic = (Dictionary<string, Cinema>)bf.Deserialize(fs);
                
                fs.Close();
               
              
            }

     直接序列化dic集合就可以了,因为dic集合中保存的就是被卖出票的所有信息。

    5:最后在继续销售的时候,将已经卖出的座位标识为红色(即已售出)

    public void SeatColorChanage(List<Tickey> tickeys)//将已售出的票变成红色 根据字典集合的键值
            {
               
                if (tickeys!=null && tickeys.Count!=0)
                {
                    
                    foreach (Tickey item in tickeys)//所有被卖出的票
                    {
                       
                        foreach (string cinemaSet in cinema.Seats.Keys)//已经售出座位的编号
                        {
                          
                            if (cinemaSet.Equals(item.Seat.Num))//如果匹配已经售出的座位
                            {
                                foreach (Control itemLast in this.tabCon.Controls)
                                {
                                    if (itemLast.Text.Equals(cinemaSet))
                                    {
                                         itemLast.BackColor = Color.Red;
                                    }
                                }
                            }
                        }
                    }
                }
    
    }

     因为以上的dic集合保存的是已经售出票的信息,如果其中的座位编号与当前的座位编号相匹配的话,将其变成红色,在treeView的事件中调用该方法。如果是该电影该时段的情况下,以dic[item].Soldtickeys.因为Soldtickey是list<tickey>类型,该字段又存在于cinema类中,所以直接以其为参数传递,将控件变为红色!

  • 相关阅读:
    Android官方数据绑定框架DataBinding*
    Application 使用分析*
    Android HandlerThread与IntentService*
    Android中SQLite应用详解*
    Android开发中,那些让您觉得相见恨晚的方法、类或接口*
    巧用ViewPager 打造不一样的广告轮播切换效果*
    Android-Universal-Image-Loader的缓存处理机制与使用 LruCache 缓存图片*
    Android Volley完全解析*
    Android 蓝牙*
    Android自定义View
  • 原文地址:https://www.cnblogs.com/chimingyang/p/5419011.html
Copyright © 2011-2022 走看看