C#程序设计

第一章:C#基础

一.知识点

1.C#的概念和了解

2.语法格式

3.案例实践

二.重点

2.1 语法格式

三.内容

3.1 C#:C sharp(利器).C-->C++-->C++++,Java都来自于C系列,诞生于C++基础之上开发的。

MS微软公司开发的,现在C#也实现了跨平台,有点晚了。

C#开发最初的时候,只适合于微软的平台(windows系列,xp、2000、7 10等),设计的程序,不仅仅是windows系列

,还有Linux、Mac、Unix、安卓等等操作系统。

应用场景:最多的是C/S系列程序(软件),C:Client客户端;S:Server;服务器;网吧系统、屏幕广告(红蜘蛛)、卖票、炒股的、黑客破解的等等。Asp.Net:Web端开发程序,网页程序,但是跨平台不好,最主要的是微软不是一个互联网公司,卖操作系统的。现在Unity3D的软件,做VR/AR在线游戏,核心语言就是C#。

3.2语法格式:

变量名的使用:JS的时候,变量名区分大小写;首字母:能不能是数字???_ +

C#:是强类型的语言,就是只要出错,在VS2012就会报错;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//命名空间:区分类;
namespace chapter01
{ //class就是类
    class Program
    {
        //static:静态的;void:不返回任何类型;Main:门;string[]args:参数;
        //程序里面也有一个门;不能动,就是程序的入口;参数就是门卫,你需要登记;
        static void Main(string[] args)
        {
            //基本数据类型;
            int age = 18;
            float height = 1.8F; //float类型后需要加F;
            double weight = 120; //C#默认小数是double类型;
            char flag = 'Y';  //字符类型,使用''单引号把数据引起来;
            bool biaozhi = true;//bool:真假型
            //字符串类型;
            String name = "zhangsan"; //字符串是双引号;
            //输出;Write():不换行; WriteLine():换行;
            Console.Write(name);
            Console.Write(age);
        }
    }
}

如何运行:“调试”里面有一个“启动调试”,快捷键:F5;但是会一闪而过;

不想一闪而过:Ctrl+F5;“调试”--》“开始执行(不调试)“

//求圆的面积;S=PI*r*r
            //1.定义变量,并赋值;
            Console.Write("请输入圆的半径:");
            double r;//3是固定的值;可以自己输入;
            r = double.Parse(Console.ReadLine());
            const double PI=3.1415926; //常量使用 const定义;常量名:大写;
            double s = PI * r * r;
             //PI = 2; 常量不能多次赋值;
            Console.WriteLine(r + "的面积是:" + s);
            //不使用Ctrl+F5;最后接受一下;
            Console.ReadLine();

3.3 占位符;

之前都是使用+连接变量和字符串;

{0},{1}-->变量1,变量2

 //占位符;两个数相加 减 乘  除
            int num1, num2;
            Console.WriteLine("请输入数字1:");
            num1 = int.Parse(Console.ReadLine());//将字符串转换成int类型;
            Console.WriteLine("请输入数字2:");
            num2 = int.Parse(Console.ReadLine());//将字符串转换成int类型;
            //2.输出;规则:{0},对应的是"",后面的第一个变量;{1}:第二个变量;
            Console.WriteLine("{0}+{1}={2}",num1,num2,(num1+num2));
            Console.WriteLine("{0}-{1}={2}", num1, num2, (num1 - num2));
            Console.WriteLine("{0}*{1}={2}", num1, num2, (num1 * num2));
            Console.WriteLine("{0}/{1}={2}", num1, num2, (num1 / num2));
            Console.WriteLine("{0}%{1}={2}", num1, num2, (num1 % num2));
            Console.ReadLine();

3.4 控制结构:

3.41顺序结构

3.4.2分支结构:if 语句 switch语句 ;

//分支语句,swtich 语句;
            //根据时间,来输出上午(789)下午(141617)晚上(202122);
            int num;
            Console.Write("请输入时间:");
            num = int.Parse(Console.ReadLine());
            //2.业务判断;
            switch(num){
                case 7:                    
                case 8:                   
                case 9:
                    Console.WriteLine("{0}点上午",num);break;
                case 14:
                case 16:
                case 17:
                    Console.WriteLine("{0}下午", num); break;
                case 20:
                case 21:
                case 22:
                    Console.WriteLine("{0}晚上", num); break;
                default:
                    Console.Write("有问题");break; //C#:强类型,必须有break;
            }
            Console.ReadLine();

循环结构:

四.作业

4.1课后作业

第二章 :循环和字符串

一.知识点

1.循环(do while/while/for/foreach)

2.字符串String和StringBuilder

3.类型转换

二.重点

1.循环掌握最少2个;

2.字符串的使用;

3.类型转换

三.内容

1.循环(固定次数的循环,不固定次数的循环)

循环的步骤:

1.1 初始化变量 i

1.2循环的条件(啥时候去循环,意味着有一个结束的条件)

​ {

​ 1.3循环的代码工作,要干的事情;

​ 1.4计数器

​ }

do while和while循环的区别?

do while:最少执行一次;因为do while循环先执行代码,后判断;

static void Main(string[] args)
        {
            //少了条件判断,降低了循环次数;
            for (int i = 1; i <= 100;i+=2 )
            {
                Console.Write(i+"  ");
            }
            Console.Read();
int i = 0;
            do{
                if (i % 2 == 0)
                    Console.Write(i + "  ");
                i++;
            }while(i<0);
            Console.Read();
 //少了条件判断,降低了循环次数;
            for (int i = 1; i <= 100;i+=2 )
            {
                Console.Write(i+"  ");
            }
            Console.Read();

foreach格式:

 //C#:数组格式[],数组的下标从0开始到数组的长度-1;
            int[] arr = { 1,3,5,7,9};
            //输出数组中的元素;数组名[下标]
            Console.WriteLine(arr[0]);
            Console.WriteLine(arr[1]);
            Console.WriteLine(arr[2]);
            Console.WriteLine(arr[3]);
            Console.WriteLine(arr[4]);
            //报错:数组的索引超出了界限;
            //Console.WriteLine(arr[5]);
            //输出数组中的元素;i:0 1 2 3 4
            //for (int i = 0; i <= 4;i++ )
            //{
            //    Console.Write(arr[i]+"   ");
            //}
            foreach(int n in arr){ //n:arr;n表示从数组中逐个取元素出来;
                Console.Write(n +"\t");
            }
            Console.Read();

2.水仙花数:

100-999之间的三位数;第一步找范围;

153=1^3+5^3+3^3

第二步确定:个位 十位 百位

% /

gw = 153 % 10; //个位%10求余数; sw = 153 / 10 % 10;//十位分两步操作; bw = 153 / 100;//百位/10整除 Console.Write("{0}",gw); Console.Write("{0}",sw); Console.Write("{0}",bw);

for(int i=100;i<=999;i++){

//第三部确定水仙花的等式条件,然后输出结果;

}

 int gw, sw, bw; //分别代表个位  十位 百位
            //i:153;
            for (int i = 100; i <= 999; i++) {
                gw = i % 10;  //个位%10求余数;
                sw = i / 10 % 10;//十位分两步操作;
                bw = i / 100;//百位/10整除
                if(i==gw*gw*gw+sw*sw*sw+bw*bw*bw){
                    Console.WriteLine(i);
                }
            }
                Console.Read();

3.String类;

 //字符串位置也是从0开始;
            String str = "今天是个好天气,我被今个老师批评了一顿,魏子博,是个好同学";
            Console.WriteLine(str.Contains("魏子博"));//是否包含
            Console.WriteLine(str.EndsWith("子博"));//以某个子串结尾
            Console.WriteLine(str.StartsWith("今天"));//以某个子串开头;
            Console.WriteLine(str.IndexOf("个"));//3 第一次出现的位置;
            Console.WriteLine(str.Insert(3,"晴天真是"));
            Console.WriteLine(str.LastIndexOf("个"));
            Console.WriteLine(str.Remove(3));
            Console.WriteLine(str.Replace("魏子博", "魏大帅哥"));
            Console.WriteLine("Abcd".ToUpper());
            Console.WriteLine("Abcd".ToLower());
            Console.WriteLine(str.Substring(3,5));//3: 起始位置;5截取的长度;
            //格式化字符串:{0},{1},{2}
            //Format(字符串加占位符,值1,值2,..,值n)
            String name="赵俊杰";
            int age=88;

            String str2 = String.Format("我们的班长是{0},年龄:{1}",name,age);
            //整出来这个格式化的字符串,控制台可以用,游戏也能用;winform也能用;
            //传值更为方便;
            Console.WriteLine(str2);
            Console.Read();
 //1.隐式转化(自动转换)
            //int age = 20;
            //double age2 = age; //double:浮点型:小数类型,范围比较大;
            //Console.WriteLine(age);
            //Console.WriteLine(age2);           
            //2.显式转化;
            double height = 2.87;
            int height2 =(int)height;       //因为double类型 范围比较大;
            //在大的类型前面加一个     (小类型)
            Console.WriteLine(height);
            Console.WriteLine(height2);  //出现的问题就是数据丢失了;
            int height3 = Convert.ToInt32(height);
            //从double类型转整型的时候会四舍五入;
            Console.WriteLine("-->"+height3);

            //3.类型转换;字符串 --》整型
            string s = "222";
            int num2 = int.Parse(s);//parse(字符串参数)
            Console.WriteLine(num2);
            int num3 = Convert.ToInt32(s);
            Console.WriteLine(num3);
            Console.Read();

四.作业

课后作业1 2 3

第三章 双重循环和数组

一.知识点

1.双重循环

2.数组

二.重点

1.面试题

2.数组

三.内容

1.双重循环:循环的嵌套

循环一般最多3层,要求大家精通双重循环面试题;掌握面试题的解决思路。

直角三角形:


    /// <summary>
    /// *
    /// * * *
    /// * * * * *
    /// * * * * * * *
    /// * * * * * * * * *
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 5;i++ ) { //i:行数;1 2  3 4 5;2i:2 4 6 8 10
                for (int j = 1;j<=2*i-1 ;j++ )//j:*的个数;1 3 5 7 9
                {
                    Console.Write("* ");
                }
                Console.WriteLine();
            }
            Console.Read();
        }
    }

奇数三角形:

 /// <summary>
    /// *
    /// * *
    /// * * *
    /// * * * *
    /// * * * * *
    /// 
    /// </summary>
      class Program
    {
        static void Main(string[] args)
        {
            //所有的这种面试题:外层循环控制行数;i代表行数
            for (int i = 1; i <= 5; i++) {
                //Console.WriteLine("输出行数"+i);
                //如何在第1行一个*;第2行**;第3行:***;
                for (int j = 1; j<=i;j++ ) //j:代表输出的*个数;
                {
                    Console.Write("* ");
                }
                Console.WriteLine();//一行完毕之后:换行
            }
            Console.Read();
        }
    }

等腰三角形:

/// <summary>
    ///        *
    ///      * * *
    ///    * * * * *
    ///  * * * * * * *
    ///* * * * * * * * *
    /// 
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 5;i++ )
            {
                for (int j = 5 - i; j >= 1;j-- )
                {
                    Console.Write("  ");
                }
                for (int j = 1; j <= i;j++ )
                {
                    Console.Write("* ");
                }
                for (int j = 1;j<i ;j++ )
                {
                    Console.Write("* ");
                }
                Console.WriteLine();
            }
            Console.Read();
        }
    }

字母三角形

2.数组

数组:概念:一组相同数据类型的集合;

为什么要用???

要求我们班42人的平均成绩???>42变量

语法格式:

数据类型 [] 数组名=new 数据类型长度]

int[]ages=new int[3]; //数组的长度为3;

int[]score=new int[42];

String[]names=new String[42];

数组的赋值:值一定要和数组数据类型一致;

数组名[下标]=值 下标从0开始;到数组的长度-1

score[0]=88;

score[1]=90;

ages={};也可以使用{}赋值;

 //1.定义数组长度;
            String[] names = new String[5];
            int[] salary = new int[5];
            //String[]names=new String[5]{"李颖","冰棍","雪糕","鸡腿","汉堡"};
            //names[0]="李自然";
            //names[2]="马冬梅";
            //names[3] = "西门吹牛";
            //names[4] = "东坡个";
            //names[1] = "曲长老";
            //names[5] = "和尚";  //最大长度为5-1=4
            //2.输入;Length:数组的长度;
            //for (int i = 0; i < names.Length; i++) {
            //    Console.Write("请输入第{0}个同学的名字:",i+1);
            //    names[i] = Console.ReadLine();
            //    Console.Write("请输入第{0}个同学的工资:",i+1);
            //    salary[i] = Convert.ToInt32(Console.ReadLine());//或:int.parse()
            //}
            //3.输出
            for (int i = 0; i < 5;i++ ) {
                Console.WriteLine("{0}同学的工资:{1}",names[i],salary[i]);
            }
            Console.Read();

四.作业

1.page 50

2.page 53上机练习1

3.有能力的同学自行预习“冒泡排序”

4.录屏,自己当老师,有注释,有声音,讲解page77作业3。

第四章:复习课

1.求含有5个数组元素的平均值

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ararydemo
{
    /// <summary>
    /// 目标:求长度为5的整型数组的平均值;
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            //1.声明数组;使用[]来定义;5
            int[] arr = new int[5];
            //2.输入;最简单的赋值的方式;使用循环来赋值;
            //找规律:arr[]  数组名[]   北极星[0]-北极星[9]
            //皇家一号[0]--皇家一号[4];  酒店名[门牌号]
            //数组名[下标]->下标的规律:0  --4;递增;
            //arr[0] = 1;
            //arr[1] = 2;
            //arr[2] = 10;
            //arr[3] = 20;
            //arr[4] = 78;
            for (int i = 0; i <= 4;i++ )
            {
                Console.Write("请输入第{0}个元素",(i+1));//占位符,值匹配
                //Console.Write("请输入第" + (i + 1) + "个元素");
                //接受;
                arr[i] = int.Parse(Console.ReadLine()); //类型转换;int.parse();Convert.ToInt32()
            }
            //3.输出;最好再写一个循环;
            //Console.WriteLine(arr[0]);
            int sum=0;  //sum和
            //for (int i = 0; i < arr.Length; i++)
            //{
            //    Console.WriteLine(arr[i]);
            //    sum = sum + arr[i];
            //}
            //也可以使用如下格式
            foreach (int num in arr)
            {
                Console.WriteLine(num);
                sum = sum + num;
            }
            //int avg = (arr[0] + arr[1] + arr[2] + arr[3] + arr[4])/5;
            int avg = sum / 5;
            Console.WriteLine("平均值:{0}", avg);
            Console.Read();
        }
    }
}

2.求数字为n的阶乘及阶乘和

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 求阶乘
{
    /// <summary>
    /// 阶乘:n!=n*(n-1)!;
    /// 4!=4*3*2*1;
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("请输入求阶乘一个数字:"); //提示信息
            int n = int.Parse(Console.ReadLine());//n:代表求阶乘的数字;假设:4
            //求1*2*3*4
            //求1!+2!+3!+4!
            int ji = 1;//设置一个变量初始值就是1;
            int sum = 0;
            for (int i = 1; i <= n;i++ )
            {
                ji = ji * i;//ji=1*1;ji=1*2=2;ji=2*3;
                sum += ji; //sum=sum+ji;
            }
            Console.WriteLine("{0}的阶乘是:{1}",n,ji);
            Console.WriteLine("阶乘的和{0}", sum);
            Console.ReadLine();
        }
    }
}

3.求母串中子串出现的位置及其个数

 String s1 = "大雪来了,大雪兆丰年,我叫大雪";
            String keyword = "大雪";
            //这个是考虑两个;
            //Console.WriteLine(s1.IndexOf(keyword)); 获取keyword关键字的位置;
            //Console.WriteLine(s1.LastIndexOf(keyword));
            int index=0;
            //母串.IndexOf(子串,查找的起始位置),当起始位置改变的时候,从新的位置继续查找原母串中子串的位置;
            //Console.WriteLine(s1.IndexOf(keyword,1));
            //Console.WriteLine(s1.IndexOf(keyword, 6));
            while ((index = s1.IndexOf(keyword,index)) != -1)
            {//条件不等于-1,则循环;
                //循环里面就是符合条件的数据字符串
                Console.WriteLine("子串位置:{0}", index);
                //下一步,是不是应该让index往后走;
                index = index + keyword.Length;  //0+2;                 
            }
            Console.Read();

4.作业:

4.1 录屏第一题,需要加注释,并自己讲解,头像、声音;

4.2预习第五章

第五章 窗体控件

一.知识点

1.窗体

2.常用控件

3.命令语句

二.重点

1.掌握窗体和常用控件

2.学会常用控件的属性、事件

三.内容

1.窗体的概念

windows:视窗;可视化窗口;

新建windows窗体--》起名:frmWin

右键-->属性;设置窗体的text:标题;name:默认刚才你写的frmWin

BackColor:背景颜色

设置一下:programs-->

Main()下面:

Application.Run(new frmWin());

StartPosition:启动位置;CenterScreen;

MaximizeBox:最大化按钮是否可以用;true:可以用;false:变灰;这个设置完之后,并不是一定不变大小;

FormBorderStyle:None:没有边框;FixedSingle:单边框;

Form窗体:网页:表单,可以放表单元素,调查页面等;实际上窗体就是一个容器,可以放其他控件。相当于饭店的餐桌;GroupBox等容器相当于盘子;

步骤:

1.找控件

2.设置属性

3.写代码

2.登录窗体效果

1577235838883.png

1.Label:标签;作用,只是提示信息;

2.textBox文本框:用来输入信息;

3.button 按钮;用来单击;交互使用;

账号文本框:txtName;

密码框:txtPwd

登录按钮:btnLogin

参考代码:

private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();//关闭
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            //MessageBox.Show(txtName.Text);//弹框;
            //MessageBox.Show(txtPwd.Text); 
            String name = txtName.Text;  //定义两个变量,接受用户名文本框和密码框的值;
            String pwd = txtPwd.Text;

            // if (txtName.Text.Equals("83193980") && txtPwd.Text.Equals("88889999"))
            if (name.Equals("83193980") && pwd.Equals("88889999"))
            {
                MessageBox.Show("登录成功");
            }
            else
            {
                MessageBox.Show("登录失败");
            }
        }

3.items

selectedIndex Items Item

四.作业

4.1 登录窗体完美版

第六章 控件

一.知识点

1.图片框

2.多窗体调用

3.控件继续

4.消息框

二.重点

1.多窗体之间调用

三.内容

1.图片框案例:

在窗体下声明变量

//声明了一个数字变量;i默认值是0;我们设置为1

        private int i=1;

上一张按钮代码:

{
            //有这样一个属性;图片的路径:ImageLocation
            //MessageBox.Show(pictureBox1.Image);
            i--;
            if (i == 0) i = 5;
            pictureBox1.ImageLocation = String.Format("img/bg{0}.jpg",i);

下一张按钮代码:

//img/bg   数字变量 .jpg;数字变量是i
            //pictureBox1.ImageLocation = "img/bg"+i+".jpg";
            i++;
            if (i == 6) i = 1;
            pictureBox1.ImageLocation = String.Format("img/bg{0}.jpg",i);

退出按钮代码(两种测试)

//第二个窗体是不是关闭了。
            //this.Close();
            Application.Exit();     //应用退出

3.MessageBox():消息框

//也可以用于删除的时候;
            //MessageBox:消息框;+20:多义方法;打
            DialogResult result=MessageBox.Show("您是否关闭皇家一号酒店系统?","提示信息",MessageBoxButtons.YesNo,MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                //要关的事件;取消属性为false;就是关了.
                e.Cancel = false;
            }
            else {
                e.Cancel = true;
            }

4.菜单栏

加图标:

是Form窗体:ICON属性,找老师给的ico图标;

RichTextBox直接设置停放;

TextBox:需要先设置成多行,然后设置Dock为Fill(可以下拉出来测试)

设置右键菜单,需要先找文本框,设置它的属性ContextMenuStrip

统一给文本框(或富文本框)改名:txtNotepad

文本框:text_changed()

富文本框:SelectionChanged

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace demo61
{
    public partial class Form1 : Form
    {
        private int i = 9;
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 当关闭窗体的时候,给提示;
        /// e:事件参数对象;
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //也可以用于删除的时候;
            //MessageBox:消息框;+20:多义方法;打
            //DialogResult result=MessageBox.Show("您是否关闭皇家一号酒店系统?","提示信息",MessageBoxButtons.YesNo,MessageBoxIcon.Question);
            //if (result == DialogResult.Yes)
            //{
            //    //要关的事件;取消属性为false;就是关了.
            //    e.Cancel = false;
            //}
            //else {
            //    e.Cancel = true;
            //}
        }

        private void 文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void 退出XToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void 撤销UToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.txtNotepad.Undo(); //撤销;调用的是系统的方法
        }

        private void 剪切ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtNotepad.Cut();       //剪切方法;
        }

        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtNotepad.Copy();
        }

        private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtNotepad.Paste();  //?
        }

        private void 变大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //设置字体,需要给Font一个具体的字体对象;
            //我已经给你设置变量i++
            txtNotepad.Font = new Font("黑体",i++);
        }

        private void 变小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtNotepad.Font = new Font("黑体", i--);
        }

        private void 加粗ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //FontStyle:字体的样式;
           // txtNotepad.Font = new Font("黑体", txtNotepad.Font.Style | FontStyle.Bold);  
            //FontStyle.Italic 斜体;
            //FontStyle.Strikeout; 删除线
            //FontStyle.Underline;//下滑线
            //如果当前是粗体,则不变;
           // MessageBox.Show(txtNotepad.Font.ToString());
            //第一个参数是之前的Font样式;省略page150行代码;
            txtNotepad.Font = new Font(txtNotepad.Font, FontStyle.Bold);
        }

        private void 状态栏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            状态栏ToolStripMenuItem.Checked = true;  //出来对勾;
            this.statusStrip1.Visible = true;
        }

        private void richTextBox1_SelectionChanged(object sender, EventArgs e)
        {
            if (txtNotepad.SelectedText.Length != 0)
            {
                复制ToolStripMenuItem.Enabled = true;
                剪切ToolStripMenuItem.Enabled = true;
            }
        }
        /// <summary>
        /// 这个一个文本框的改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtNotepad_TextChanged(object sender, EventArgs e)
        {
            
        }
        //颜色:ForeColor 前景色;BackColor:背景色;
        private void 红色ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txtNotepad.ForeColor=Color.Pink;
        }
    }
}

四.作业

第七章 控件二

一.知识点

1.掌握控件的用途

2.掌握控件的主要属性

3.掌握控件的使用技巧

二.重点

1.时钟控件

2.工具栏、ImageList

三.内容

1.Tool strip 控件是由system.Windows.forms.Toolstrip类提供的,作用是创建易于自定义的常用工具栏,让这些工具栏支持高级用户界面和布局功能,如停靠、漂浮、带文本和图像的按钮、下拉按钮等。

常用属性:

显示方式 属性
DisplayStyle 图像和文本显示方式,一般ImageAndText
Image 按钮或标签上的图片
ImageScaling 图片大小
Text 标签上显示的文本
TextImageRelation 图像和文字的相对位置,一般ImageAboveText

2.TabControl(选项卡)

属性 说明
Multiline 是否可以显示一行上的选项卡
TabPages 设置控件上的选项卡页的集合
SelectedIndex 选项卡页的索引
SelectedTab 当前选定的选项卡页

3.Timer控件

它是什么?

  控件。它是不可见的。

它是干什么的?

  用于背景进程中。通过引发Timer事件,Timer控件可以有规律的隔一段时间执行一次代码。也就是,你可以根据你自己的需要,给Timer控件设置时间,Timer每隔这段时间,就执行一次代码(这个代码你可以根据自己需要的功能写。)

属性 说明
Interval 事件发生的频率,以毫秒为单位
Enabled 获取或设置计时器是否正在运行
事件 说明
Tick 每隔指定间隔发生的事件
方法 说明
Start 启动计时器
Stop 停止计时器
属性
Name tmDate
Interval 1000(1秒=1000毫秒)

4.ImageList

案例:动态相册

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace demo61
{
    public partial class frmImage : Form
    {
        //要让0 1 2 3 4 5,需要定义变量;
        int i = 0;
        public frmImage()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 在时钟时间,每滴答一次更改一下图片
        /// imageList:图像列表;它里面每一项都是一个图像(Image)
        /// images:很多图片;images[0]--就是第一个图片;
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {            
            if (i > 80)
                i = 0;
            this.pictureBox1.Image=this.imageList1.Images[i];
            i++;
           
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = true;
           // this.timer1.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.timer1.Stop();
        }
        //快
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            this.timer1.Interval = 100;
        }
        //中
        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            this.timer1.Interval = 500;
        }
        //慢
        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            timer1.Interval = 1000;
        }
    }
}

跑马灯和颜色变化

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace demo61
{
    public partial class frmGun : Form
    {
        //颜色改变,定义变量
        int i=0;
        public frmGun()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
           
        }
        /// <summary>
        /// 跑马灯,在Html,marquee
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmGun_Load(object sender, EventArgs e)
        {

        }
        //从右向左;
        //颜色是怎么构成的?三原色(红 绿 蓝)0-255;
        //255最强光;255 255 255->白;0 0 0
        private void timer1_Tick_1(object sender, EventArgs e)
        {
            label1.Left = label1.Left - 2;
            //this.Left += 2; //this:就是窗体;
            this.label2.Left -= 3;
            if (label1.Left < -label1.Width)
                label1.Left = this.Width;//this:代表当前窗体宽度;
            if (label2.Left < -label2.Width)
                label2.Left = this.Width;//this:代表当前窗体宽度;

            //调色;
            Color color = new Color();//弄一个新颜色;
            color = Color.FromArgb(255,i,255-i);
            i += 5; //i值变化;
            if (i > 255) i = 0;
            //label2.ForeColor = color;//前景色;
            //变窗体的背景色;
            this.BackColor = color;
        }
    }
}

四.作业

第八章 C#和Mysql数据库连接

一.知识点

1.安装插件和补丁包软件

2.下载dll文件

二.重点

1.访问顺序;

2.查询

三.内容

准备工作,注意不是复制dll文件,也不是复制到bin/debug下,而是添加引用;

1578272880876.png

1578273653538.png

1578273725132.png

1578273774953.png

第一步熟悉一下:C#连接数据库的一些常用类库

农夫山泉:口号;不生产水,搬运工;

数据提供程序:不生产数据,数据库生产数据;只是搬运工;

1551491971415.png

不能用的处理方式

1578276019957.png

把目标框架更改一下:

1578276065775.png

数据库访问的顺序:

1)建立数据库连接

 //str:是一个连接数据库的连接字符串;
            String str = "server=localhost;userid=root;password=root;database=school";
            //建立连接;练习搬运工;这个搬运工叫conn
            MySqlConnection conn = new MySqlConnection(str);
           // conn.ConnectionString = str;  //给搬运工的连接方式(联系方式,去丹江口)赋值
            MessageBox.Show(conn.ConnectionString);

2)打开数据库连接

//在之前的代码基础上,增加如下代码。进行测试;
conn.Open();  //Open():表示搬运工已经和对方水厂(数据库建立了联系).
            ConnectionState state = conn.State;
            MessageBox.Show(state.ToString());//?

1578276904746.png

3)编写SQL语句

//mysql: 4个功能;增删改查;

String sql="";

 //insert grade(gname) values('S1'),('S2'),('S3')多个
            String sql = "insert grade(gname) values('S5')";
String sql = "delete from grade where gname in('S4','S5')"; //id>3
 String sql = "update grade set gname='大一' where id=1";

4)创建SQL命令对象SQLCommand

 //给搬运工下达命令;MySqlCommand:命令类,用来执行搬运工的命令;
            MySqlCommand comm = new MySqlCommand(sql, conn); //   +3方法有三个同名的方法 ;
            //comm.Connection = conn;   //和刚才的搬运工建立联系;
            //comm.CommandText = sql; //接受命令;

5)执行SQL命令

  int result=comm.ExecuteNonQuery(); //不是查询是增删改
  if (result > 0)
                MessageBox.Show("插入成功");
  else
                MessageBox.Show("插入失败");

6)关闭数据库连接

//最后有一个关闭???为啥要关闭呢?

示例1:添加班级信息

string constr="server=localhost;userid=root;password=root; database=school";
MySqlConnection conn = new MySqlConnection(constr);//创建数据库连接对象
conn.Open();//打开连接对象
string className = txtClassName.Text;
string createDate = txtCreateDate.Text;
string sql =string.Format("insert into classes(className,createDate) values('{0}','{1}')",className,createDate);
MySqlCommand command = new MySqlCommand(sql,conn);//根据sql命令和数据库连接创建数据库命令对象
int count=command.ExecuteNonQuery();//执行数据库的非查询命令
if (count > 0)//如果返回值(影响的行数)大于0,提示录入成功
{
    MessageBox.Show("班级录入成功");
}
conn.Close();//关闭数据库连接

  1. string time = dateTime.Value.ToShortDateString();

四.作业

1.熟练掌握增删改查

第九章:数据库连接

一.知识点

1.动态插入数据,新控件的学习

2.DataReader查询信息

3.MDI窗体

二.重点

1.动态增删改

2.DataReader

三.内容

1.增加学生信息

步骤:

​ 1.1建立窗体,拖拉控件;

​ 1.2.改名字;

​ 1.3.引用数据库using MySql.Data.MySqlClient;

​ 1.4.写代码;

2.DataReader控件的使用

DataReader对象的属性和方法

属性 说明
HasRows 是否返回结果,如果有查询,则返回True,否则返回False
FieldCount 返回当前行中的列数

常用方法

方法名 说 明
Close 清除任何数据的DataSet
Reader 将XML和数据导入到DataSet
NextResult 使数据读取器前进到下一个结果
IsDBNull 判断列中的数据是否为NULL值,返回True/False

3.MDI窗体

1578452718217.png

效果如下:

1578454077276.png

单击:

1578454095649.png

信息增加代码:

 frmAddStu addStu = new frmAddStu();//new新窗体;
            addStu.MdiParent = this;        //设置新窗体的父窗体是当前MDI容器;
            addStu.Show();

效果: 1578454228811.png

拖动主界面窗体,子窗体界面会随主窗体界面来回跑动。

四.作业:

4.1开始项目设计数据库和表;做好分析;

4.2练习上课内容

4.3做酒店需要自学第8章的ListView

第十章 DataSet 、数据适配器、数据表格

一.知识点

1.DataSet

2.导入数据到数据表格

二.重点

​ 2.1数据集

​ 2.2 数据适配器

​ 2.3 数据表格

三.内容

3.1数据集

1)数据集合的作用:是在内存中建立起一个临时的数据仓库,可以对其进行操作并同步到底层数据库。

​ 为什么用它?

MySqlConnection conn连接对象。--》打开完毕之后,给comm

​ MySqlCommand 可以增删改查。考试理论(50道),这些试题就放在了数据集里面。考试完毕之后,要提交的时候

,再插网线,将内存中的答案等提交一下。相当于C#给我们提供的临时数据库。

2)数据集结构:

1551507101167

3)使用DataTable

有行和列的集合:Columns和Rows,

Rows就是查询获得的数据表中的每一行数据集合,集合就可以通过索引或下标访问,例如:通过Rows[行号][]"班级名称" ]获得该数据,

Columns是表格中列的集合,通过Columns["身份证号码"]来获得指定的列对象

3.2 数据适配器

数据适配器类似于充电器;充电器找到一个手机,去手机里面充电。

从数据源把数据拿到DataSet(数据集)的DataTable(数据表)

​ new的时候,查看参数是哪些。大家也可以看书。

1578877057577.png

fill()方法;参数是数据集对象

1578886473287.png

也可以填充数据表,填充数据表到通用类来讲。

封装提取代码:

3.3 DataGrid控件

4)DataGridView

常用属性:

DataSource:数据源,可以设置某一个DataTable即可

SelectionMode:是表格的选择模式,一般选择FullRowSelect

MultiSelect:是否可以多选

ReadOnly:是否只读

添加该控件后顺手把它的这几个选项如图选定,一般不在表格中进行添加和修改操作。

1551505590554

查询使用数据适配器MySQLDataAdapter,用法和MySqlCommand相同,该适配器可以填充一个内存中的表格DataTable对象,然后让dataGradView的数据源(DataSource)指向该表格。

 String str = "server=localhost;userid=root;password=root;database=school;charset=utf8";
            MySqlConnection conn = new MySqlConnection(str);
            conn.Open();
            String sql="select id 编号,name 姓名,gender 性别,age 年龄,birth 生日,address 地址 from student";

            //加两个参数:(sql命令,连接对象)
            MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
            //DataSet临时数据库对象ds
            DataSet ds=new DataSet();
            //Fill(参数是数据集对象)
            //adapter.Fill(ds);  索引下标;
            adapter.Fill(ds, "学生");  //又加了一个表名
            //目的是填充到数据表格里面。
            //???就是ds这个临时数据库里面有几个表???
            //MessageBox.Show(ds.Tables.ToString()); 不加Count是数据表的集合
            //MessageBox.Show(ds.Tables.Count.ToString()); 是数据表的个数
            //向数据表格进行填充;
            //数据源是一个数据表???
            //dgvStudent.DataSource = ds.Tables[0];  对的是索引下标,从0开始;
            dgvStudent.DataSource = ds.Tables["学生"];  //表名

3.4 数据库通用代码

假设现在6个表,每个表对应4个窗体,24个,再加上额外的6个,30个窗体。

有很多重复的代码:

 String conStr = "server=127.0.0.1;userid=root;password=root;database=school;charset=utf8";
            MySqlConnection conn = new MySqlConnection(conStr);
            conn.Open();
            String sql = String.Format("select name,pwd from student where name='{0}' and pwd='{1}'",txtName.Text.Trim(),txtPwd.Text.Trim());
            MySqlCommand comm = new MySqlCommand(sql, conn);
            //数据;读者;数据读取器;
            MySqlDataReader reader=comm.ExecuteReader();

怎么办?

​ 3.4.1 一个记忆好,每次都敲,这叫劳模;

​ 3.4.2 复制 、粘贴,要快些;

​ 3.4.2 合格的程序员,要偷懒;把这些公共的代码要进行封装,放到一个类里面,这个类是一个公共的类。

util文件夹,它里面放公共的类文件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient; /*加mysql命名空间;*/
using System.Data;  //使用System.Data命名空间,否则;DataTable出不来;

//命名空间:chapter08.util

namespace chapter08.util
{
    /// <summary>
    /// 这个是一个公共的连接数据库的类
    /// static:静态的关键字;static:不可变的;访问的时候,可以直接类名.属性/类名.方法
    /// </summary>
    class DBHelper
    {
        static String str = "server=localhost;userid=root;password=root;database=school;charset=utf8";
        //1.获得通用连接对象 ;static,是否可以去掉;
        public static MySqlConnection getConn() {
            MySqlConnection conn = new MySqlConnection(str);
            conn.Open(); //自动打开;
            return conn;
        }
        //2.关闭连接;关闭的连接对象,所以参数是连接对象
        public static void close(){
            MySqlConnection conn = getConn();
            if(conn!=null){
                conn.Close();
            }
        }
        //3.增删改操作;方法有参数没有???
        public static int update(String sql) { 
            //通用方法的增删改的连接对象也是通用的.
            MySqlConnection conn = getConn();
            MySqlCommand comm = new MySqlCommand(sql,conn); //sql是从外部传过来的命令语句;conn是通用的连接对象.
            int result = comm.ExecuteNonQuery();
            return result;
        }
        //4.查询操作;参数
        public static DataTable query(String sql) {
            //通用方法的增删改的连接对象也是通用的.
            MySqlConnection conn = getConn();
            MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
            //定义了一个数据表格对象;没有数据;
            DataTable dt = new DataTable();
            //这时候填充到数据表格对象dt里面
            adapter.Fill(dt); //这时候dt就有数据了;
            return dt;
        } 
    }
}

3.5 单击数据表格获取值

//使用一个变量来接受一下;rows:行的集合;
            //首先是获得数据表格的rows,
            //其次是第几行的第几列;cells
            //这时候得到的是一个单元格对象;就是一个格子,我们的目标是其中的值;
            //String str = dataGridView1.Rows[0].Cells[1].ToString();
            //MessageBox.Show(str);
            //*******得到其中的值***********
            //String str2 = dataGridView1.Rows[0].Cells[1].Value.ToString();
            //MessageBox.Show(str2);
            //*************得到当前行的值;e:代表的是当前鼠标单击事件;rowIndex:行号;ColumnIndex:列序号;
            //String str3 = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
            //MessageBox.Show(str3);

3.6 单击数据表格传值给新窗体

数据表格代码:

 //*******接下来目标就是把数据显示到frmUpdateGrade窗体上面;            
            String id = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
            String name = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
            //声明了窗体对象,并new了一下,新建出来;
            frmUpdateGrade updateGrade = new frmUpdateGrade();

            updateGrade.id = id;
            updateGrade.name = name;

            updateGrade.Show();
            //跨窗体传值的时候,应该把id,name传给updateGrade;

新窗体代码:

 //1.给窗体定义两个属性;id,name
        public String id;//如果是int,则需要强制转化一下;
        public String name; 
        
        

在窗体加载事件添加代码:

 //这时候没有值;
            //MessageBox.Show(id + "初始化....," + name);
            //当我们写了frmDataGrid2,两行赋值代码之后,id和name的值就传过来了。
            //我们要把这个值传到哪里去呢???this:在这里代表当前窗体对象;
            txtId.Text = this.id;
            txtGName.Text = this.name;

更新按钮代码:

 /// <summary>
        /// 更新按钮代码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            String sql = string.Format("update grade set gname='{0}' where id={1}",txtGName.Text,txtId.Text);
            int result=DBHelper.update(sql);
            if (result > 0)
                MessageBox.Show("更新成功");
            else
                MessageBox.Show("更新失败");
            DBHelper.close();
        }

四.作业

4.1 掌握三类内容

4.2 使用通用的数据库操作类来实现增删改查;

4.3 项目的所有资料:

​ 4.3.1 需求分析+人员分工(放假之前交),具体的人做哪个模块

4.3.2  数据库表的设计(写本上,就是几张表,表名,字段名和含义)

​ 4.3.3 命名规范 写下来(frm前缀;btn;cmb;)

4.4 DBHelp.cs录屏讲解

十一.项目阶段

项目阶段的分解:

1.需求分析;宿舍管理系统、酒店管理系统、背单词项目、会员系统;交付给公司架构师、项目经理,高级程序员等;

​ 一般由项目经理来做需求,去客户地方实际挖掘需求、采样数据、获取资料等。

确定的是有哪些模块、以及模块之间的关联、业务大致流程、规范。

2.详细设计说明书/数据库文档说明书:根据目前我们的实际程度,我们将二者可以合并到一起;

实际形成文档的是word文档,不是这种Excel文档

3.项目开发计划:

我们这里定义的项目进度安排,这个就是简化版的开发计划,也就说大家实际上市遵循了项目开发的业务流程的。

4.测试环节:

黑盒测试和白盒测试

所谓黑盒测试:就是对于外界测试来说,不用考虑代码即可,只需要测试功能需求。

白盒测试:一个是针对我们的错误调bug,一个就是加断点等简单的小技巧,来看看自己的程序是否有问题,这个时候,大家会发现针对的是代码。

合并项目,小项目合并,小项目合并到大项目,大项目合并到总项目,桩模块的测试。

5.打包发布、上线运行(试运行)

我们这里,就是项目演示、答辩的环节。

字段名 类型 约束要求 默认值 备注
stuId int 主键 primary key 学员编号
stuName varchar not null 学员姓名
gender varchar 学员性别

总结:

​ 不管我们做的多么low,感觉和公司的规范差别很大,但是实际上大家都不自觉的遵循了公司的开发规范。

11.1 项目问题总结

11.1.1 项目问题:查询

image-20200306094404479.png

涉及到哪些表:

学生表、班级表 有关联。学生表.班级编号=班级表.编号

楼层表 宿舍表 宿舍表.楼层编号=楼层表.编号

关联查询,建议大家使用or 即可。

11.1.2 项目问题:入住

image-20200306095012115.png

image-20200306095400904.png

入住的时候问题:

​ 1.在入住之前需要先判断,该宿舍类型是男 还是女;男--》男生宿舍;女-》女生宿舍;

​ 2.入住的时候,只能入住未满的宿舍;满的可以不显示;

如果做的酒店项目,涉及到提前预约的问题,如果预约过了,则不能再次预约该房间;比入住多了一个限制。

转宿的问题:

​ 1.是转宿的时候,对方一定要是未满,这个可以过滤掉;

费用管理:

涉及到找零啊,一个月多少天,住不满怎么办?29天,住了7天;住了5天,这种问题;可以往后放,首先核心功能完成了

再去考虑这些问题。

费用汇总:水费、电费、住宿费、优惠等等。

11.1.3常规问题

image-20200306111317978.png

  • 窗体名还是英文格式;
  • 最大化这种框框实际是不允许东的;
  • MDI窗体启动,或内置窗体一定要居中对齐,不要乱放。
  • bug处理,大家可以加上try catch块。防止运行直接崩掉。
  • 窗体间数据的传值,在要传值的窗体,要设置一个属性或多个属性来接受一下;整个项目使用,可以使用类,设置成static的字段,扩充和自学的。

11.1.4 作业:

  • 项目继续完善,挖掘出bug,不要认为完美了;
  • A135的要组织一下提前的预审;
  • 迎接下周的项目评审。

11.2项目预审统一再要求

1.各组需要提交一个项目视频,就是你们讲解的视频,这个视频组长要讲模块分工、具体成员的工作分配;完毕之后,

按照业务流程,由各个组员来讲解具体的模块。

比如说:张三:学生业务模块

​ 李四:教员模块

​ 王五:宿管;

​ 组长:统筹安排,

2.演示流程:组长先统一讲解,讲解完了,具体的成员再讲自己的模块,这个视频可以是采用组内叮叮直播的方式或者是各人做好视频,统一交由组长,然后由组长交给我。这个时间不能太短,不能低于15分钟。(组内所有人)

3.针对有问题的组,不要刻意规避问题的存在,比如说:转宿有问题,满了还能继续转,删除,输入一个人的名字,但是存在多人,都删除掉了,要要演示上去。

4.有些组,感觉已经做完了,核心模块,把项目打包+数据库发给我,再来测试一下。这样我们再看下是否有哪些问题。答辩的时候,重点针对组员。

5.评审的时候,组内成员都应该有一份相同的、最终版的、可以运行的项目,这时候,老师说,李四,你来演示教员模块,李四要及时连麦,所以,需要组内成员之间,提前学会连麦、屏幕分享模式。

11.3 项目打包和发布

因为注册码过期,我们先演示流程,作为一个扩充知识点给学有所余的同学,项目未完成的了解即可。

11.3.1 注意事项:命名空间不要是中文;

11.3.2 版本号

image-20200311091642952.png

11.3.3 上次修改的的方式,成了可以自己公司的一些信息

image-20200311091802976.png image-20200311092150763.png

11.3.3 打包

image-20200311093715173.png

image-20200311093735835.png

image-20200311094036677.png

image-20200311095724019.png image-20200311095745329.png

image-20200311094220086.png

image-20200311094426960.png image-20200311094531639.png

image-20200311094750304.png

image-20200311094959112.png

image-20200311095138996.png

image-20200311102304097.png

image-20200311102247387.png