• .Net学习笔记——细节问题


    本篇是《ASP.NET编程技巧》(http://blog.csdn.net/zhouwen/archive/2010/09/16/5889330.aspx)的姊妹篇,记录.Net学习笔记——细节问题!有的时候,细节决定成败!

    (1)如何判断2个字符串对象是否指向同一个引用?

    string s1 = "aa";
    string s2 = "aa";
    MessageBox.Show(object.ReferenceEquals(s1,s2).ToString());  //true


    char[] ch = { 'a', 'a' };
    string s1 = new string(ch);
    string s2 = "aa";
    MessageBox.Show(object.ReferenceEquals(s1,s2).ToString());  //false
    (2)获取本机IP地址。
     public static IPAddress[] GetLocalhostIPv4Addresses()
            {
                String LocalhostName = Dns.GetHostName();
               IPHostEntry host = Dns.GetHostEntry(LocalhostName);
                List<IPAddress> addresses=new List<IPAddress>();
                foreach (IPAddress ip in host.AddressList)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                        addresses.Add(ip);
                }
                return addresses.ToArray();
            }

    (3)如何把窗体坐标转换成屏幕坐标?
           private void Form4_MouseMove(object sender, MouseEventArgs e)
            {
                 textBox1.Text = string.Format("x:{0},y:{1}", e.X,e.Y);
                 Point p = new Point(e.X, e.Y);
                 p=this.PointToScreen(p); //把窗体坐标转换成屏幕坐标
                textBox2.Text = string.Format("x:{0},y:{1}", p.X,p.Y);
                p = this.PointToClient(p);
                textBox3.Text = string.Format("x:{0},y:{1}", p.X, p.Y);
            }
    (4) 窗体显示帮助按钮
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
    this.HelpButton = true;
    this.MaximizeBox = false;
    this.MinimizeBox = false;
    点击帮助按钮,显示chm格式的帮助文件?

    处理窗体的HelpButtonClicked事件:

    System.Diagnostics.Process.Start("ArticleCollectorAPI.chm");

    (5)控件的Anchor、Dock属性区别
    Anchor用于设置控件与窗体边缘的距离保持不变!
    Dock用于设置控件紧贴窗体的某个边缘或者填充整个窗体。

    (6)使用DataGridView显示、更新、删除数据

     string connstr = @"server=.\sqlexpress;initial catalog=MySchool;uid=sa;pwd=sa2008";
     DataSet ds = new DataSet();
    SqlDataAdapter da;

    //显示数据

    private void LoadData()
    {
                string strwhere;
                if (comboBox1.Text == "男")
                    strwhere="sex='男'";
                else
                    if (comboBox1.Text == "女")
                        strwhere="sex='女'";
                    else
                        strwhere="sex='男' or sex='女'";
                    string sql = "select StudentId,StudentNo,StudentName,Sex from Student where " + strwhere;
                    da = new SqlDataAdapter(sql, connstr); 

                    ds.Tables.Clear();
                    da.Fill(ds);
                    dataGridView1.DataSource = ds.Tables[0];

                }
    //更新数据

            private void button2_Click(object sender, EventArgs e)
            {

              //自动产生更新数据库的SQL语句,但其数据必须是来自同一个数据表。否则,更新失败!
                SqlCommandBuilder cmdb = new SqlCommandBuilder(da);            

               da.Update(ds);
                LoadData();
            }

    //删除数据

           private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                if (dataGridView1.SelectedRows.Count== 0)  //SelectionMode属性用FullRowSelect
                {
                    MessageBox.Show("请选择!");
                    return;
                }
                if (MessageBox.Show("确认要删除吗?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    using (SqlConnection conn = new SqlConnection(connstr))
                    {
                        string sql = "delete from Student where StudentId=" + (int)dataGridView1.SelectedRows[0].Cells[0].Value;
                        SqlCommand cmd = new SqlCommand(sql, conn);
                        conn.Open();
                        cmd.ExecuteNonQuery();
                    }
                    LoadData();
                }
            }


    (7)关闭主窗体,出现是否退出的对话框:

           private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (MessageBox.Show("确定要退出吗", "系统消息", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {

                    e.Cancel = true;
                }
            }

            private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
            {

                Application.Exit();            
            }

           //“退出”菜单的事件代码

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

    (8)JavaScript访问服务端控件:

        服务端控件声明:       

          <asp:TextBox ID="txtName" onblur="CheckName()" runat=server></asp:TextBox><span id="error" style="color:Red"></span><br />

        对应的JavaScript代码:
        function CheckName()
        {
            if(document.forms(0).txtName.value.length!=6)
            {
                document.getElementById("<%= txtError.ClientID%>").value="error";
            }
            else
                document.getElementById('error').innerHTML="";
        }

    (9)表单回发之后,保留密码框中的密码

           一般来说,当表单回发之后,密码框将会被自动清空。但是有些时候,我们并不希望这样。这时,我们可以添加下面的代码来避免这个问题。

    protectedvoidPage_Load(objectsender,EventArgse)

    {

        if(IsPostBack)  //如果是页面回发

        {

        if(!(String.IsNullOrEmpty(txtPassword.Text.Trim())))    

        {

               txtPassword.Attributes["value"]=txtPassword.Text;

            }

       }

    }

    (10)重写Equals 方法判断对象是否相等

          默认情况下,Object类的Equals()方法用于判断2个对象是否相等,是比较2个对象是否引用同一个对象。如果要支持值相等,则需要重写Equals虚方法。

            public override bool Equals(object obj)
            {
                //将要比较的对象转换为当前类型
                Student target = obj as Student;

                //如果为空、类型不同
                if( target == null)
                    return false;

                if (target.name == this.name &&
                    target.gender == this.gender &&
                    target.age == this.age)
                {
                    return true;
                }
            return false;
            }

    (11)FileDialog的FilterIndex属性

    注意msdn中的描述:

    The index value of the first filter entry is 1.不是0.

    (12)FileDialog的RestoreDirectory属性

    msdn中的描述:假设用户在搜索文件的过程中更改了目录,那么,如果对话框会将当前目录还原为初始值,则值为 true;反之,值为 false 默认值为 false。看了这个描述,是不是还是糊里糊涂的 o(∩_∩)o

    其实,这个属性其实是控制当前程序中的System.Environment.CurrentDirectory的,也就是,当属性设置为true时,System.Environment.CurrentDirectory永远是程序从中启动的文件夹目录;而设置为false是,则每次使用OpenFileDialog选择完文件后,System.Environment.CurrentDirectory会变成最后一次打开文件的目录。

    (13)页面刷新后保持滚动条不动,还在原来的位置

    ASP.NET 2.0里提供了这样的一个方案,可以通过设置

    <%@ Page MaintainScrollPositionOnPostBack="true"  %>

    或在编码里设置

    Page.MaintainScrollPositionOnPostBack= true;

    或在web.config里设置

    <pages maintainScrollPositionOnPostBack="true" />

    来达成。

     (14)操作SQL Server数据库的bit字段

    在SQL Server数据库的bit字段的值为1,或者是0。因此,向数据库中新增或修改时,该字段的值要为1或者是0。

    但从数据库中取出bit字段的值时,对应的值为true或者为false。

    (15)使用GUID

    GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成GUID的API。生成算法很有意思,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。GUID的唯一缺陷在于生成的结果串会比较大。
    1. 一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,你可以在所有计算机和网络之间使用这一整数。

    2. GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。例如:337c7f2b-7a34-4f50-9141-bab9e6478cc8 即为有效的 GUID 值。

    3. 世界上(Koffer注:应该是地球上)的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。

    .NET中使用GUID

    GUID 在 .NET 中使用非常广泛,而且 .NET Framework 提供了专门 Guid 基础结构。
    Guid 结构的常用法包括:
    1) System.Guid.NewGUID()
    生成一个新的 GUID 唯一值
    2) System.Guid.NewGUID() ToString()
    将 GUID 值转换成字符串,便于处理

    1、Guid.NewGuid().ToString("N") 结果为:
        38bddf48f43c48588e0d78761eaa1ce6
    2、Guid.NewGuid().ToString("D") 结果为:
        57d99d89-caab-482a-a0e9-a0a803eed3ba
    3、Guid.NewGuid().ToString("B") 结果为:
        {09f140d5-af72-44ba-a763-c861304b46f8}
    4、Guid.NewGuid().ToString("P") 结果为:
        (778406c2-efff-4262-ab03-70a77d09c2b5)
    可见默认的为第2种效果

    同样,SQL Server也很好地集成了GUID的用途。SQL Server数据类型uniqueidentifier能够存储一个GUID数值。你可以通过使用NEWID()函数在SQL Server中生成这一数值,或者可以在SQL Server之外生成GUID,然后再手动地插入这一数值。

    (16)内容页访问母版页控件

    在子页中可以通过事件来访问母版页的控件属性

    方法一如下:
      (1)说明:  通过Master对象查找控件的形式转换为对应的控件类型
     示例:this.lblContent.Text = (Master.FindControl("lblTime") as Label).Text;
    this.lblContent.Text = (Master.FindControl("lblTime") as Label).Text;
    (2)必须在子页面一些指定的方法里面
     protected void Page_LoadComplete(object sender, EventArgs e)
        {
            this.lblContent.Text = (Master.FindControl("lblTime") as Label).Text;
        }
        其中,“Page_LoadComplete”是内容页面加载完成时触发的一个事件。
    (3)也可以在事件中操作母版页功能
           protected void Button1_Click(object sender, EventArgs e)
        {
            (Master.FindControl("lblTime") as Label).Text = "HeLLO you";
        }

    方法二 通过强引用

    <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
    <%@ MasterType VirtualPath="~/MasterPage.master" %>

    然后可以在母版页中定义公共属性或方法
    public string GetUserName()
    {
         return Page.User.Identity.Name;
    }
    在内容页中调用
     Label1.Text = "欢迎光临" + Master.GetUserName();

    (17)转到前一页

    方法一:
     在asp.net的aspx里面的源代码中
    <input type="button onclick="javascript:window.history.go(-1);"value="返回上一页">
    浅析:这个是用了HTML控件,通过一个onclick的事件,调用了javascript中的一个方法就可以了。这个是最简单的了,也同样适用于静态页面,ASP页面等。
    方法二:
    利用Reponse.Write
    Response.Write("<script language=javascript>history.go(-2);</script>)
    <a   href="#"   onclick="javascript:history.back();">返回前一页</a>
    因为在asp.net中的页面,当你按下一个button后,由于页面中会实现page.postback的缘故,实际上在这其中是刷新了两次页面,我们要的是第一次的,所以就......
    方法三
    利用Response.Redirect() 或 Server.Transfer()
    在page_load中加入:
    if(!IsPostBack)  
       ViewState["retu"]=Request.UrlReferrer.ToString();      
    而后在返回按钮事件中加入:   
      Response.Redirect(ViewState["retu"].ToString());  
      或Server.Transfer   (ViewState["retu"].ToString());  
    Request.UrlReferrer可以获取客户端上次请求的url的有关信息,我们在使用这个的时候最好对其进行一个判断
    if(ViewState["UrlReferrer"]!=null)
        Response.Redirect(ViewState["UrlReferrer"].ToString();
    else
     Response.write("对不起,当前是最前页码“);
    在使用Request.UrlReferrer时还要注意:
    1.  如果上一页面使用document.location方法导航到当前页面,Request.UrlReferrer返回空值
    2.  如果有A,B两个页面,在浏览器中直接请求A页面,在A页面的中Page_Load事件中导航到B 页面,则    Request.UrlReferrer返回空。因为在Page_load事件中页面还未初始化,所以无法记录当前页的信息,导航到b页面也就无法获得上一页面的信息  
    3.  点击刷新按钮不会改变Request.UrlReferrer
    方法四:
    在button的onClick事件中输入
    this.RegisterClientScriptBlock("e", "<script language=javascript>history.go(-2);</script>");

    (18)Web.config中注册用户控件和自定义控件

         在ASP.NET 的早先版本里,我们通过在页面的顶部添加 <%@ Register %> 指令来引入和使用自定义服务器控件和用户控件时,象这样:
      <%@ Register TagPrefix="scott" TagName="header" Src="Controls/Header.ascx" %>
      <%@ Register TagPrefix="scott" TagName="footer" Src="Controls/Footer.ascx" %>
      <%@ Register TagPrefix="ControlVendor" Assembly="ControlVendor" %>
      <html>
      <body>
      <form id="form1" runat="server">
      <scott:header ID="MyHeader" runat="server" />
      </form>
      </body>
      </html>
      注意到上面的前两个注册指令是用来注册用户控件的(是在.ascx文件里实现的),最后这个是用来注册编译进一个程序集 .dll 文件里的自定义控件的。注册完后,我们能够在页面的任何地方用设定好的 tagprefix (标识前缀)和标识符号名( tagname)来声明这些控件。这行之有效,但管理起来会很痛苦,当我们要在我们的网站的许多页面上使用控件的话,尤其是,假如你移动了.ascx 文件,需要更新所有的注册声明的话。
      处理方案:
      ASP.NET 2.0 使得控件声明极其干净而且管理起来极其容易。不用在页面上重复这些声明,只需在应用的web.config 文件的新的 pages->controls 部分声明一次即可:
      <?xml version="1.0"?>
      <configuration>
      <system.web>
      <pages>
      <controls>
      <add tagPrefix="scottgu" src="~/Controls/Header.ascx" tagName="header"/>
      <add tagPrefix="scottgu" src="~/Controls/Footer.ascx" tagName="footer"/>
      <add tagPrefix="ControlVendor" assembly="ControlVendorAssembly"/>
      </controls>
      </pages>
      </system.web>
      </configuration>
      能够用这种方式同时声明用户控件和编译好的自定义控件。当使用这个技巧时,Visual Studio是完全支持这两者的,而且 VS 2005 Web Site 项目 和 VS 2005 Web Application 项目也都支持这两者。Visual Studio会在设想器里以所见即所得(WYSIWYG)模式显示这些控件,也会在后台编码文件里提示控件字段的声明。
      一旦你在web.config 文件中声明好这些控件后,就能够在你网站上的任何一个页面,母板页或者用户控件中使用它们了,象这样(不再需要注册指令):
      <html>
      <body>
      <form id="form1" runat="server">
      <scottgu:header ID="MyHeader" runat="server" />
      </form>
      </body>
      </html>

    但要注意:如果在Web.config中注册用户控件ASCX控件文件跟ASPX页面文件不能放在同一个目录下,否则会报错。

    (19)WinForm中将Form显示在Panel中(C#)

    pnlOPContainer.Controls.Clear();//移除所有控件
    FrmAddUser frmAddUser = new FrmAddUser();
    frmAddUser.TopLevel = false;
    frmAddUser.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    pnlOPContainer.Controls.Add(frmAddUser);
    frmAddUser.Show();

    (20)DBNULL和NULL

    Null是.net中无效的对象引用。
    DBNull是一个类。DBNull.Value是它唯一的实例。它指数据库中数据为空时,在.net中的值。
    null表示一个对象的指向无效,即该对象为空对象。
    DBNull.Value表示一个对象在数据库中的值为空,或者说未初始化,DBNull.Value对象是指向有效的对象。
    DBNull在DotNet是单独的一个类型 System.DBNull 。它只有一个值 DBNull.Value 。DBNull 直接继承 Object。
    这里容易犯的一个错误是,把ExecuteScalar返回DBNull与null的情况混淆,例如:
    string sql = string.Format("SELECT SUM(Cost) FROM CardRecord WHERE CardNO ='{0}'",txtCardNO.Text);
    如果没有数据,这里就会出错。
    你可以用Convert.IsDBNull来判断一个值是否DBNull。
    if (Convert.IsDBNull(command.ExecuteScalar()) == true)
    {
        MessageBox.Show("no");
        connection.Close();
        return;
    }
    注意Convert.IsDBNull(null)是false,也就是说null跟DBNull.Value是不等的。

    (21)装箱和拆箱

    object o = 2.56;
    float f = (float)o;//运行时报异常。
    C#中有两种类型变量,一种是值类型变量, 例如:int,   float,double等等;
    另一种是引用类型变量例如:string,用class定义的类型等等;
    那么这两种类型变量的区别是,前一个是分配在栈中,后一个是分配在堆中。
    对于如下操作
    object   obj   =   0.0;
    在c#中称为装箱操作,即把本应该放在栈中的数据放在堆中。
    那么如果要拆箱,即把object返还成float变量,
    不能用
    float   f2   =   (float)(obj);
    去获得,而要用
    float   f2   =   float.Parse(obj.ToString());
    为什么前者不行呢,因为如果float存在栈中,长度是固定的。但是通过object来存放在堆中,
    那么它的长度就不仅仅是float数据的长度,还要包括一些其他信息,那么按照第一种方法进行强转的时候,
    很可能按照object存放的起始位置,以及float的变量长度,是无法把相应字节转换成float变量,因此会产生异常。
    下面的代码是可以的:
    object o = 2.56f;
    float f = (float)o;

  • 相关阅读:
    FastDFS安装配置过程中出现错误提示"/home/yuqing/fastdfs" can't be accessed, error info: No such file or directory
    dubbo-monitor安装监控中心,管理控制台安装网页一直访问不到,解决bug的方式记录
    dubbo-monitor安装监控中心,管理控制台安装
    zookeeper伪分布式集群安装
    zookeeper单节点安装
    JedisCluster操作redis集群demo
    Redis Cluster集群的搭建
    redis3.0.6安装配置
    Windows注册表中修改CMD默认路径
    eclipse中使用mybatis-generator逆向代码生成工具问题解决记录
  • 原文地址:https://www.cnblogs.com/zhouhb/p/1957336.html
Copyright © 2020-2023  润新知