zoukankan      html  css  js  c++  java
  • 15-03-16 winform

    winform应用程序是一种智能的客户端技术;我们可以使用winform应用程序帮助我们获得信息或者传输信息等;它是CS交互模式下的软件,要求我们的电脑必须安装
    客户端软件;

    传智不拖控件不是指winform,指的是asp.net做网站的时候

    做网站拖控件会产生大量的代码,那些代码大部分对你来说是没用的,当一个网站所有东西都是拖出来的,那么会有很多垃圾代码,当网站运行的时候,垃圾代码
    也会被执行,因此你拖的控件越多,网站的性能就越低;做网站的时候,所有的东西都是一点一点敲出来的,不是拖控件的,但是winform就只能去拖控件了。

    有一门做winformUI层的技术叫做wpf,它用到的一门语言是XAML

    不管是窗体应用程序还是控制台应用程序Main函数都是主入口;

    program.cs中
    static class Program
    {
      static void Main()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new Form1());   //创建一个Form1的对象,控制台创建的对象都看不见,但是winform创建的对象都可见;
       }
    }


    public partial class Form1:Form
    {
      public Form1()
      {
         InitialComponent();
       }
    }
    正方体是方法的图标,蓝色长方体是字段的图标,枚举的图标是二个黄色的小方块,属性是一个小板子
    private void InitializeComponent()
    {
      this.SuspendLayout();
      //
      //
      //
      // form1的一大堆属性
    }
    Form1.Designer.cs  窗体自动生成的代码;
    Form1.resx窗体应用程序的资源文件,音乐图片这些,
    Form1后台代码
    Form1和Form1.Designer.cs 都有partial form1类 他们共同组成了Form1类
    如何在后台快速切换到前台,后台右击空白处,点第一个查看设计器
    winform中看到的每一种控件其实都是每种类;往上面托控件,就是创建该类的对象的过程;

    当我们关闭窗体的时候会执行释放资源的方法
    private System.ComponentModel.IContainer component = null;
    protected override void Dispose(bool disposing)
    {
      if(disposing&&(component != null))
      {
       components.Dispose();
       }
       base.Dispose(disposing);
    }

    给控件设置属性可以在Form1.Designer.cs里面的代码中进行设置;或者选中控件,右键,属性;或者F4导出属性栏,F5运行,F6生成解决方案;
    2.属性
    Name:在后台要获得前台的控件对象,需要使用Name属性;
    BackgroundImageLayOut:控件的背景图片完整填充控件;
    ContextMenuStrip:右键菜单;  要添加右键菜单的话,找到工具箱,菜单和工具栏,ContextMenuStrip拖过来,显示在窗体底下,在左上角设置;然后就在
    这个控件的属性中的contxetMenustrip绑定起来;
    Cursor:光标类型;移到设置的控件中才有效;
    Enable指示控件是否可用,
    Visiable指示控件是否可见;

    3.事件
    发生一件事情;
    注册事件:属性上面的雷标记里就是事件,控件里面被选中的事件都是我们最常用的事件;在对应事件名称中双击即可注册事件,事件本质上就是一个方法;
              Winform中的MessageBox.Show() 就是控制台里面的Console.WriteLine();
    触发事件:

    事件方法的两个参数:第一个参数object sender,表示触发这个事件的对象;是谁触发了这个事件;第二个参数就是EventArgs e表示执行这个事件所需的资源;
    object sender说明控件里面的这些类依然继承于object类
    我们写winform应用程序是由各种事件累积而成;
    在项目目录里,右键,添加,就可以添加多个form窗体;
    在Main函数当中创建的窗体对象,我们称之为这个窗体应用程序的主窗体;
    也就意味着,当你将主窗体关闭了,整个应用程序就都关闭了;
    如果说你想给某个控件注册它的默认被选中的事件,你直接双击这个控件就可以了;
    From2 frm2 = new Form2();
    frm2.show();
    如何在别的窗体中获得主窗体的对象;
    新建一个类;
    public static class Test  //静态类在整个项目当中资源共享,静态类不能创建对象,我们说静态类数据共享,所以我们存一些共享的数据在里面;
    {
       public static Form1 _frm1Test; 声明一个静态字段;
    }
    然后在程序运行的时候,把主窗体对象扔到_frm1Test里面;
    在winform应用程序里面;你要想关闭所有应用程序你就得关闭主窗体,但是在form3窗体里面拿不到主窗体对象;因为根本就不在一个类里面;现在要想在form3中
    获得主窗体的对象,我们就通过静态类传过来,其实是通过静态字段传过来,在Form3中虽然访问不到Form1里面的对象,但是我能访问到Test静态类,因为在一个项目里
    因此也能访问到Test里面的公有字段;
    我们要在程序一运行的时候,就把对象存进去;因此就在Form_Load事件里写
    Test._frm1Test = this;
    在Form3中写
    Test._frm1Test.Close();
    其实就是通过搭建中间桥梁的作用,静态类中的静态字段就是中间桥梁;

    MouseEnter事件;鼠标进入控件所触发的事件;
    this.Close(); 关闭当前窗体;
    this.Width 是窗体的宽度,是个死值;
    this.ClientSize.Width是当前窗体的宽度,随着窗体拉大他也变大;
    this.Height
    this.ClientSize.Height同理
    button1.Location = new Point(r.Next(0,x+1),r.Next(0,y+1))按钮的坐标;
    拖出来一个控件如果有小箭头,那么就点开来看看;

    TextBox
    Multiline属性如果为True,则可以多行显示
    WordWrap属性如果为True,则可以自动换行;
    ScrollBars属性滚动条,横向,纵向,双向
    凡是通过鼠标设置的属性,都可以通过后台代码设置;
    PasswordChar 让文本框显示一个单一的字符
    默认的事件是TextChanged

    同一件事情做好多遍就要用到工具箱,组件当中的Timer,默认Enable是false。Interval事件执行的频率,以毫秒为单位;
    只有一个事件Tick
    跑马灯就是字符串截取(substring)第一个字符截取到最后,在一个Timer中反复执行;
    在Label事件显示就是 lblTme.Text = DateTime.Now.Tostring();但是在刚开始的那一秒不会动,因为计时器是在一秒之后才启动,为了
    解决这个问题,要在窗体加载的时候,将当前系统的时间赋值给我的Label   lblTme.Text = DateTime.Now.Tostring();一个写在时钟事件里
    一个写在Form_Load事件里;
    DateTime.Now.Hour
    DateTime.Now.Minute
    DateTime.Now.Second
    SoundPlayer sp = new SoundPlayer(); //创建一个播放音乐对象
    sp.SoundLocation=@"" //播放文件的路径,只能播放.wav的文件;
    sp.play();                  播放
    可以通过visible属性来控制不同权限,不同用户看到的界面;
    TextBox1.Clear();清空文本框;
    TextBox1.Focus();文本框获得焦点;
    一个属性的true和false可以通过一个按钮来控制;
    if(button1.Text == "自动换行")
    {
      TextBox1.WordWrap = false;
      button1.Text == "取消自动换行";
    }
    else if
    {
      TextBox1.WordWrap = true;
      button1.Text == "自动换行";
    }

    checkbox指示该控件有没有被选中;单选和多选都有
    如何给控件分组呢,这时候需要用到容器 groupbox,把2个radiobutton放进去,这时候放进去的就成了一组;
    默认情况下在一个窗体中,所有的单选按钮只允许选择一个,可以使用groupbox进行分组;
    MDI窗体,一个父窗体里面包含很多子窗体,而且这些子窗体移不出父窗体;
    MDI窗体设计
    1,首先确定一个父窗体; 找到窗体的属性IsMdiContainer 设置为True就是父窗体了
    菜单就是工具箱下面的菜单和工具栏里的MenuStrip,要给里面的按钮注册事件就直接双击对应的按钮;
    2,创建子窗体,并且设置他们的父窗体;
    form2 frm2 = new form2();
    frm2.MdiParent = this;
    frm2.show();
    子窗体在Mdi窗体里横向排列
    LayoutMdi(LayoutMdi.TileHorizontal);
    子窗体在Mdi窗体里纵向排列
    LayoutMdi(LayoutMdi.TileVertical);

    PictureBox显示图片的控件
    属性 SizeMode: StretchImage 将图片完整得显示在图片框里;
    PictureBox.Image = Image.FromFile(@"dizhi");
    操作文件的类是file,操作路径的类是path,操作文件夹的类是directory
    获得指定文件夹的所有文件的全路径
    string[] path = Directory.GetFiles(@"路径");
    设置图片如何在picturebox中显示 picturebox1.SizeMode = PictureBoxSizeMode.StretchImage;
    FileStream读不出word.excel这样的文件;读这样的文件要用.net提供的其他类库;

    ----------------------------------------------------------------------------------------------

    创建文件夹 Directory.CreateDirectory(@"路径名称");
    删除文件夹 Directory.Delete(@"路径名称");如果文件夹里面有东西,则删不了 回收站也没有,是个彻底删除的操作;
    删除文件夹 Directory.Delete(@"路径名称",true);即使里面有东西,也能删除; 回收站也没有,是个彻底删除的操作;
    剪切文件夹 Directory.Move("原路径","新路径");
    找到文件夹下.jpg结尾的文件    string[] path = Directory.GetFiles(@"路径","*.jpg");
    string[] path = Directory.GetDirectories();得到文件夹下所有文件夹的路径
    Directory.Exists("路径");是否存在这个文件夹;
    浏览器控件 webbrowser控件,很多窗体应用程序里都可以打开网页,用的就是Webbrower 主要属性是url,
    string text = Textbox1.Text;
    Uri uri = new Uri("http://"+text);
    WebBrower1.Url = uri;
    ComboBox.items.Add("张三"); 给combox添加内容;添加的类型是object;
    ComboBox.items.AddRange();添加集合;
    Combobox.items.Clear();把集合给清空;
    Dropdownstyle:控制下拉框的样式
    给combobox起名字的时候,一般都是cbo+...
    combobox默认的事件是selectindexchanged事件;
    为了防止连续添加,应该在添加之前,把原来的清空;
    想拿到combobox的值,用cbomonth.SelectedItem.Tostring();SelectedText和SelectedValue取不到
    str.split(new char[]{'月'},stringsplitoptions.RemoveEmptyEntries);
    ((year%400==0)||(year%4==0&&year%100!=0))判断闰年的条件;

    listbox1.items.Add() //往listbox里面添加元素;
    Path.GetFileName(); //得到路径中的文件名
    listbox常用事件 doubleclick
    listbox.SelectedIndex 当前选中项的索引;
    要把一部分要重复用到的代码写成一个方法的时候,选中要的代码,右键,重构,提取方法,写入方法名称
    如何出现对话框,无非就是创建对话框对象,打开对话框openfiledialog,保存对话框savefiledialog,字体对话框fontdialog,颜色对话框colordialog
    openfiledialog ofd = new openfiledialog();
    ofd.Title = "123";//设置对话框的标题;
    ofd.Multiselect = true; //设置对话框可以多选;
    ofd.InitialDirectory = @"...桌面的路径";//设置对话框打开的初始界面;
    ofd.Filter = "文本文件|*.txt|所有文件|*.*"; //显示你想要看的文件类型;
    ofd.showDialog; //设置属性一定要在对话框显示的前面设置,不然就没有用了;
    string path = ofd.FileName; //获得在打开对话框中选中文件的路径;
    string[] path = ofd.FileNames;
    using(FileStream fsrRead = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Read))
    {
      byte[] buffer = new byte[1024*1024*5];
      int r = fsrRead.Read(buffer,0,buffer.Length); //实际读取到的字节数;
      TextBox1.Text = Encoding.Default.GetString(buffer,0,r);
    }

    savefiledialog sfd= new savefiledialog();
    sfd.ShowDialog();
    sfd.Title
    sfd.InitialDirectory
    sfd.Filter
    string path = sfd.FileName;//获得路径;
    using(FileStream fsWrite = new FileStream(path,FileMode.OpenOrCreate,FileAccess.Write))
    {
      byte[] buffer = Encoding.Default.GetBytes(TextBox1.Text);
      fsWrite.Write(buffer,0,buffer,length);
    }

    FontDialog fd = new FontDialog();
    fd.ShowDialog();
    textBox1.Font = fd.Font;


    colordialog cd = new colordialog();
    cd.ShowDialog();
    textBox1.ForeColor = cd.Color;

    工具箱,容器,Panel
    Panel.Visiable = false; //在Panel中的控件也都消失了;
    工具箱,菜单和工具栏中有MenuStrip就是菜单栏;拖进去即可;
    string FileName = Path.GetFileName(path); //用Path类获得路径中的文件名
    .....ToolStripMenuItem.Text == "";获得菜单栏的文本
    进程可以理解为每一个应用程序都是一个进程;.net操作进程的类是process
    Process[] pros = Process.GetProcesses(); //类名.方法名调用这个静态方法,得到计算机正在运行的所有进程,返回进程类型的数组;
    Process pro = new Process();
    pro.kill();关闭进程;
    Procsee.Start("calc"); 通过进程的方式打开计算机;
    Procsee.Start("mspaint");
    Procsee.Start("notepad");
    Procsee.Start("iexplore","www.baidu.com");
    //通过进程打开指定的文件;
    Process pro = new Process();//创建进程对象;
    processinfo psi = new processinfo(@"文件路径"); //创建的原因,p.start的时候需要这种类型的对象;
    pro.StartInfo = psi;
    p.start();
    每一个进程都是由多个线程组成的;
    单线程给我们带来的问题;
    winform中要看到输出就在调试,窗口,输出打开即可;
    在VS中,每运行一个程序,计算机都会分配一个主线程(只有一个)来执行这样的一个程序,
    拖动窗体,操作窗体都是主线程在做的事;如果主线程去干别的事了,那么窗体就会出现假死;
    VS中操作线程的类是Thread
    创建一个线程对象
    Thread th = new Thread(Test);//传进去的是让线程执行的方法(委托); 这个是线程,但不是主线程;
    private void Test()
    {
      for(int i = 0;i < 10000;i++)
       {
         Console.WriteLine(i);
        }
    }
    th.start() //标记这个线程准备就绪了,可以随时被执行;线程执行是由CPU决定,我们是不能手动的调用线程的;
    调用方法占一个线程?
    线程分为2种,一种是前台线程,一种是后台线程;
    前台线程:只有所有的前台线程都关闭才能完成程序关闭;
    后台线程:只要所有的前台线程结束,后台线程自动结束;
    我们默认情况下自己创建的线程都是前台线程;
    主线程也属于前台线程
    把线程设置为前台线程 th.IsBackground = true;
    单线程的弊端;
    1.如果让程序做很多程序,会出现假死的状态;多线程的目的就是为了能让程序做多件事情;
    主窗体和窗体中的控件是由主线程创建的,
    Thread th = new Thread(Test);
    private void Test()
    {
      for(int i = 0;i < 10000;i++)
       {
         TextBox1.text = i; //如果改成这样就出错了,因为TextBox1是主线程创建的,而th是我们的新线程,出现了新线程去访问主线程的资源,在.netframework下是不允许跨线程的访问的;
        }
    }
    th.start()
    在执行上述代码的时候,如果在运行过程中关闭程序,就可能出现错误,错误是释放资源出错,因为主线程关了,导致了文本框等消失了,此时新线程还没有结束,但是没有文本框了,不能访问了,
    所以报错了;
    解决办法是在FormClosing事件里判断新线程是否为null;如果为null的话,说明他已经关了,如果不为null,就把它关闭;
    if(th != null)
    {
      th.Abort();//结束这个线程,当线程被结束之后,就不能start了;
    }
    Contral.CheckForIllegalCrossThreadCalls = false; 取消检查跨线程访问,写在FormLoad事件里
    Control类是winform所有控件的基类;
    Thread.Sleep(1000)  静态方法,可以使当前线程停止一段时间运行;1000表示1000毫秒;
    Name线程名
    Thread.CurrentThread获得当前的线程引用;
    我们不能通过代码操作CPU

    string[] path = ofd.FileNames; //得到打开框里所有的文件;
    //把多选的文件加入到列表框当中;
    for(int i = 0; i < path.length;i++)
    {
      listbox1.Items.Add(Path.GetFileName(path[i]));
    }
    点击播放下一首
    int index = listbox1.SelectedIndex;
    index++;
    if(index == listbox1.Items.Count)
    {
      index = 0;
    }
    listbox1.SelectedIndex = Index; //这句话很关键,必须把新索引复制给listbox1.SelectedIndex;不然索引是没变的;
    线程分为前台线程和后台线程,我们应该使用后台线程;
    Thread th = new Thread(Test);
    private void Test(string s)
    {
      for(int i = 0;i < 10000;i++)
       {
         Console.WriteLine(i);
        }
    }
    程序报错,原因如下;
    如果线程执行的方法需要参数,那么要求这个参数必须是object类型;
    Thread th = new Thread(Test);
    th.IsBackground = true;
    th.Start("123");

    private void Test(object s)
    {
      for(int i = 0;i < 10000;i++)
       {
         Console.WriteLine(i);
        }
    }
    //这样就不会出错了;

    摇奖机
    外面
    bool b = false;

    private void PlayGame()
    {
      Random  r = new Random();
      while(b)
      {
        label1.Text = r.Next(0,10).ToString();
        label2.Text = r.Next(0,10).ToString();
        label3.Text = r.Next(0,10).ToString();
       }
    }
    按钮单击事件中:
    if(b == false)
    {
      b = true;
      Button1.Text = "停止";
      Thread th = new Thread(PlayGame);
      th.background = true;
      th.start();
    }
    else
    {
      b = false;
      Button1.Text = "开始";
    }

    FormLoad事件中:
    Contral.CheckForIllegalCrossThreadCalls = false;

    // avg = Convert.ToDouble(avg.ToString("0.00")); 真正的保留两位,原值改变了
    // Console.WriteLine("{0:0.00}" , avg);输出的时候保留两位,原值没变;

    通过冒泡排序对整数数组{ 1, 3, 5, 7, 90, 2, 4, 6, 8, 10 }进行升序排列
    int[] nums = { 1, 3, 5, 7, 90, 2, 4, 6, 8, 10 };
    for(int i = 0;i < nums.length - 1;i++)
    {
        for(int j = 0; j < nums.length - 1-i;j++)
            {
               if(nums[j] > nums[j+1])
                {
                   int temp = nums[j];
                   nums[j] = nums[j+1];
                   nums[j+1] = temp;  
                }
             }
    }
    升序最快 Array.sort(nums);
    降序  Array.Reverse(nums);


      while (index != -1)
                {
                    i++;
                    index = str.IndexOf("咳嗽",index + 1);
                    if (index == -1)
                    {
                        break;
                    }
                    Console.WriteLine("第{0}次出现咳嗽的位置是{1}", i, index);

      //搜索一个词在字符串中出现几次,在那个位置的关键方法;

    "  hello      world,你  好 世界   !    "
    string[] sNew = str.Split(new char[]{''},StringSplitOptions.RemoveEmptyEntries);
    string strNew = string.join("",sNew);

    string s = "";
    string ss = " ";
    这两个不是一个东西,上面那个是空,下面那个不为空,有个空格字符串;


    Reverse()方法是
    for(int i = 0 , i<str.length/2,i++)
    {
       int temp = str[i];
       str[i] = str[str.length-1-i];
       str[str.length-1-i] = temp;
    }

    如果要把一个方法重写,就要把他标记为virtual,或者是abstract的,普通的方法不能去重写;


     private string name;
            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            public string Name
            {
                get;
                set;
            }

    下面那种是自动属性,跟上面那种是一样的效果;

  • 相关阅读:
    delphi正则表达式
    delphi将字符串转换成stringlist
    spring中@Conditional注解
    spring中@Profile的作用
    spring中的bean的生命周期
    java新特性stream
    lambda表达式
    springBoot--组合注解RestController,GetMapping,PostMapping
    idea配置svn,jdk,maven
    一次记录 java非web项目部署到linux
  • 原文地址:https://www.cnblogs.com/hhsfrank/p/4342628.html
Copyright © 2011-2022 走看看