置顶随笔

[置顶]执子之手--与子偕老

 

谁,吻我之眸,遮我半世流离;

谁,抚我之面,慰我半世哀伤;

谁,携我之心,融我半世冰霜;

谁,扶我之肩,驱我一世沉寂。

谁,唤我之心,掩我一生凌轹。

谁,弃我而去,留我一世独殇;

谁,可明我意,使我此生无憾;

谁,可助我臂,纵横万载无双;

谁,可倾我心,寸土恰似虚弥; 

谁,可葬吾怆,笑天地虚妄,吾心狂。

伊,覆我之唇,祛我前世流离; 

伊,揽我之怀,除我前世轻浮。

  

执子之手,陪你痴狂千生;

深吻子眸,伴你万世轮回。

执子之手,共你一世风霜;

吻子之眸,赠你一世深情。

我, 牵尔玉手, 收你此生所有;

我, 抚尔秀颈, 挡你此生风雨。 

予,挽子青丝,挽子一世情思;

予,执子之手,共赴一世情长;

曾,以父之名,免你一生哀愁;

曾,怜子之情,祝你一生平安!

 

posted @ 2011-08-25 17:38 青蛙學堂 阅读(309) | 评论 (1)编辑 收藏

2020年8月5日

Layui table 示例


Layui table 示例

 <link rel="stylesheet" href="lib/layui/css/layui.css" media="all">

 
    
<table id="demo" lay-filter="test"></table>
 
<script src="lib/layui/layui.js"></script>
<script>
    layui.use('table', function () {
        var table = layui.table;

        //第一个实例
        table.render({
            elem: '#demo'
          , height: 312
        //  , url: '/demo/table/user/' //数据接口
          ,  url: 'common/Getdatatwo.ashx' 
          , page: true //开启分页

            , edit: true

          , cols: [[ //表头
               { checkbox: true },
              //  { checkbox: true,type: 'checkbox', width: 100, title: '选择' },
            //  { type: 'checkbox', width: 100, title: '选择' },
           // { field: 'ID', title: 'ID', width: 80, sort: true, fixed: 'left' }
            , {  field: 'yuefen',   title:'月份', width: 80 }
            , { field: "state", title: "状态", width: 80, sort: true }
            , { field: "state2", title: "状态2", width: 80, event: 'setSign', style: 'cursor: pointer;' }
            , {  field: "empname",   title: "操作员" , width: 177 ,edit:true }
            , { field: "createdate", title: "时间", width: 180, sort: true }
           
              
             , { fixed: 'right', width: 250, align: 'center', toolbar: '#barDemo' } //这里的toolbar值是模板元素的选择器
           
          ]]

//*********************************
 , page: { theme: '#409eff', prev: '上一页', groups: 8, next: '下一页', layout: ['count', 'prev', 'page', 'next'] }
       
         

//********************************
        });

        //*******************************

        //监听行单击事件
        table.on('row(test)', function (obj) {
         //   console.log(obj.tr) //得到当前行元素对象
          //  console.log(obj.data) //得到当前行数据

           // alert(obj.data.yuefen);
          
            //obj.del(); //删除当前行
            //obj.update(fields) //修改当前行数据
        });

        //监听行双击事件
        table.on('rowDouble(test)', function (obj) {
            //obj 同上
        });
        //监听复选框选择
        table.on('checkbox(test)', function (obj) {
            alert(obj.checked);
            alert(obj.data.ID);
            console.log(obj.checked); //当前是否选中状态
          //  console.log(obj.data); //选中行的相关数据
            console.log(obj.type); //如果触发的是全选,则为:all,如果触发的是单选,则为:one
        });

        //编辑
        table.on('edit(test)', function (obj) { //注:edit是固定事件名,test是table原始容器的属性 lay-filter="对应的值"
            alert("1122" + obj.value);
            console.log(obj.value); //得到修改后的值
            console.log(obj.field); //当前编辑的字段名
            console.log(obj.data); //所在行的所有相关数据  
        });

        //监听单元格事件
        table.on('tool(test)', function (obj) {

          

            var data = obj.data;
            if (obj.event === 'setSign') {

                alert("eeeeeee:" );
                //同步更新表格和缓存对应的值
                obj.update({
                    state2: '7777777'
                });
                /*
                layer.prompt({
                    formType: 2
                  , title: '修改 ID 为 [' + data.id + '] 的用户签名'
                  , value: data.sign
                }, function (value, index) {
                    layer.close(index);

                    //这里一般是发送修改的Ajax请求

                    //同步更新表格和缓存对应的值
                    obj.update({
                        sign: value
                    });
                });
                
*/
            }
        });


        //监听工具条 
        /*
        table.on('tool(test)', function (obj) { //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
            var data = obj.data; //获得当前行数据
            var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
            var tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)

            if (layEvent === 'detail') { //查看
                //do somehing
            } else if (layEvent === 'del') { //删除
                layer.confirm('真的删除行么', function (index) {
                    obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
                    layer.close(index);
                    //向服务端发送删除指令
                });
            } else if (layEvent === 'edit') { //编辑
                //do something

                //同步更新缓存对应的值
                obj.update({
                    state2: '123'
                  , empname: 'xxx'
                });
            } else if (layEvent === 'LAYTABLE_TIPS') {
                layer.alert('Hi,头部工具栏扩展的右侧图标。');
            }
        });
        
*/

    });
</script>

    <script type="text/html" id="barDemo">
  <a class="layui-btn layui-btn-xs" lay-event="detail">查看</a>
  <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
  <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
  
  <!-- 这里同样支持 laytpl 语法,如: -->
  {{#  if(d.auth > 2){ }}
    <a class="layui-btn layui-btn-xs" lay-event="check">审核</a>
  {{#  } }}
</script>

posted @ 2020-08-05 10:35 青蛙學堂 阅读(2) | 评论 (0)编辑 收藏

2020年7月28日

Lambda表达式


一、简介  
  Lambda表达式来源于数学家Alonzo Church等人在1920~1930期间发明的Lambad积分。Lambda积分是用于表示函数的一套系统,它使用希腊字母Lambda( λ )来表示无名函数。

  C# 3.0引入了Lambda表达式,它是一种简化的匿名函数,可用于创建委托或表达式目录树。你也可以将 Lambda 表达式作为参数进行传递,或者将它作用于函数调用值调用后返回的一个函数来使用。

 

二、基础
  它的语法形式是: 输入参数 => 表达式或语句块  即运算符的左边是输入参数(如果有),右边是表达式或语句块。 ( “ => ” 读作 “ goes to ” )

  

  2.1 表达式Lambda
        表达式位于 => 运算符右侧的 lambda 表达式称为“表达式 lambda”。 表达式 Lambda 会返回表达式的结果,并采用以下基本形式:

    (input parameters) => expression

delegate int myDel(int x,int y);    //声明委托

class Program
    {
        static void Main(string[] args)
        {
            myDel del = (x,y) =>  x+y;    //返回x+y的结果
       Console.WriteLine("values {0}",del(5,8)); //输出13        Console.ReadKey();      }   }


有关Lambda表达式的参数列表要点如下:

♥ Lambda表达式参数列表中的参数必须在参数数量、类型和位置上与委托相匹配

♥    表达式参数列表中的参数不一定需要包含类型(隐式类型),除非委托有ref或out参数----此时必须注明类型(显式类型)

♥    如果只有一个参数,并且是隐式类型的,周围的圆括号可以被省略,否则必须有括号

♥    如果没有参数,必须使用一组空的圆括号

2.2  语句Lambda
    当lambda表达式中,有多个语句时,写成如下形式:

    (input parameters) => {  statement; }

delegate int myDel(string str);

    class Program
    {
        static void Main(string[] args)
        {
            myDel del = (str) =>
            {
                Console.WriteLine("hello {0}",str);
                return 123;
            };
            Console.WriteLine("values {0}",del("world"));
            Console.ReadKey();
        }
    }

    在C#的语法中有一种比较特殊的写法,叫做Lambda表达式,这种表达式的写法在于你查询数据的时候直接是使用以下箭头的形式来表示查询语句的:=>。例如,我们要查找学生的List<Student>集合中班级编号为1001的所有学生数据,我们即可用Studentlist.Where(t=>t.ClassCode=‘1001’)语句来直接完成,无需再写繁琐的foreach语句或者for循环。Lambda表达式的运算符即为=>。

一、Lambda表达式定义

        Lambda表达式实际上是一种匿名函数,在Lambda表达式中可以包含语句以及运算等操作。并且可用于创建委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内联表达式。使用Lambda表达式可大大减少代码量,使得代码更加的优美、简洁,更有可观性。

 

二、Lambda表达式的表现形式

       表达式形式:(Input Param)=>Expression。在表达式左侧的表示输入参数,右侧的为相应的运算语句或者判断语句等,可包含函数调用等复杂方式。运算符=>读作为goes to,例如下面这个表达t=>t.ClassCode='1001',多做goes to ClassCode equal 1001。

       在上述的表达式中,仅仅只有当参数只有一个的时候,括号是可选择的,例如下面这种含有两个参数时候的情况应该是这样子的写法

1
(a,b)=>a==b

  当表达式中的多个参数编译器无法自动判断类型的时候,则需要显式指定类型。

1
(int firstIndex, string str) => str.IndexOf('Hello') > firstIndex

 (1)查询班级编号为1001的班级下面的所有学生实体并返回到list1001中存储

1
var list1001=Studentlist.Where(t=>t.ClassCode==‘1001’);

 (2)查询班级编号为1001的班级下面的所有学生实体并返回到list1001中存储,并按照学生的出生日期从小到大排列。

1
var list1001=Studentlist.Where(t=>t.ClassCode==‘1001’).OrderBy(t=>t.BirthDay);

   在此说一下,OrderBy是从小到大排序,需要从大到小排列则用OrderByDescending。

 (3)查询班级编号为1001的班级下面的姓氏为【李】的同学的所有集合,并按照学生的出生日期从小到大排列。

1
var list1001=Studentlist.Where(t=>t.ClassCode==‘1001’&&t.StudentName.StartWith(“李”)).OrderBy(t=>t.BirthDay);

posted @ 2020-07-28 08:25 青蛙學堂 阅读(126) | 评论 (0)编辑 收藏

2020年7月27日

c# Mvc常用特性2


1.[Required] : 必须输入

[Required(ErrorMessage = "请输入用户名")]  
 

2.[StringLength] : 限制字符串长度

[StringLength(10, ErrorMessage = "长度不能超过10个字符")]  

3.[Range] : 限制取值范围

[Range(0, 120, ErrorMessage = "年龄范围在0到120岁之间")]  
 

4.[RegularExpression] : 必须符合某个正则表达式(1)直接使用RegularExpression来写表达式:

01.[RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "请输入Email格式")]  
02.public String RegualarExpressionField { getset; } 

posted @ 2020-07-27 13:49 青蛙學堂 阅读(2) | 评论 (0)编辑 收藏

c# Mvc常用特性


 介绍一些在开发中非常有用的MVC特性,如下:

BindAttribute
Remote
HandleError
HiddenInput

1.BindAttribute
使用BindAttribute的目的是限制用户在提交form表单时使用合适且正确的值。当我们提交一个表单时,就会检查每一个实体上绑定的特性。

假设我们已经有下面一个Employee实体类:

public class Employee
{
    public string Name { getset; }
    public string Email { getset; }
    public string Address { getset; }
    public string PhoneNo { getset; }
}

现在如果我们只想提交Email,Name和PhoneNo,而我们不想提交地址,这时我们可以在实体类上添加如下特性:
[Bind(Exclude="Address")]
   public class Employee
   {
       public string Name { getset; }
       public string Email { getset; }
       public string Address { getset; }
       public string PhoneNo { getset; }
   }

BindAttribute要在System.Web.Mvc命名空间下使用,使用BindAttribute,我们可以在提交表单时对字段进行一些控制。在下面的图中,我们已经在提交的form数据中得不到Address的值了。

我们也可以将BindAttribute直接用在Action的参数中,像下面这样:

public Actionresult emprigister([Bind(Exclude="Address")],Emploree emp)
{
}

2.RemoteAttribute
假设我们有一个注册表单,里面有邮箱文本框,当输入邮箱后,我们想检查输入的邮箱是否在数据库中已经存在,如果存在,则不提交表单,这时我们可以使用RemoteAttribute,通过RemoteAttribute,我们可以在不用提交表单就可以先进行一些服务端验证。

我们可以在下面的例子中使用RemoteAttribute:

public class Employee
{
    public string Name { getset; }
    [Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")]
    public string Email { getset; }
    public string Address { getset; }
    public string PhoneNo { getset; }
}

RemoteAttribute的第一个参数是一个Action名字,第二个是Controller名字,第三个是如果邮箱已存在后显示给用户看的提示信息。当我们输入完邮箱后,CheckEmail方法将被执行并检查邮箱是否存在。
public JsonResult CheckEmail(string Email)
  {
      //Check here in database if it exist in database return true else false.
      return Json(false, JsonRequestBehavior.AllowGet);
  }


3.HandleError Attribute
我们已经有很多方法在MVC中处理异常,比如用try catch,或者使用Filter,或者通过第三方库比如elmah。但是MVC也提供了一个HandleErrorAttribute去处理异常,如下:

[HandleError()]
public ActionResult CheckError()
  {
     int a = 10;
     int b = 0;
     int k = a / b;
     return View();
  }

在web.config文件中,我们添加如下两行:

<customErrors mode ="On" defaultRedirect ="Error.cshtml">
</customErrors>

在shared文件夹下创建一个视图Error.cshtml,然后运行程序,如果运行上面的CheckError()方法,你刚创建的Error.cshtml将会显示出来。

我们也可以使用HandleErrorAttribute给不同类型的异常显示不同的视图页面。

[HandleError(ExceptionType=typeof(DivideByZeroException),View="DivideByZeroErrorView")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "NullRefrenceErrorView")]
public ActionResult CheckError()
       {
           int a = 10;
           int b = 0;
           int k = a / b;
           return View();
       }

4.HiddenInput Attribute
如果我们想对用户隐藏一些实体字段,我们可以使用HiddenInput特性。

public class Employee
    {
        [HiddenInput(DisplayValue=false)]
        public string Name { getset; }
        [Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")]
        public string Email { getset; }
        public string Address { getset; }
        public string PhoneNo { getset; }
    }

在以上的实体中,我用HiddenInput特性去描述Name字段。这样程序运行后在浏览器中Name字段将不在显示。因此HiddenInput给我们d 在实体字段上多了一些额外的控制。

posted @ 2020-07-27 13:38 青蛙學堂 阅读(3) | 评论 (0)编辑 收藏

2020年7月24日

boootstrap talbe多列checkbox设置


boootstrap talbe多列checkbox设置

boootstrap talbe 列值进行格式化操作:

 {
                          title: '审核',
                          field: '审核',
                        //  width: '10%',
                         // align: "left",
                          formatter: function (value, item, index,row) {
                              if (value == '1') {
                                  return '<input type="checkbox"   id="a_' + index + '" checked = "checked"/>';
                              }
                              else if (value == '0') {
                                  return '<input type="checkbox"  id="a_' + index + '" />';
                              }
                              else if (value == null) {
                                  return '<input type="checkbox"  id="a_' + index + '" />';
                              }
                          }
                      }

//***************************************************8

2. 在table的cell单击事件里取值赋值

 onClickCell:function(field, value, row, $element,index)
            {
               // alert("单击cell-" + value);
               // alert("单击cell-" + row.id);
               // if ($('#a_' + index).get(0).checked) {
                if ($('#a_' + index).is(':checked')) {
                    row.审核 = "1";
                } else {
                    row.审核 = "0";
                }

                alert(value+"单击cell-" + row.id);


            },

posted @ 2020-07-24 10:31 青蛙學堂 阅读(3) | 评论 (0)编辑 收藏

c# 抽象类和接口

抽象类与接口紧密相关。然接口又比抽象类更抽象,这主要体现在它们的差别上:1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声明必须用public来修饰没有具体实现的方法。3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。4)这一点也是最重要的一点本质的一点"抽象类是对象的抽象,然接口是一种行为规范"。
  以上是它们本身的异同,下面再来从实际应用讲讲它们的异同!
  不同之处:
  1、定义 
  抽象类表示该类中可能已经有一些方法的具体定义,但是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。
  1、用法 
  1)在继承抽象类时,必须覆盖该类中的每一个抽象方法,而每个已实现的方法必须和抽象类中指定的方法一样,接收相同数目和类型的参数,具有同样的返回值,这一点与接口相同。
  2)当父类已有实际功能的方法时,该方法在子类中可以不必实现,直接引用的方法,子类也可以重写该父类的方法(继承的概念)。
  3)而实现 (implement)一个接口(interface)的时候,是一定要实现接口中所定义的所有方法,而不可遗漏任何一个。
  4)另外,抽象类不能产生对象的,但可以由它的实现类来声明对象。
  有鉴于此,在实现接口时,我们也常写一个抽象类,来实现接口中的某些子类所需的通用方法 



对于C#初学者来说,abstract抽象类在网上的定义和解释说了一大堆,却往往我们忽视了为何要使用abstract类,使用它的意义在哪里。面试的时候也会有人问起使用它有什么好处,因为不适用它用自己定义的类也可以实现。那么为什么要使用抽象类?

那么我们什么时候应该用抽象类呢?
如果一个类设计的目点是用来被其它类继承的,它代表一类对象的所具有的公共属性或方法,那个这个类就应该设置为抽象类。

抽象类与其它的类有什么区别呢?
抽象类是不能够被实例化的。如果一个类中包含有抽象方法,那么这个类一定要声明为抽象类。同时,抽象方法一定需要在子类中重写,让抽象方法成为一个具体的实实在在的方法。

相信大家在网上一定看过很多这类解释了吧?好吧,不理解的我们一起来看看通俗易理解的说法吧:

比如说:我们需要创建 “狗”、“猫”、“鱼”、“马”这些对象(类),我们可以说他们有一些共同的属性像嘴巴、尾巴、重量、颜色、大小等等一些共同的属性(properties),但是它们彼此的属性的形状是不同的(如嘴巴),在这种情况下,我们如果一个个去定义各自类似的属性是不是比较繁琐?如果用抽象类是不是很方便的给他们去继承。抽象类也有个更加好的地方,体现在“同质异像”就是实质相同实现形式不同的方法继承上,例如上面的狗、猫、马等的呼吸这个方法或者跑的速度的方法形式不同,我们这个是用定义一个抽象方法,让他们各自的类去实现它是不是很方便。“抽象”的意义正在于此。将共同的东西抽出来封装,但不实现只给继承。

posted @ 2020-07-24 08:51 青蛙學堂 阅读(2) | 评论 (0)编辑 收藏

c# 使用接口

c#为什么要使用接口?通俗的讲,就是为了降低耦合度。给大家看一个我见过的很搞笑的例子。看看下面的程序:一个学校里边,有两种人:学生、老师。他们都要吃饭和睡觉。
------------------------------
public interface I人
{
    void 吃饭();
    void 睡觉();
}
public class 学生:I人
{
    public void 吃饭()
        { //去食堂吃饭 }
    public void 睡觉()
        { //回寝室睡觉 }
    //其他特有方法,比如泡妞、打游戏
}
public class 老师:I人
{
    public void 吃饭()
        { //回家吃饭 }
    public void 睡觉()
        { //回家睡觉 }
    //其它特有方法,比如为生儿育女传宗接代的历史使命努力等“不足为外人道也”的事情
}
public class 学校
{
    public void 开饭(I人 ren)
        { ren.吃饭(); }
    public void 放学(I人 ren)
        { ren.睡觉(); }
}
-----------------------------
    这里就用到了里氏代换原则,"开饭()"和"放学()"的参数都是人,那么这个地方如果换成学生和老师肯定也可以。
I人 某学生 = new 学生();
某学生.开饭();
某学生.放学();
这样执行的结果就是学生回寝室吃饭。
I人 某老师 = new 老师();
某老师.开饭();
某老师.放学();
这样执行的结果就是老师回家吃饭。
    为什么要这样写呢?这样写有什么好处呢? 我在开饭的时候完全可以直接调用“学生.吃饭();”、“老师.吃饭();”。接着看,有一天,学校里来了第三种人,家长。 家长既不是去寝室睡觉也不是回家睡觉,而是旅馆睡觉,既不是去食堂吃饭也不是回家吃饭,而是去下馆子。 这个时候学校这个系统该怎么处理呢? 如果原来没有定义"I人"这个接口那就麻烦啦,所有用到人的地方代码都要改。 现在不一样了,我可以直接定义一个类:家长,这个类实现人这个接口就可以了。 好,看代码:
------------------------------
public class 家长:I人
{
    public void 吃饭()
        { //下馆子 }
    public void 睡觉()
        { //去旅馆睡觉 }
    //其它特有方法,比如会见老师,晓之以钱,动之以利等等,不一而足
}
-------------------------------
    在调用的时候不需要修改任何代码,还和原来一样:
I人 某家长=new 家长();
某家长.开饭();
某家长.放学();
    轻松搞定家长的食宿问题! 这样一来学校来再多的客人都没关系啊,绝对可以应付自如,这也就是传说中的可扩展性!不知道大家看到这里是不是能够明白接口的作用。如果你还不明白,那么你把人这个接口去掉,自己写一个学校开饭和放学的类,然后再加一个家长这个新新人类进去,看看你的代码是什么样子的,再想一下在人口这么多的中国,万一哪天你的学校里来了成千上万个新新人类你该怎么办!
    先声明一下,这个案例可不是我想出来的~~但是很经典,是不?
    然后我们就很好理解了,为什么用别人的东西要实现接口呢?很直接的一个原因是这样一来,编程的复杂度就可能会大大降低了,不是么?

posted @ 2020-07-24 08:49 青蛙學堂 阅读(133) | 评论 (0)编辑 收藏

2020年7月23日

css计算宽度高度vh-vw

calc 是 css3提供的一个在css文件中计算值的函数:
     用于动态计算长度值。
     需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
     任何长度值都可以使用calc()函数进行计算;
     calc()函数支持 "+", "-", "*", "/" 运算;
     calc()函数使用标准的数学运算优先级规则;
calc(100vh - 10px)  表示整个浏览器窗口高度减去10px的大小 calc(100vw - 10px)   表示整个浏览器窗口宽度减去10px的大小 一般用来设置流式布局宽高,当然,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值 calc()的兼容性如下,使用时需注意
 
在讲calc之前先说一下 vh  vw:
    vw  相对于视口的宽度。视口被均分为100单位的vw
   vh  相对于视口的高度。视口被均分为100单位的vh
   vmax 相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax
   vmin 相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin

posted @ 2020-07-23 14:12 青蛙學堂 阅读(2) | 评论 (0)编辑 收藏

easyui多列checkbox-未测试

 $('#grid').datagrid({
              columns:[[
                  {field:'CODE_NM',title:'名称',align:'center',width:'40%'},
                  {field:'a',title:'选项A',width:'15%',align:'center',
                      formatter: function (value, rowData, rowIndex) {
                                  if(value=="1"){
                                      return '<input type="checkbox"  id="a_'+rowIndex+'" />';
                                  }else if(value="0"){
                                      return '<input type="checkbox"   id="a_'+rowIndex+'" checked = "checked"/>';
                                  }
                                
                            }},
                  {field:'b',title:'选项B',width:'15%',align:'center',
                      formatter: function (value, rowData, rowIndex) {
                                  if(value=="1"){
                                       return '<input type="checkbox"  id="b_'+rowIndex+'" />';
                                  }else if(value=="0"){
                                       return '<input type="checkbox"  id="b_'+rowIndex+'" checked="checked"/>';
                                  }
                               
                            }}
              ]],
              width:'100%',
              hight:'100%',
              rownumbers:true,
              title:'列表信息',
              url:"getDetail",
              onClickRow:function(index,row){
                  $('#grid').datagrid('clearSelections');
                  if($('#a_'+index).get(0).checked){
                      row.a = "0";
                  }else{
                      row.a = "1";
                  }
                  if($('#b_'+index).get(0).checked){
                      row.b = "0";
                  }else{
                      row.b = "1";
                  }                  
              },
              dataType:"json",
              type:'post',
              onLoadSuccess:function(data){
              }
          
          }); 

 

posted @ 2020-07-23 09:59 青蛙學堂 阅读(3) | 评论 (0)编辑 收藏

2020年7月22日

事件和委托的区别

前言:作为.Net攻城狮,你面试过程中是否遇到过这样的问题呢:什么是事件?事件和委托的区别?既然事件作为一种特殊的委托,那么它的优势如何体现?诸如此类…你是否也曾经被问到过?你又是否都答出来了呢?

关于面试中涉及到的事件的问题,我们只需要抓住几个关键点就好了:

(1)事件是委托的封装,可以理解为一种特殊的委托。

(2)事件里面其实就两个方法(即add_event()和remove_event())和一个私有的委托变量,这两个方法里面分别是对这个私有的委托变量进行的合并和移除,当调用事件的+=时其实是调用的事件里面的add_event()方法,同样-=调用的是remove_event()方法。

(3)事件只能够从对象外部增加新的响应方法和删除已知的响应方法,而不能主动去触发事件和获取其他注册的响应方法等信息。如果使用公有的delegate则不能做这些限制,也就是说事件对委托做了限制,使委托使用起来更加方便。也有人说事件是对委托的阉割,大概也是这个意思。

如果回答的时候抓住了以上的3点,那么我想你的面试应该不会太差。毕竟面试那么短的时间,有一两个亮点就很不错了,你说呢。哪怕你对事件机制完全不懂,为了面试记住其中两点也是很好的,工作经验咱们没有,换工作的经验可不能没有哦~~扯远了,关于面试就到此为止。如果你还想继续将事件了解透彻,别着急,慢慢往下看。

1、事件的定义及由来:

定义事件:

public delegate void MyStudyEvent(object sender, EventArgs e);
public class TestEvent
{
   public event MyStudyEvent eMyStudyEvent;
}
 

将这段代码生成dll后,通过反编译工具reflector我们可以看到:

c# 基础事件

正如上文所说,可以看到当定义一个事件public event MyStudyEvent eMyStudyEvent的时候,编译器会自动给他生成两个方法add和remove,以及一个private的委托变量eMyStudyEvent。我们将反编译代码copy出来看看。

可以看到这两个方法的主要作用就是在向private变量eMyStudyEvent里面添加委托和移除委托。当调用事件的+=和-=时,eMyStudyEvent里面就合并和移除传过来的委托,当事件触发的时候,eMyStudyEvent变量就执行。这样设计也正好符合封装的原则,保证了内部变量的安全性。

//私有委托变量
private MyStudyEvent eMyStudyEvent;
//add方法合并委托到eMyStudyEvent里面
public void add_eMyStudyEvent(MyStudyEvent value)
{
    MyStudyEvent event3;
    MyStudyEvent eMyStudyEvent = this.eMyStudyEvent;
    do
    {
       event3 = eMyStudyEvent;
       MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Combine(event3, value);
       eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3)
    }
    while (eMyStudyEvent != event3);
}
 
//remove方法移除eMyStudyEvent里面已存在的委托  
public void remove_eMyStudyEvent(MyStudyEvent value)
{
    MyStudyEvent event3;
    MyStudyEvent eMyStudyEvent = this.eMyStudyEvent;
    do
    {
        event3 = eMyStudyEvent;
        MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Remove(event3, value);
        eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3);
    }
    while (eMyStudyEvent != event3);
}

posted @ 2020-07-22 08:40 青蛙學堂 阅读(2) | 评论 (0)编辑 收藏

仅列出标题  下一页
<2020年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿(7)

随笔分类

随笔档案

收藏夹

青蛙学堂

最新评论

阅读排行榜

评论排行榜

60天内阅读排行