[转载]Asp.Net MVC 把PartialView、View转换成字符串

mikel阅读(1090)

[转载]Asp.Net MVC 把PartialView、View转换成字符串 – 徐明祥 – 博客园.

在开发中有时要在后台获得某个View 或者 PartialView 生成的字符串,只要你熟悉ASP.NET MVC  生命周期就能理解和敲出下面的代码。没什么高深的,直接上代码:

1,输出View HTML 字符串:
/// <summary>
/// 描述:输出View HTML 字符串
/// </summary>
/// <param name=”controller”></param>
/// <param name=”viewName”>视图文件名</param>
/// <param name=”masterName”>母板页文件名</param>
/// <returns></returns>
protected static string RenderViewToString(Controller controller, string viewName, string masterName)
{
IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
using (StringWriter writer = new StringWriter())
{
ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
viewContext.View.Render(viewContext, writer);
return writer.ToString();
}
}
2,输出PartialView HTML 字符串
/// <summary>
/// 描述:输出PartialView HTML 字符串
/// </summary>
/// <param name=”controller”></param>
/// <param name=”partialViewName”>部分视图文件名</param>
/// <returns></returns>
protected static string RenderPartialViewToString(Controller controller, string partialViewName)
{
IView view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
using (StringWriter writer = new StringWriter())
{
ViewContext viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
viewContext.View.Render(viewContext, writer);
return writer.ToString();
}
}

[转载]Webkit内核探究(2)——Webkit CSS实现

mikel阅读(1017)

[转载]Webkit内核探究【2】——Webkit CSS实现 – 李嘉昱 – 博客园

注:【转载请注明文章来源、保持原样】

出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660364.html
作者:李嘉昱

CSS在Webkit中的实现属于相对独立的一个模块,注意这里说的是相对。

CSS在Webkit中的作用自然是不言而喻的,在Web早期,文档的结构和样式还未分离的那个时代,HTML担负了文档的结构和样式这两个双重任 务,即HTML既负责文档的结构,同时文档的样式也通过HTML中通过标签的属性来指定。可想而知,在那个时候HMTL页面的开发和使用比起现在而言是多 么的不便。

不过仔细想想,这恐怕与当时的技术发展程度有着很大大关,首先,那个时候互联网远不像现在这样普及,另外,网页也远不如现在这样复杂,不像现在, 可以说,世界上信息的主要传播方式是以网页形式出现的,没数据说明,但我觉得至少趋势是这样的。 就这样,互联网在不断的前进之中,直到后来CSS的出现,大大的改进了Web的开发模式,从此,文档的结构和样式被清晰的一分为二。HTML主要负责文档 的结构,而CSS则担负着文档的样式指定。

关于CSS的介绍网上已经有很多了,在这里将主要从Webkit实现的角度对其进行介绍。

CSS是什么


CSS是Cascading Style Sheets的缩写,按照官方定义,它可以被认为是一个样式表语言,它允许用户通过它来为结构化文档(HTML文档)指定样式。通过使用CSS用户可以将文档的内容和样式分离,从而简化Web页面的开发和维护。

既然说它是一个样式表语言,那么它就有相应的语法规则,规定了如何如何来书写一个样式表,让其作用与文档内容达到书写者想要的外观。CSS的语法规 则是比较简单的, 自顶向下的来看,一个级联样式表(CSS)是由一系列的规则(rule)组成的, 每一条规则又是由一个选择器(selector)和若干条声明(Declearation)组成的。每条声明(Declearation)又是一个键值 对,由属性(property)和值(value)来组成,如下图所示。

原图片出处:http://dabrook.org/cc/Basic-Anatomy-of-a-CSS-Rule.png

从这里可以看到,语法是很简单的,使用起来也确实很简单。注意,我在这里只是说使用简单,就跟铅笔一样,谁都会用,铅笔的使用当然是简单的不能再简 单了,但是就是这样普通的工具,在专业人士和普通人的手里所能创造出的东西是截然不同的。所以我想说的是,你能很快的学会如何使用CSS并不代表你编织出 漂亮的网页,它只是一个工具,能发挥到什么程度还得看人。

转回来,从其简单的语法来看,似乎是只要简单的将其转化为对应的程序设计模型即可,但实际中,CSS的实现还是比较复杂的,其复杂性就在于,CSS 本身的复杂程度,它定义了一系列的规则来决定为哪些元素来指定样式,以及样式的继承关系,哪些是继承的,哪些是非继承的,以及作用于同一个元素的多个样式 的叠加,还有就是它对所有能指定的样式都有完整的对应的属性集。所以从实现的角度来看,一个完整的,兼容于标准的CSS实现,需要顾及到的东西还是很多 的。

CSS实现模型


webkit css部分的实现代码为于目录webcore/css中,算是webkit中一个相对独立的模块,下面类图是我为了更好的了解css实现所作,大致勾勒出了CSS的内部实现。

用户所书写的css文档,最终会转化为webkit内部的模型表示,这里有几个比较重要的类。

(待续…)

CSS默认样式表


从Webkit CSS的实现可以看到,即使你不指定任何样式表,实际上当CSS模块运作起来的时候,它都会载入几张默认的样式表,要知道,在 CSSStyleSelector的构造函数中,总是会调用loadDefaultStyle()这个函数,其作用就是载入默认的样式表。

这些默认的样式表包含了一些HTML元素的最基本的样式信息。相信在使用css的用户中,大多数人都不会在对<div>指定样式的时候 会为其添加一条display:block吧,是啊,几乎所有使用css html的人都知道div是一个块级元素,所以没人会多此一举,但是通过了解其CSS模块的具体实现,我们可以知道,这些个默认的样式表其实就已经为我们 指定了一系列我们认为的想当然的规则。

这四个默认样式表是

  • html4UserAgentStyleSheet
  • quirksUserAgentStyleSheet
  • svgUserAgentStyleSheet
  • sourceUserAgentStyleSheet

额,从名字上大致也能够了解1, 2了吧,它们不是以文件形式存储,而是在CSS中以字符数组的形式出现,也就是说作为数据编到代码里面去了,应该是考虑到每次都要使用默认样式表而为了减少I/O造成的性能损失。

为了说明我前面所说的,这些默认样式表描述的都是些个关于HTML元素的最基本的信息,还是来看个例子吧,

比如说html4UserAgentStyleSheet,从名字上可以看到,这张应该就是传说中的浏览器默认样式表了。看看都有些啥吧,这里只截取个片段。

1 html { 2 display: block 3  } 4 5 head { 6 display: none 7  } 8 9 meta { 10 display: none 11  } 12 13 title { 14 display: none 15  } 16 17 link { 18 display: none 19  } 20 21 style { 22 display: none 23  } 24 25 script { 26 display: none 27  } 28 29 body { 30 display: block; 31 margin: 8px 32  } 33 34 p { 35 display: block; 36 margin: 1.0__qem 0px 37  } 38 39 div { 40 display: block 41  } 42 43 layer { 44 display: block 45  }

从上面可以看出,真就是些最基本的属性的指定,如果没有这些默认值指定的话,用户还得自行添加这些规则,那会很麻烦。

其他几张表在此不作分析。

CSS解析


CSS使用的时候,只需要将按照其语法规范,书写一个规则集合,然后保存为一个.css文件,在html中引用即可,当然这里使用的是外部样式表的方式,只是使用CSS的一种方式,在这里我不打算讨论CSS的几种使用方式,所以都按外部的来。

那么这种按照语法规则书写的CSS样式表式如何转换为Webkit内部的CSS模型的呢,这自然需要通过词法语法分析。在这里,Webkit使用了 自动代码生成工具生成了相应的代码,也就是说词法分析和语法分析这部分代码是自动生成的,但它们不够完整,然后我们需要自己写一些配合性的代码才能让真个 CSS模块工作起来,说的再白一些,就是需要我们自己是写一些函数让那些个自动生成的代码来Call Back,用过其他各类解析器的朋友们应该很熟悉这个吧。如果谁对这部分代码有兴趣,可以研究一下。我倒是曾经为找一个跨平台的bug调过这部分代码,结 构还是蛮简单的,代码看起来稍多了些。入口是yylex和yyparse,有兴趣可以自己看看。

那么Webkit中实现的这些个Call Back们在哪里呢?就在CSSParser中了,显然,刨去生成的代码不说,需要手工完成的CSS解析代码部分就是这个了。CSS的一些解析功能的入口 也在此处,它们会调用lex,parse等生成代码。相对的,生成代码中需要的Call Back也需要在这里实现。

举例来说,现在可以来看一个较大单位的回调函数的实现,createStyleRule(),该函数将在一般性的规则需要被建立的时候调用。

1 CSSRule* CSSParser::createStyleRule(CSSSelector* selector) 2 { 3 CSSStyleRule* rule = 0; 4 if (selector) { 5 rule = new CSSStyleRule(styleElement); 6 m_parsedStyleObjects.append(rule); 7 rule->setSelector(sinkFloatingSelector(selector)); 8 rule->setDeclaration(new CSSMutableStyleDeclaration(rule, parsedProperties, numParsedProperties)); 9 } 10 clearProperties(); 11 return rule; 12 }

从该函数的实现可以很清楚的看到,解析器达到某条件需要创建一个CSSStyleRule的时候将调用该函数,该函数的功能是创建一个 CSSStyleRule,并将其添加已解析的样式对象列表m_parsedStyleObjects中去,这里的对象就是指的Rule。那么如此一来, 经过这样一番解析后,作为输入的样式表中的所有Style Rule将被转化为Webkit 的内部模型对象CSSStyleRule对象,存储在m_parsedStyleObjects中,它是一个Vector。

像这样的函数还有createCharsetRule,createImportRule,createMediaRule等等,它们的作用大体上和createStyleRule类似,都是为创建Rule而准备的,只不过是不同类型的Rule。

了解了上面这些,大体上能够就能够了解CSS解析式怎么运作的。但是我们解析所要的结果是什么?通过调用CSSStyleSheet的 parseString函数,上CSS解析过程将启动,解析完一遍后,所有的Rule都将存储在对应的CSSStyleSheet对象中。但是这个时候的 规则依然是不易于处理的,需要将之转换为CSSRuleSet,CSSRuleSet提供了一个addRulesFromSheet方法,能将 CSSStyleSheet中的rule转换为CSSRuleSet中的rule,这样所有的纯样式规则都会放存储在对应的集合当中,这种集合的抽象就是 CSSRuleSet。以后就可以基于这些个CSSRuleSet来决定每个页面中的元素的样式了,后面会有介绍。

(…)


CSS如何作用于Render Tree


所谓的作用于Render Tree其实是指基于上面的解析成果来为相应的Render Object来指定特定的样式,这个样式的抽象就是RenderStyle(关于Render Tree可参见我的其他文章)。

(…)


[转载]Webkit内核探究(1)——Webkit简介

mikel阅读(892)

[转载]Webkit内核探究【1】——Webkit简介 – 李嘉昱 – 博客园.

注:【转载请注明文章来源、保持原样】

出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660355.html
作者:李嘉昱

研究Webkit内核已经有一段时间了,在这期间我花了很多时间去研读webkit代码,并在网上查阅了不少的资料。在这之后,我开始尝试对Webkit内核进行剪裁,以便得到自己所需的部分。

俗语有言,“独学而无友 则孤陋而寡闻”,遂本着交流的态度拿出来与大家分享之,顺便回顾一下自己这段时间以来走过的路。到目前,本人虽不能说是精 通Webkit内核 ,但也总算是在Webkit内核中游历过了一番,并获得了不少Webkit内核代码的直接经验。

在此,我将以Webkit内核代码为基础,详细介绍Webkit内核的组成以及其各个模块的功能和实现。文章写到哪算哪,有了新的认识也会更新,补充。

什么是Webkit


Wekbit是一个开源的Web浏览器引擎,也就是浏览器的内核。Apple的Safari, Google的Chrome, Nokia S60平台的默认浏览器,Apple手机的默认浏览器,Android手机的默认浏览器均采用的Webkit作为器浏览器内核。Webkit的采用程度由 此可见一斑,理所当然的成为了当今主流的三大浏览器内核之一。另外两个分别是Gecko和Trident,大名鼎鼎的Firefox便是使用的Gecko 内核,而微软的IE系列则使用的是Trident内核。虽然目前市场上IE内核浏览器仍然占据大多数市场份额,但其他内核浏览器也大有后来居上之势。其 中,Webkit作为一款优秀的浏览器内核,它众多优秀的特性引起业内的的广泛关注。尤其是近来,google的加入更是让Webkit有所升温,从 Goole Chrome浏览器, Goole Anroid手机操作系统内置浏览器均采用Webkit作为内核, 近来推出的Chrome OS更是让人期待。从实现角度来讲,据说其比Gecko代码更为整洁清晰,我目前还没研究过Gecko的代码,所以还无从比较。

Wekbit做了什么?


作为浏览器的内核,Webkit做了哪些工作?为了了解这些,先让我们来看下一个Web浏览器究竟做了什么。我们可以从输入输出的角度来看一个 Web浏览器为我们做了哪些工作。先看一个简单的例子,Web浏览器的输入是一个HTML文档,输出则是一个我们用眼睛所看到的一个Web页面, 就普通用户而言它的输入和输出就是这么简单,如下图所示。

那么Webkit的输入和输出又是什么呢?如果能明白这个,那我们就能很清楚的知道Webkit到底是做什么的了。不过现在要说清楚这个还有点困 难,因为Webkit的输出就要复杂些了,因为它的输出本来就非直接面向用户,现在简单点来说,Webkit的输入是web 文档,输出是一些看不见的模型,浏览器上层借助于这些模型来绘制出我们所看到的实际页面。后面适当的时候会更具体的探讨这些模型。

Wekbit组成


Webkit实际上包含三大部分,至少从代码结构上来说是这样的,当然,如果细分的话还能够划分出更多的模块。如下图所示

其中,WebCore是Webkit的核心部分,它实现了对文档的模型化,包括了CSS, DOM, Render等的实现, JavaSript Core显然是对JavaSript支持的实现。而橘黄色标注的Webkit部分包含了很多不同平台对Webkit封装的实现,即抽象出了与浏览器所能直 接对应的一些概念的实现,如,WebView,WebPage, WebFrame等。这三部分共同构成了Webkit, 在源码中,它们分别对应这个这三个目录, 即Webkit三大部分为WebCore, JavaSript Core,Webkit。

应用程序如何利用Webkit的


从下图可以看出,利用Webkit的应用程序的位置处于Webkit模块之上,应用程序并不直接和WebCore以及JavaScript Core来打交道,也不需要和它们打交道,而是同我前面提到过的Webkit模块来交互,从而屏蔽了WebCore和JavaSript Core部分。Webkit模块实际上抽象出了大多数应用程序所需要的那一部分,这里所说的大多数应用程序其实就是指的浏览器, 对于实现一个浏览器而言,Webkit模块所提供的接口已经足够。不过对于某些应用,可能得对其实施一定的改造,但是话又说回来,Webkit本来就是被 设计成为Browser的内核而被实现的。

看到这里,也就是说如果我们要想利用Webkit来实现一个功能完善Browser或其他类浏览器应用程序的话,你只需要了解Webkit模块部分 就足够了,更确切的说只需要了解它所提供的接口就够了。事实上,大多数平台,如果采用了Webkit内核作为浏览器内核组件的话,所提供的对应文档部分都 是关于Webkit模块所提供的接口的描述。很多平台都提供了Browser组件,其使用方法就像是其他可视组件一样,在应用程序中应用起来非常方便。比 如,某平台提供了叫做WebView的可视化组件,我们就可以通过如下几行代码来展示一个网页, 使用的代码仅仅三行。

WebView *view = new WebView();

view->load(Url(“http://www.google.cn”));

view->show();

以Webkit作为浏览器组件的平台有不少,包括Symbian S60, Android, Qt, GTK等等,前不久看到消息,好像Black Berry也准备在自家的手机上使用Webkit了。

[转载]Visual Studio调试程序一些小技巧

mikel阅读(1126)

[转载]调试程序一些小技巧 – –中庸– – 博客园.

一、监视窗口

1、配置应用程序,使应用程序处于调试状态(设置断点的状态)。

2、点击“调试”—-“窗口”—-“监视”—-“监视1”,打开监视窗口。

3、在监视窗口中“名称”栏中输入变量名称或html元素id,可查看变量的当前值和数据类型或html元素的属性、方法、事件等。如下图:

4、亦可选中变量,将其拖到“名称”栏,即可查看变量的当前值和数据类型。如下图:

二、即时窗口

1、配置应用程序,使应用程序处于调试状态。

2、点击“调试”—-“窗口”—-“即时”,打开即时窗口。

3、在即时窗口中输入变量名或html元素对应的属性,即可查看变量的当前值或html元素的属性、方法的值。

[转载]visual studio 调出即时窗口

mikel阅读(1827)

[转载]visual studio 2005,visual studio 2008调出即时窗口 – 龙王 – 博客园.

在调试时,即时窗口(Immediate Window)非常有用。

在调试时,调出即时窗口

visual studio 2005 :Ctrl+Alt+I 或则 Ctr+D,I

visual studio 2008 :  Ctrl+Alt+I

visual studio 2003 :  Ctrl+Alt+I

假设你正在会议室里演示即时编译的程序。有什么最佳的方式来进行演示呢?

你还在往代码窗口里输入代码?这样,你得依赖听众的想像力 ―― 他们在脑海中构造这个程序是怎样运行的。此外,你还得依赖他们相信你的代码真的像和你所说的一样运作。
或者你要不停的运行你的代码,这样程序的输出窗口会弹出,然后听众可以看到代码的实际工作情况?这是有风险的,因为每次切换代码和输出窗口会中断流程。并且你得依赖听众会记得他们每次看到的输出信息所对应的代码。
我想这是一个可以被技术所解决的问题!我为Visual Studio 2008 写了一个小插件。它关注的是当前文本缓冲中所包含的代码,并在后台编译它,然后在前端窗口中显示输出。这一系列动作大概每2秒钟重复一次。你甚至不需要保 存再重新编译代码就能看到输出 了。这个插件特意制做成独立的控制台程序因为它用不着输入。这是一幅截图:
源代码很小而且简单易懂,并且可以从上面的链接中获得。
有两个关键的地方。第一是要使用多线程进行处理。我想让源代码在后台线程中编译因此它并不会影响Visual Studio UI. 但是要获取当前缓冲的文本你必须使用UI线程,而且要显示输出你也得使用它。我使用System.Timers.Timer在后台线程触发它的事件,同时 为需要UI线程的任务调用form.Invoke(…)。
我还使用了“non-AutoReset”计时器。我让它获取源码并进行编译+运行+显示,暂停2秒后,再去获取源码并进行编译+运行+显示,如此循环。换句话说,计时器的时间间隔必须设为2 秒在处理完先前的定时事件之后。
”’ <summary>
”’ OnTimer 处理non-autoreset计时器信号。它运行在后台线程中。从当前的缓冲区中获取
”’ 源代码并编译它,然后显示输出。
”’ </summary>
”’ <remarks></remarks>
Sub OnTimer() Handles t.Elapsed
Try
Dim oldsrc = src
我们在后台线程中。但只能从 UI 线程获取源
此委托将获取源代码并将它存储在“src”字段中
f.Invoke(New Action(AddressOf GetSource))
If src <> oldsrc Then
Dim oldoutput = output
在后台编译并运行
output = CompileAndRun(src)
If output <> “” OrElse oldoutput = “” Then
在屏幕上显示输出必须在UI线程中完成
此委托从“output”字段中得到要输出的内容并显示它
f.Invoke(New Action(AddressOf ShowOutput))
End If
End If
Finally
t.Start()
End Try
End Sub
另一个关键时刻与如何运行代码并捕获它的输出有关。在“My”命名空间中,VB在这方面有很多有用的函数。我的主要问题是合理的处理异常不留任何遗漏。 (注意:获取临时文件名的代码并不完全准确:事实上你在某个状态之前得到一个未使用的临时文件名并不意味着这个文件名会一直不被使用;同样,它也并不意味 着添加了“.vb”扩展名的临时文件名会一直不被使用。但是把这种情况处理的更准确看直来并不十分划算;不管怎样,在异常处理中我们将所有的问题恢复到正 常状态。)
Function CompileAndRun(ByVal src As String) As String
Dim fn_exe = “”
Dim fn_src = “”
Dim vbc As System.Diagnostics.Process = Nothing
Dim exe As System.Diagnostics.Process = Nothing
Try
准备编译
fn_src = My.Computer.FileSystem.GetTempFileName() & “.vb”
My.Computer.FileSystem.WriteAllText(fn_src, src, False)
fn_exe = My.Computer.FileSystem.GetTempFileName() & “.exe”
Dim framework = Environment.ExpandEnvironmentVariables(“%windir%\Microsoft.Net\Framework”)
Dim latest_framework = (From d In My.Computer.FileSystem.GetDirectories(framework) Where d Like “*\v*” Select d).Last
编译
vbc = System.Diagnostics.Process.Start(New ProcessStartInfo _
With {.CreateNoWindow = True, _
.UseShellExecute = False, _
.FileName = latest_framework & “\vbc.exe”, _
.Arguments = String.Format(“/out:””{0}”” /target:exe “”{1}”””, fn_exe, fn_src)})
Dim vbc_done = vbc.WaitForExit(3000)
If Not vbc_done Then Return “”
If vbc.ExitCode <> 0 Then Return “”
运行
Dim pinfo = New ProcessStartInfo With {.CreateNoWindow = True, _
.UseShellExecute = False, _
.FileName = fn_exe, _
.RedirectStandardOutput = True}
exe = New System.Diagnostics.Process With {.StartInfo = pinfo}
exe.Start()
Dim output = exe.StandardOutput.ReadToEnd
Dim exe_done = exe.WaitForExit(3000)
If Not exe_done Then Return “”
Return output
Finally
我们可以巧妙的关闭VBC进程
If vbc IsNot Nothing Then
If Not vbc.HasExited Then
Try : vbc.Kill() : Catch ex As Exception : End Try
Try : vbc.WaitForExit() : Catch ex As Exception : End Try
End If
Try : vbc.Close() : Catch ex As Exception : End Try
vbc = Nothing
End If
我们可以巧妙的关闭EXE
If exe IsNot Nothing Then
If Not exe.HasExited Then
Try : exe.Kill() : Catch ex As Exception : End Try
Try : exe.WaitForExit() : Catch ex As Exception : End Try
End If
Try : exe.Close() : Catch ex As Exception : End Try
exe = Nothing
End If
删除剩余的文件
Try : My.Computer.FileSystem.DeleteFile(fn_exe) : Catch ex As Exception : End Try
Try : My.Computer.FileSystem.DeleteFile(fn_src) : Catch ex As Exception : End Try
End Try
End Function

[转载]Visual Studio 即时窗口和命令窗口使用教程

mikel阅读(2851)

[转载]Visual Studio [即时窗口] & [命令窗口] (Immediate Window & Command Window) – 知生知死 – 博客园.

打开[即时窗口]

1) Shortcut

Ctrl+D, I

2) Menu

3) 在[命令窗口]输入immed

打开[命令窗口]

1) Shortcut

Ctrl+W, A

2) Menu

3) 在[即时窗口]输入cmd

4) 在[即时窗口] 输入 > , 可以直接执行命令

[即时窗口]计算变量

命令格式依次为: 1) Variable 2) Expression 3) ?Expression 4) Debug.Print Expression 5) Function

1.直接输入断点前的变量的值,回车会向下执行该值就位即时窗口输入的值

然后验证调试结果

[即时窗口] & [命令窗口]小技巧:

1) 清空内容命令

2) 标记模式下, 相当于一个建议文本编辑器,方便操作.

3) IntelliSense

3) 向上键和向下键 找回以前输入的命令执行

4) Ctrl+向上键/向下键 在窗口中移动光标

问题列表

1) Debug.EvaluateStatement

= 用于输入 EvaluateStatement 命令的窗口确定是将等号 (=) 解释为比较运算符还是赋值运算符。在“即时”窗口中,将等号 (=) 解释为赋值运算符。例如,命令 >Debug.EvaluateStatement(varA=varB) , 将为变量 varA 赋予变量 varB 的值。
与此相反,在“命令”窗口中,将等号 (=) 解释为比较运算符。 不能在“命令”窗口中进行赋值运算。例如,如果变量 varA 和 varB 的值不相同,则命令>Debug.EvaluateStatement(varA=varB), 将返回 False 值。
实际执行时将出现如下图所示的提示,原因不明。

参考资料列表:
http://msdn.microsoft.com/zh-cn/library/f177hahy%28v=VS.100%29.aspx
http://msdn.microsoft.com/zh-cn/library/c785s0kz%28v=VS.80%29.aspx

[转载]图文并茂详解VisualStudio使用技巧二

mikel阅读(1352)

[转载]工欲善其事,必先利其器——图文并茂详解VisualStudio使用技巧二 – 望穿秋水 – 博客园.

第一节地址:

工欲善其事,必先利其器——图文并茂详解VisualStudio使用技巧一

http://www.cnblogs.com/qqflying/archive/2008/11/19/1336094.html

直接先上第二节目录:

怎样使用书签?
怎样使用即时窗口来显示变量或执行方法?
怎样在硬盘中快速找到项目中的文件?
怎样快速调整文档或某段代码的格式?
怎样快速把文件加入到项目中?
怎样强制调用智能提示?
怎样强制调用参数信息?
怎样跳转到指定的行?

怎样使用向前定位及向后定位快捷键?
怎样快速切换不用的页面?
怎样快速隐藏或显示当前代码段?
怎样同时修改多个控件的属性?
怎样录制与播放临时宏?

9.怎样使用书签来快速找到自己的文件?

如果你在开发一个中、大型项目,如果你的解决方案下面包含很多工程,如果你拥有很多的页面,那么要想快速找到想要的某个页面是不是很麻烦,层层目录去找?太慢了,何况要还要让你去找某个页面中的某段代码呢?!

VS中的书签功能能够很好地解决这一问题。首先把光标放到需要标记书签的代码处,然后点击VS中的插入书签按钮,就完成了设置书签的操作。也可以使用设置书签的快捷键:Ctrl+B,Ctrl+T来完成书签的设置或取消。

见图:

书签设置好之后,直接在书签列表中双击你设置的书签就能直接跳转到想要的代码段了。提醒一下,你可以自己重命名书签的名字呀,很方便吧。

10.怎样使用即时窗口来调试程序?

这个即时窗口的用途就不用说了,大家可能都知道,但是好多人却因为不小心关掉了这个窗口而再想使用它时却怎么找也找不到。

想一想,既然是即时窗口肯定是在调试的时候才有用,那么怎样打开它呢?调试——窗口——即时窗口,或快捷键:Ctrl+D,I

11.怎样在硬盘中快速找到项目中的文件?

如果你在使用VS,想拷贝项目中的某个文件,不要再去硬盘中一个目录一个目录深入了,在VS中打开该文件,然后右键该选项-打开所在的文件夹即可,见图:

12.怎样快速调整文档或某段代码的格式?

现在大家写代码都喜欢拷代码,可是拷过来的代码有时候毕竟不像写的那样格式很正确,排的很整齐,怎麽办?手动一行一行地调整?不用!

交给VS来做这无聊的工作吧:选择编辑——高级——设置文档的格式 或 编辑——高级——设置选中代码的格式。有了它再也不怕代码排版不美观了。

13.怎样快速把文件加入到项目中?

打开VS,直接把文件粘贴到想要放置的文件夹中即可。

14.怎样强制调用智能提示?

如果没有VS的只能提醒,估计好多人都不会写代码了。可是智能提醒又不是能够让我们随心所欲地使用,过了那个时候你鼠标再怎么移动它都不会出来,搞的我们有时候不得不把原来写的代码删除一部分重新点个”.”来调用智能提醒。

其实VS中有个快捷键,能够真正让我们达到随心所欲,想什么时候看智能提醒就什么时候看。

把光标放到想调用智能提醒的地方,然后输入Ctrl+J,看吧,熟悉的智能提醒又出来了。见图:

15.怎样强制调用参数信息?

一个方法的参数信息也是很重要的,可是它有时候会使哦我们存在和14条中相同的困惑。怎样让我们“想看就看”呢?

记住这个快捷键:Ctrl+Shif+空格,让你想看就看。 光标放到参数名上面,然后输入Ctrl+Shif+空格,看看什么出来了:

16.怎样跳转到指定的行?

两种方法,能够快速定位到文档中的某一行:1.Ctrl+G  2.单击状态栏中的行号,如下图:

17.怎样使用向前定位及向后定位快捷键?

相信VS中的“转到定义”大家都喜欢用,可是转到定义之后怎么能够快速地转回来呢?下面这个快捷键会节省你“转回来”的时间:

Ctrl+_ 。如果你转回来之后还想转到定义,直接输入:Ctrl+Shif+_ 就好了。来回切换吧,想怎么看就怎么看。

如果你说这样看着太累了,那再告诉你一个更简洁的方法:打开:视图——代码定义窗口,然后你再在页面中把鼠标点到某个方法上,看看代码定义窗口中显示的是什么:

18.怎样快速切换不用的页面?

Window中切换不同的窗口的快捷键你知道吧:Alt+Tab,那么VS中也有:Ctrl+Tab,看看效果吧:

19.怎样快速隐藏或显示当前代码段?

Ctrl+M,M
20.怎样同时修改多个控件的属性?

选中多个控件,然后右键属性,这个时候这些控件共有的属性就会出现,修改之后所有的控件都会变化。
21.怎样录制与播放临时宏?

如果你在VS中需要不断重复一系列键盘操作的时候,这个时候你可以考虑让VS自己写代码了。使用VS中的宏功能,把你的一系列需要不断重复的键盘操作给录制下来,然后直接执行宏就能让VS自己写代码了。

录制:工具-宏-记录临时宏,Ctrl+Shif+R
播放:工具-宏-运行临时宏,   Ctrl+Shif+P
保存:工具-宏-保存临时宏.,可以重命名宏

后记:OK,这个系列写完了,对VisualStudio你更熟悉了吗?“工欲善其事,必先利其器”,让我们拿起VisualStudio这把利器,打造更美好的明天吧!That’s all.

原创文章,转载请注明出处。

[原创]EasyUI的Datagrid组件getFooterRows使用教程

mikel阅读(2019)

项目中需要获取页脚合计后的总金额,于是查看EasyUI的datagrid文档,发现getFooterRows是用来获取页脚的方法,于是编写如下代码:

var footers=$('#grid').datagrid('getFooterRows');
var sum=footers.Sum_Money;

可是提示footers.Sum_Money未定义undefined,网上搜索了下相关资料,没有合适的答案,查看了源码后发现getFooterRows返回的是所有footer的数组,尽管这里我的footer只有一个,它还是会返回一个数组,于是试着用alert下footers.length发现提示长度为1,于是修改代码如下:

var footers=$('#grid').datagrid('getFooterRows');
var sum=footers[0].Sum_Money;

[转载]在ASP.NET MVC中如何应用多个相同类型的ValidationAttribute?

mikel阅读(1021)

[转载]在ASP.NET MVC中如何应用多个相同类型的ValidationAttribute? – Artech – 博客园.

ASP.NET MVC采用System.ComponentModel.DataAnnotations提供的元数据验证机制对Model实施验证,我们可以在 Model类型或者字段/属性上应用相应的ValidationAttribute。但是在默认情况下,对于同一个类型的 ValidationAttribute特性只允许一个应用到目标元素上——即使我们将AllowMultiple属性设置为True。这篇文章的目的就 是为了解决这个问题。[源代码从这里下载]

一、一个自定义ValidationAttribute:RangeIfAttribute

为 了演示在相同的目标元素(类、属性或者字段)应用多个同类的ValidationAttribute,我定义了一个名称为 RangeIfAttribute特性用于进行“有条件的区间验证”。如下面的代码片断所示,RangeIfAttribute是 RangeAttribute的子类,应用在上面的AttributeUsageAttribute特性的AllowMultiple 属性被设置为True。RangeIfAttribute定义了Property和Value两个属性,分别表示被验证属性/字段所在类型的另一个属性名 称和相应的值,只有当指定的属性值与通过Value属性值相等的情况下我们在真正进行验证。具体的验证逻辑定义在重写的IsValid方法中。

   1: [AttributeUsage( AttributeTargets.Field| AttributeTargets.Property, AllowMultiple = true)]
   2: public class RangeIfAttribute: RangeAttribute
   3: {
   4:     public string Property { get; set; }
   5:     public string Value { get; set; }
   6:     public RangeIfAttribute(string property, string value, double minimum, double maximum)
   7:         : base(minimum, maximum)
   8:     {
   9:         this.Property = property;
  10:         this.Value = value;
  11:     }
  12:     protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  13:     {
  14:         object propertyValue = validationContext.ObjectType.GetProperty(this.Property).GetValue(validationContext.ObjectInstance,null);
  15:         propertyValue = propertyValue ?? "";
  16:         if (propertyValue.ToString()!= this.Value)
  17:         {
  18:             return null;
  19:         }
  20:         if (base.IsValid(value))
  21:         {
  22:             return null;
  23:         }
  24:
  25:         string[] memberNames = (validationContext.MemberName != null) ? new string[] { validationContext.MemberName } : null;
  26:         return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName), memberNames);
  27:     }
  28: }

二、将RangeIfAttribute应用于Employee

我们将RangeIfAttribute特性应在具有如下定义的表示员工的Employee类型的Salary(表示薪水)属性上,另外一个属性 Grade表示员工的级别。应用在Salary属性上的RangeIfAttribute特性体现了基于级别的薪水区间验证规则:对于G7、G8和G9的 员工,其薪水分别在2000~3000,3000~4000和4000~5000范围内。

   1: public class Employee
   2: {
   3:     public string Name { get; set; }
   4:     public string Grad { get; set; }
   5:     [RangeIf("Grad", "G7", 2000, 3000)]
   6:     [RangeIf("Grad", "G8", 3000, 4000)]
   7:     [RangeIf("Grad", "G9", 4000, 5000)]
   8:     public decimal Salary { get; set; }
   9: }

现在我们创建如下一个EmployeeController,其默认的两个Index操作方法定义如下。在HttpPost的Index操作中,如果验证成功我们将“验证成功”字样作为ModelError添加到ModelState中。

   1: public class EmployeeController : Controller
   2: {
   3:     public ActionResult Index()
   4:     {
   5:         return View(new Employee());
   6:     }
   7:
   8:     [HttpPost]
   9:     public ActionResult Index(Employee employee)
  10:     {
  11:         if (ModelState.IsValid)
  12:         {
  13:             ModelState.AddModelError("", "验证成功");
  14:             return View(new Employee());
  15:         }
  16:         else
  17:         {
  18:             return View(new Employee());
  19:         }
  20:     }
  21:
  22: }

下面是Index操作默认的View的定义:

   1: @model MultipleValidator.Models.Employee
   2: @{
   3:     ViewBag.Title = "Employee Management";
   4: }
   5: @Html.ValidationSummary(true)
   6: @using (Html.BeginForm())
   7: {
   8:     @Html.EditorForModel()
   9:     <input type="submit" value="Save" />
  10: }

遗憾的是,ASP.NET MVC并不能按照我们希望的方对我们的输入进行验证。如下面的截图所示,我们只有在输入G9的时候,系统才能实施成功地验证,对于G7和G8则被输入的Salary值(0.00)是合法的。

image

三、重写TypeId属性解决问题

之所以会发生上述的这种现象,原因在于被应用到Salary属性上的RangeIfAttribute特性,最终只有最后一个 (Value=“G9”)被使用到。ASP.NET MVC在生成包括验证特性的Model的元数据的时候,针对某个元素的所有ValidationAttribute是被维护在一个字典上的,而这个字典的 值就是Attribute的TypeId属性。在默认的情况下,Attribute的TypeId返回的是自身的类型,所以导致应用到相同目标元素的同类 ValidationAttribute只能有一个。幸好Attribute的TypeId属性是可以被重写的,县在我们在 RangeIfAttribute中按照如下的方式对这个属性进行重写:

   1: [AttributeUsage( AttributeTargets.Field| AttributeTargets.Property, AllowMultiple = true)]
   2: public class RangeIfAttribute: RangeAttribute
   3: {
   4:     //其他成员
   5:     private object typeId;
   6:     public override object TypeId
   7:     {
   8:         get
   9:         {
  10:             return (null == typeId) ? (typeId = new object()) : typeId;
  11:         }
  12:     }
  13: }

再次运行我们的程序则一切正常:

image

值得一提的是:重写TypeId属性的方式只能解决服务端验证的问题,对于客户端认证无效。

[原创]EasyUI1.2.5中Numberbox赋值的问题

mikel阅读(1293)

原来一直用EasyUI1.2.4开发的应用,最近测试时发现Numberbox组件提交的值都为0,于是查看js代码发现有对numberbox赋值的代码如下:

$('#number').val(23);

EasyUI1.2.4使用上述代码可以给numberbox赋值成功,并可以提交到后台保存,EasyUI1.2.5不能这样赋值要用setValue方法赋值,修改后的代码如下:

$('#number').numberbox('setValue',23);