[工具]VS2008 快捷键大全

mikel阅读(754)

转载:http://hi.baidu.com/crp8/blog/item/1617262ad20b543c5343c1c7.html
Ctrl+m+Crtr+o折叠所有大纲
Ctrl+M+Crtr+P: 停止大纲显示
Ctrl+K+Crtr+C: 注释选定内容
Ctrl+K+Crtr+U: 取消选定注释内容
Ctrl+J : 列出成员 智能感知
Shift+Alt+Enter: 切换全屏编辑
Ctrl+B,T / Ctrl+K,K: 切换书签开关
Ctrl+B,N / Ctrl+K,N: 移动到下一书签
Ctrl+B,P: 移动到上一书签
Ctrl+B,C: 清除全部标签
Ctrl+I: 渐进式搜索
Ctrl+Shift+I: 反向渐进式搜索
Ctrl+F: 查找
Ctrl+Shift+F: 在文件中查找
F3: 查找下一个
Shift+F3: 查找上一个
Ctrl+H: 替换
Ctrl+Shift+H: 在文件中替换
Alt+F12: 查找符号(列出所有查找结果)
Ctrl+Shift+V: 剪贴板循环
Ctrl+左右箭头键: 一次可以移动一个单词
Ctrl+上下箭头键: 滚动代码屏幕,但不移动光标位置。
Ctrl+Shift+L: 删除当前行
Ctrl+M,M: 隐藏或展开当前嵌套的折叠状态
Ctrl+M,L: 将所有过程设置为相同的隐藏或展开状态
Ctrl+E,S: 查看空白
Ctrl+E,W: 自动换行
Ctrl+G: 转到指定行
Shift+Alt+箭头键: 选择矩形文本
Alt+鼠标左按钮: 选择矩形文本
Ctrl+Shift+U: 全部变为大写
Ctrl+U: 全部变为小写
代码快捷键
Ctrl+Shift+空格键 / Ctrl+K,P: 参数信息
Ctrl+K,I: 快速信息
Ctrl+E,U / Ctrl+K,U: 取消选定注释内容
Ctrl+K,M: 生成方法存根
Ctrl+K,X: 插入代码段
Ctrl+K,S: 插入外侧代码
F12: 转到所调用过程或变量的定义
窗口快捷键
Ctrl+W,W: 浏览器窗口
Ctrl+W,S: 解决方案管理器
Ctrl+W,C: 类视图
Ctrl+W,E: 错误列表
Ctrl+W,O: 输出视图
trl+W,P: 属性窗口
Ctrl+W,T: 任务列表
Ctrl+W,X: 工具箱
Ctrl+W,B: 书签窗口
Ctrl+W,U: 文档大纲
Ctrl+D,B: 断点窗口
Ctrl+D,I: 即时窗口
Ctrl+Tab: 活动窗体切换
Ctrl+Shift+N: 新建项目
Ctrl+Shift+O: 打开项目
Ctrl+Shift+S: 全部保存
Shift+Alt+C: 新建类
Ctrl+Shift+A: 新建项
Shift+Alt+Enter: 切换全屏编辑
Ctrl+B,T / Ctrl+K,K: 切换书签开关
Ctrl+B,N / Ctrl+K,N: 移动到下一书签
Ctrl+B,P: 移动到上一书签
Ctrl+B,C: 清除全部标签
Ctrl+I: 渐进式搜索
Ctrl+Shift+I: 反向渐进式搜索
Ctrl+F: 查找
Ctrl+Shift+F: 在文件中查找
F3: 查找下一个
Shift+F3: 查找上一个
Ctrl+H: 替换
Ctrl+Shift+H: 在文件中替换
Alt+F12: 查找符号(列出所有查找结果)
Ctrl+Shift+V: 剪贴板循环
Ctrl+左右箭头键: 一次可以移动一个单词
Ctrl+上下箭头键: 滚动代码屏幕,但不移动光标位置。
Ctrl+Shift+L: 删除当前行
Ctrl+M,M: 隐藏或展开当前嵌套的折叠状态
Ctrl+M,L: 将所有过程设置为相同的隐藏或展开状态
Ctrl+M,P: 停止大纲显示
Ctrl+E,S: 查看空白
Ctrl+E,W: 自动换行
Ctrl+G: 转到指定行
Shift+Alt+箭头键: 选择矩形文本
Alt+鼠标左按钮: 选择矩形文本
Ctrl+Shift+U: 全部变为大写
Ctrl+U: 全部变为小写

[NUnit]Nunit中如何进行事务性单元测试

mikel阅读(655)

单元测试要求:单元测试方法并不真正去变更数据库,也就是说单元测试不依赖于数据库中的数据。那我们如何解决执行单元测试方法后,不变更数据库中数据呢?

一般的解决方案有两种:

 

1、 新建一个单元测试数据库,开发数据库与单元测试数据库分离,单元测试方法完全基于单元测试数据库。

此中方法的优点是:,开发人员在开发期间不会对单元测试数据库中数据进行变更,也就不会影响单元测试方法 在任何时间执行。

缺点:单元测试数据库和开发数据库同步问题,特别是对迭代式开发项目,数据库是根据需求在不断地跟进或者变更,同步问题成为了单元测试正常运行的瓶颈。

 

2、 使用事务对单元测试方法的执行进行回滚。

此种方法的优点:解决了方法一中缺点,不会出现数据库结构不同步的问题。

缺点:在进行CRUD(Create/Read/Update/Delete操作时,需要在单元测试方法中进行一些插入数据操作,从而保证单元测试与开发数据库的独立,造成了单元测试工作量增加。

 

在实际的项目中,可以根据需要选择符合自己的解决方案,如果数据库结构在项目进入开发阶段已经确定,并且以后不会有变动,建议采用第一种方案,否则建议第二种方案。目前我们项目采用第二中方案。

一、NUnit事务性单元测试

 

那使用Nunit框架如果保证数据的会滚呢?这里我们使用了COM+事务。

System.EnterpriseServices;

具体如下:

/// <summary>

    ///单元测试基类,所有单元测试类都需要继承此类

    /// </summary>

    [TestFixture]

    [Transaction(TransactionOption.Required)]

    public class DatabaseFixture:ServicedComponent

    {

        public DatabaseFixture()

        {

            //

            // TODO: Add constructor logic here

            //

        }

        [TearDown]

        public void TransactionTearDown()

        {

            if (ContextUtil.IsInTransaction)

            {

                ContextUtil.SetAbort();

            }

        }

所有的单元测试方法都需要继承与此类。比如:

public class AddressSQLDAOTest : DatabaseFixture

这样,单元测试方法执行完后,会继续执行DatabaseFixture类中的TransactionTearDown()方法。从而会滚之前的数据操作,单元测试方法也就不会影响开发数据库,同样开发数据库也不会影响单元测试方法的执行,从而保证了单元测试与数据库数据的独立。

 

二、如何CRUD单元测试

1、测试增加方法:判断返回的主键是否>0,如果主键>0 说明单元测试方法成功,否则失败

2、测试查询方法:首先在执行单元测试类中的插入数据方法(不是被测试类中的插入方法,而是在单元测试类中写的插入方法,一定要区分开),然后执行查询方法。

3、测试更新方法:首先在执行单元测试类中的插入数据方法,然后执行更新方法。

4、测试删除方法:首先在执行单元测试类中的插入数据方法,然后执行删除方法。

 

三、单元测试的命名规范

为了便于后期单元测试方法的维护,建议如下命名单元测试类 和单元测试方法。

单元测试类名:被测试类名称+Test

单元测试方法名:被测试方法名称+Test

四、总结

至此,大家就可以利用Nunit中如何进行事务性单元测试已经完毕,相信大家也已经了解了如何让单元测试独立于数据库数据,从而更高效地进行单元测试,也不影响开发。

 

版权

作者:灵动生活

出处:http://www.cnblogs.com/ywqu

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

[算法]遗传编程算法

mikel阅读(917)

转载;http://www.cnblogs.com/zgw21cn/archive/2009/11/07/1598238.html

假设从向银行申请贷款的顾户中,要选出优质顾客。怎么做?

现在有学习数据如下

ID

孩子个数

薪水

婚姻状况

是否优质顾客?

ID-1

2

45000

Married

0

ID-2

0

30000

Single

1

ID-3

1

40000

Divorced

1

       

如果从学习数据中学习出如下规则

IF (孩子个数(NOC) = 2) AND (薪水(S) > 80000) THEN 优良顾客 ELSE 不良顾客。

这条规则以一条树的形式可以表现如下。

image

遗传编程(genetic programming)基于遗传算法,传统的遗传算法是用定长的线性字符串表示一个基因。而遗传编程基于树的形式,其树的深度和宽度是可变的。树可以轻易表达算术表达式,逻辑表达式,程序等。例如

(1)算术表达式image

表示成树为

image

(2) 逻辑表达式:(x Ù true) ® (( x Ú y ) Ú (z « (x Ù y)))。可以由树表达为

image

(3)程序

i =1;

while (i < 20){

i = i +1

}

可以表示为

image

正因为遗传编程中,以树的形式来表达基因,因此遗传编程更适于表达复杂的结构问题。其用武之地也比遗传算法广泛得多了。开始的银行寻找优良顾客就是其中一例子。

遗传编程算法的一个最为简单的例子,是尝试构造一个简单的数学函数。假设我们有一个包含输入和输出的表,如下

x

y

Result

2

7

21

8

5

83

8

4

81

7

9

75

7

4

65

其背后函数实际上是x*x+x+2*y+1。现在打算来构造一个函数,来拟合上述表格中的数据。

首先构造拟合数据。定义如下函数。

 

 

 

 

def examplefun(x, y):
return x * x + x + 2 * y + 1
def constructcheckdata(count=10):
checkdata = []
for i in range(0, count):
dic = {}
x = randint(0, 10)
y = randint(0, 10)
dic['x'] = x
dic['y'] = y
dic['result'] = examplefun(x, y)
checkdata.append(dic)
return checkdata

实际上一棵树上的节点可以分成三种,分别函数,变量及常数。定义三个类来包装它们:

class funwrapper:
def __init__(self, function, childcount, name):
self.function = function
self.childcount = childcount
self.name = name
class variable:
def __init__(self, var, value=0):
self.var = var
self.value = value
self.name = str(var)
self.type = "variable"
def evaluate(self):
return self.varvalue
def setvar(self, value):
self.value = value
def display(self, indent=0):
print '%s%s' % (' '*indent, self.var)
class const:
def __init__(self, value):
self.value = value
self.name = str(value)
self.type = "constant"
def evaluate(self):
return self.value
def display(self, indent=0):
print '%s%d' % (' '*indent, self.value) 

现在可以由这些节点来构造一棵树了。

class node:
def __init__(self, type, children, funwrap, var=None, const=None):
self.type = type
self.children = children
self.funwrap = funwrap
self.variable = var
self.const = const
self.depth = self.refreshdepth()
self.value = 0
self.fitness = 0
def eval(self):
if self.type == "variable":
return self.variable.value
elif self.type == "constant":
return self.const.value
else:
for c in self.children:
result = [c.eval() for c in self.children]
return self.funwrap.function(result)
def getfitness(self, checkdata):#checkdata like {"x":1,"result":3"}
diff = 0
#set variable value
for data in checkdata:
self.setvariablevalue(data)
diff += abs(self.eval() - data["result"])
self.fitness = diff
def setvariablevalue(self, value):
if self.type == "variable":
if value.has_key(self.variable.var):
self.variable.setvar(value[self.variable.var])
else:
print "There is no value for variable:", self.variable.var
return
if self.type == "constant":
pass
if self.children:#function node
for child in self.children:
child.setvariablevalue(value)
def refreshdepth(self):
if self.type == "constant" or self.type == "variable":
return 0
else:
depth = []
for c in self.children:
depth.append(c.refreshdepth())
return max(depth) + 1
def __cmp__(self, other):
return cmp(self.fitness, other.fitness)
def display(self, indent=0):
if self.type == "function":
print ('  '*indent) + self.funwrap.name
elif self.type == "variable":
print ('  '*indent) + self.variable.name
elif self.type == "constant":
print ('  '*indent) + self.const.name
if self.children:
for c in self.children:
c.display(indent + 1)
##for draw node
def getwidth(self):
if self.type == "variable" or self.type == "constant":
return 1
else:
result = 0
for i in range(0, len(self.children)):
result += self.children[i].getwidth()
return result
def drawnode(self, draw, x, y):
if self.type == "function":
allwidth = 0
for c in self.children:
allwidth += c.getwidth()*100
left = x - allwidth / 2
#draw the function name
draw.text((x - 10, y - 10), self.funwrap.name, (0, 0, 0))
#draw the children
for c in self.children:
wide = c.getwidth()*100
draw.line((x, y, left + wide / 2, y + 100), fill=(255, 0, 0))
c.drawnode(draw, left + wide / 2, y + 100)
left = left + wide
elif self.type == "variable":
draw.text((x - 5 , y), self.variable.name, (0, 0, 0))
elif self.type == "constant":
draw.text((x - 5 , y), self.const.name, (0, 0, 0))
def drawtree(self, jpeg="tree.png"):
w = self.getwidth()*100
h = self.depth * 100 + 120
img = Image.new('RGB', (w, h), (255, 255, 255))
draw = ImageDraw.Draw(img)
self.drawnode(draw, w / 2, 20)
img.save(jpeg, 'PNG')
 其中计算适应度的函数getfitness(),是将变量赋值后计算所得的值,与正确的数据集的差的绝对值的和。Eval函数即为将变量赋值后,计算树的值。构造出的树如下图,可由drawtree()函数作出。 

image

其实这棵树的数学表达式为x*x-3x。

然后就可以由这此树来构造程序了。初始种群是随机作成的。

def _maketree(self, startdepth):
if startdepth == 0:
#make a new tree
nodepattern = 0#function
elif startdepth == self.maxdepth:
nodepattern = 1#variable or constant
else:
nodepattern = randint(0, 1)
if nodepattern == 0:
childlist = []
selectedfun = randint(0, len(self.funwraplist) - 1)
for i in range(0, self.funwraplist[selectedfun].childcount):
child = self._maketree(startdepth + 1)
childlist.append(child)
return node("function", childlist, self.funwraplist[selectedfun])
else:
if randint(0, 1) == 0:#variable
selectedvariable = randint(0, len(self.variablelist) - 1)
return node("variable", None, None, variable(self.variablelist[selectedvariable]), None)
else:
selectedconstant = randint(0, len(self.constantlist) - 1)
return node("constant", None, None, None, const(self.constantlist[selectedconstant]))

当树的深度被定义为0时,表明是从重新开始构造一棵新树。当树的深度达到最高深度时,生长的节点必须是变量型或者常数型。

当然程序不止这些。还包括对树进行变异和交叉。变异的方式的方式为,选中一个节点后,产生一棵新树来代替这个节点。当然并不是所有的节点都实施变异,只是按一个很小的概率。变异如下:

def mutate(self, tree, probchange=0.1, startdepth=0):
if random() < probchange:
return self._maketree(startdepth)
else:
result = deepcopy(tree)
if result.type == "function":
result.children = [self.mutate(c, probchange, startdepth + 1) for c in tree.children]
return result

交叉的方式为:从种群中选出两个优异者,用一棵树的某个节点代替另一棵树的节点,从而产生两棵新树。

 def crossover(self, tree1, tree2, probswap=0.8, top=1):
if random() < probswap and not top:
return deepcopy(tree2)
else:
result = deepcopy(tree1)
if tree1.type == "function" and tree2.type == "function":
result.children = [self.crossover(c, choice(tree2.children), probswap, 0)
for c in tree1.children]
return result

以上变异及交叉都涉及到从现有种群中选择一棵树。常用的选择算法有锦标赛方法,即随机选出几棵树后,按fitness选出最优的一棵树。另一种方法是轮盘赌算法。即按fitness在种群的比率而随机选择。Fitness越大的树,越有可能被选中。如下所列的轮盘赌函数。

 def roulettewheelsel(self, reverse=False):
if reverse == False:
allfitness = 0
for i in range(0, self.size):
allfitness += self.population[i].fitness
randomnum = random()*(self.size - 1)
check = 0
for i in range(0, self.size):
check += (1.0 - self.population[i].fitness / allfitness)
if check >= randomnum:
return self.population[i], i
if reverse == True:
allfitness = 0
for i in range(0, self.size):
allfitness += self.population[i].fitness
randomnum = random()
check = 0
for i in range(0, self.size):
check += self.population[i].fitness * 1.0 / allfitness
if check >= randomnum:
return self.population[i], i

其中参数reverse若为False,表明fitness越小,则这棵树表现越优异。不然,则越大越优异。在本例中,选择树来进行变异和交叉时,选择优异的树来进行,以将优良的基因带入下一代。而当变异和交叉出新的子树时,则选择较差的树,将其淘汰掉。

现在可以构造进化环境了。

def envolve(self, maxgen=100, crossrate=0.9, mutationrate=0.1):
for i in range(0, maxgen):
print "generation no.", i
child = []
for j in range(0, int(self.size * self.newbirthrate / 2)):
parent1, p1 = self.roulettewheelsel()
parent2, p2 = self.roulettewheelsel()
newchild = self.crossover(parent1, parent2)
child.append(newchild)#generate new tree
parent, p3 = self.roulettewheelsel()
newchild = self.mutate(parent, mutationrate)
child.append(newchild)
#refresh all tree's fitness
for j in range(0, int(self.size * self.newbirthrate)):
replacedtree, replacedindex = self.roulettewheelsel(reverse=True)
#replace bad tree with child
self.population[replacedindex] = child[j]
for k in range(0, self.size):
self.population[k].getfitness(self.checkdata)
self.population[k].depth=self.population[k].refreshdepth()
if self.minimaxtype == "min":
if self.population[k].fitness < self.besttree.fitness:
self.besttree = self.population[k]
elif self.minimaxtype == "max":
if self.population[k].fitness > self.besttree.fitness:
self.besttree = self.population[k]
print "best tree's fitbess..",self.besttree.fitness
self.besttree.display()
self.besttree.drawtree()  

每次按newbirthrate的比率,淘汰表现不佳的旧树,产生相应数目的新树。每次迭代完后,比较fitness,选出最佳的树。迭代的终止条件是其fitness等于零,即找到了正确的数学表达式,或者迭代次数超过了最大迭代次数。

还有其它一些细节代码,暂且按下不表。自由教程可按这里下载:http://www.gp-field-guide.org.uk/

全部代码可在这里下载:http://wp.me/pGEU6-z

[JQuery]星级评分--jQuery插件

mikel阅读(907)

转载:http://www.cnblogs.com/studyplay/archive/2009/11/08/1598382.html

   以前写过一篇文章JQuery为基础的星星评分 ,今天有时间把这个功能重写,并以JQuery插件的形式出现以便以后使用。 首先看一下运行效果如下图所示。

    鼠标移到星星上该星星前面的所有星星全部变亮,鼠标单击将记录点击的星星数,前面的所有星星将变亮。

    一、原理

    本程序的原理是这样的:一个“ul”标签,该标签的背景为灰色的星星,控制“ul”标签的宽度显示星星的数量。例如:一个星星图片的宽度为23px,那么要显示10个星星,则“ul”的宽度为230px就可以显示10个星星。

    n个“li”标签,n表示您要显示星星的个数,例如你要显示10个星星那么将有10个“li”标签。那么这10个标签的宽度分别为1个星星的宽度 23px,2个星星的宽度46px,……,10个星星的宽度230px。这些“li”标签的背景将为蓝色的星星。

   则另外还有一个“li”标签记录鼠标单击的星星或初始设置。

   这些标签都是重叠在一起的,通过鼠标滑动效果切换这些标签的层叠顺序,显示不同的星星数量,单击记录星星个数。

   二、源码

   $.fn.studyplay_star=function(options,callback){
 //默认设置
 var settings ={
  MaxStar      :20,
  StarWidth    :23,
  CurrentStar  :5,
  Enabled      :true
  }; 
 if(options) { JQuery.extend(settings, options); };
 var container = jQuery(this);
 container.css({"position":"relative"})
 .html('<ul class="studyplay_starBg"></ul>') 
 .find('.studyplay_starBg').width(settings.MaxStar*settings.StarWidth)
 .html('<li class="studyplay_starovering" style="width:'+settings.CurrentStar*settings.StarWidth+'px; z-index:0;" id="studyplay_current"></li>');
 if(settings.Enabled)
 {
 var ListArray = ""; 
 for(k=1;k<settings.MaxStar+1;k++)
 {
  ListArray +='<li class="studyplay_starON" style="width:'+settings.StarWidth*k+'px;z-index:'+(settings.MaxStar-k+1)+';"></li>';
 }
 container.find('.studyplay_starBg').append(ListArray)
 .find('.studyplay_starON').hover(function(){
             $("#studyplay_current").hide();
             $(this).removeClass('studyplay_starON').addClass("studyplay_starovering");
             },
           function(){
            $(this).removeClass('studyplay_starovering').addClass("studyplay_starON");
            $("#studyplay_current").show();
            })
 .click(function(){
     var studyplay_count = settings.MaxStar – $(this).css("z-index")+1;
     $("#studyplay_current").width(studyplay_count*settings.StarWidth)
     //回调函数
     if (typeof callback == 'function') {
     callback(studyplay_count);
     return ;
     }
     })
 } 
}

  这个插件有两个参数一个是options表示插件的一些基本设置;callback表示回调函数,该函数存在一个参数表示用户选择的星星数量。

   三、使用

  如果我们想在id为“z”的div上显示5个星星,默认有一颗星星选中,弹出选择星星的个数对话框,就可以如下编写代码:

<div id="z"></div>

<script type="text/JavaScript">
  $(document).ready(function(){
   $("#z").studyplay_star({MaxStar:5,CurrentStar:2},function(value){alert(value)});
  }); 
</script>

如果想显示评分结果 可以把Enabled设置false就ok了

 四、代码下载

/Files/studyplay/star.rar

[C#]ASP.NET缓存

mikel阅读(1172)

原文地址:http://www.codeproject.com/KB/aspnet/AspDotNetCache.aspx

AspDotNetCache2

 

介绍

缓存是在内存存储数据的一项技术,也是ASP.NET中提供的重要特性之一。例如你可以在复杂查询的时候缓存数据,这样后来的请求就不需要从数据库中取数据,而是直接从缓存中获取。通过使用缓存可以提高应用程序的性能。

主要有两种类型的缓存:

1.输出缓存Output caching
2.数据缓存Data caching

 

1. 输出缓存(Output Caching)

使用输出缓存,你可以缓存最后输出的HTML页面,当相同的页面再次请求的时候,ASP.NET不会再执行页面的生命周期和相关代码而是直接使用缓存的页面,语法如下:

<%@ OutputCache Duration=”60” VaryByParam=”None”  %> 

Duration 属性设置页面将被缓存60妙。任何的用户请求都会被缓存,在缓冲的60秒内相同的请求都会直接使用缓存的页面。当缓存过期后ASP.NET会再次执行页面代码并且为下一个60秒创建一个新的HTML缓存。

  <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
CodeFile="OutputCachingTest.aspx.cs" Inherits="OutputCachingTest" Title="Untitled Page" %>
 <%@ OutputCache Duration="20" VaryByParam="None" %>
 <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<div class="title">Output Cache</div>
Date: <asp:Label ID="lblDate" runat="server" Text="" />
Time: <asp:Label ID="lblTime" runat="server" Text="" />
</asp:Content>
protected void Page_Load(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.ToShortDateString();
lblTime.Text = DateTime.Now.ToLongTimeString();
}

在这个例子中页面将被缓存20秒。

通过查询字符串缓存(Cache by Query String )

在实际应用中页面往往会根据一些参数动态的改变页面的内容。如果你的页面是通过查询字符串来获取信息的,你可以根据查询字符串很容易的缓存页面的不同拷贝。VarByParam=”None”指定ASP.NET只存储缓存页面的一个拷贝。VarByParam=”*” 指定ASP.NET根据不同的查询字符串存储不同的缓存页面。

<%@ OutputCache Duration="60" VaryByParam="*" %>
<div align="right">
<a href="OutputCachingTest2.aspx">No Query String</a> |
<a href="OutputCachingTest2.aspx?id=1">ID 1</a> |
<a href="OutputCachingTest2.aspx?id=2">ID 2</a> |
<a href="OutputCachingTest2.aspx?id=3">ID 3</a> |
<a href="OutputCachingTest2.aspx?id=3&langid=1">ID 3</a>
</div> 


上面的例子中,在查询字符串中传了不同的ID.ASP.NET为每一个ID都存储了单独的缓存页面。这种方式会有一些问题就是当查询字符串范围很广的时候。
这个时候我们可以在VarByParam 属性中指定重要的查询字符串变量的名字,如下: 

<%@OutputCacheDuration="60"VaryByParam="id;langid"%>

这样,ASP.NET可以根据id” or “langid”来缓存不同的缓存版本。

 

自定义缓存(Custom Caching)

你也可以创建自定义的程序来缓存页面。ASP.NET提供了一种很便捷的方式来创建自定义缓存,使用VarByCustom属性指定自定义缓存类型的名字。

%@OutputCacheDuration="20"VaryByParam="None"VaryByCustom="browser"%

你还要创建为缓存生成自定义字符串的方法,如下:

public override stringGetVaryByCustomString(HttpContext context, stringcustom)
{
    if(custom == "browser")
    {
       returncontext.Request.Browser.Browser +
              context.Request.Browser.MajorVersion;
    }
    else
  
{
       return base.GetVaryByCustomString(context, custom);
    }
}

这个方法必须写在global.asax文件中。ASP.NET使用该方法返回的字符串来实现缓存,如果这个方法在不同的请求中返回相同的字符串,ASP.NET就会使用缓存的页面,否则就会生成新的缓存版本。

上面的例子中GetVaryByCustomString()方法根据浏览器的名字创建缓存字符串,ASP.NET会根据不同的浏览器请求创建不同版本的缓存。

控件缓存(Control Cache )

上面的缓存技术可以让你很容易的缓存整个页面,如果要缓存指定控件的内容,可以通过指定VaryByControl 属性来完成。

<%@OutputCacheDuration="20"VaryByControl="MyControl_1"%>

上面代码ASP.NET将会缓存MyControl_1控件20分钟。如果要根据一些属性值来缓存控件只需要将OutPutCache指令加入*.ascx页面。 

<%@Control Language="C#"AutoEventWireup="true"CodeFile="MyControl.ascx.cs"Inherits="Controls_MyControl"%>
<%
@OutputCacheDuration="20"VaryByControl="EmployeeID"%>
……
……

VaryByControl=”EmployeeID”告诉ASP.NET根据控件中声明的EmployeeID属性来创建不同版本的缓存。

.ascx.cs 文件加入EmplyeeID属性为ASP.NET 缓存使用。

private int_employeeID;
public intEmployeeID
{
   get{ return_employeeID; }
   set{ _employeeID = value; }
}
protected voidPage_Load(objectsender, EventArgs e)
{
   lblDate.Text = DateTime.Now.ToShortDateString();
   lblTime.Text = DateTime.Now.ToLongTimeString();
   lblEmployeeID.Text = EmployeeID.ToString();
}

在页面中增加控件并且设置 EmployeeID.

<%@RegisterSrc="Controls/MyControl.ascx"TagName="MyControl"TagPrefix="uc1"%>
<asp:ContentID="Content1"ContentPlaceHolderID="ContentPlaceHolder1"runat="Server">
    <
divalign="center">
        <
uc1:MyControlID="MyControl1"runat="server"EmployeeID="1"></uc1:MyControl>
    </
div>
</
asp:Content>

 

缓存配置文件(Cache Profile )

web.config可以配置缓存相关的设置,

<system.web>
  <
caching>
    <
outputCacheSettings>
      <
outputCacheProfiles>
     <
addname="ProductItemCacheProfile" duration="60"/>
   </
outputCacheProfiles>
</
outputCacheSettings>
   </
caching>
</
system.web>

你可以通过设置 CacheProfile=”ProfileName” 属性 来使用上面的配置:

%@OutputCacheCacheProfile="ProductItemCacheProfile"VaryByParam="None"%

2. 数据缓存(Data Caching)

ASP.NET还提供了另一种灵活的缓存类型:数据缓存。你可以将一些耗费时间的条目加入到一个对象缓存集合中,以键值的方式存储。

Cache["Name"] = data;

我们可以通过使用Cache.Insert()方法来设置缓存的过期,优先级,依赖项等。

date1 = DateTime.Now;
Cache.Insert("Date1", date1, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero);

ASP.NET允许你设置一个绝对过期时间或滑动过期时间,但不能同时使用。

缓存依赖项Cache dependency

缓存依赖项使缓存依赖于其他资源,当依赖项更改时,缓存条目项将自动从缓存中移除。缓存依赖项可以是应用程序的 Cache 中的文件、目录或与其他对象的键。如果文件或目录更改,缓存就会过期。

date2 = DateTime.Now;
string[] cacheKeys = { "Date1"};
CacheDependency cacheDepn = newCacheDependency(null, cacheKeys);
Cache.Insert("Date2", date2, cacheDepn);

上面的例子“Date2”缓存对象依赖“Date1”缓存条目,当 “Date1” 对象过期后“Date2” 将会自动过期。CacheDependency(null, cacheKeys)中的第一个参数为空是由于我们只监视缓存键的更改情况。

回调函数和缓存优先级(Callback Method and Cache Priority)

ASP.NET允许我们写一个回调函数,当缓存条目从缓存中移除的时候触发。还可以设置缓存条目的优先级。

protected void Page_Load(object sender, EventArgs e)
{
DateTime? date1 = (DateTime?)Cache["Date1"];
if (!date1.HasValue) // date1 == null
{
date1 = DateTime.Now;
Cache.Insert("Date1", date1, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero,
CacheItemPriority.Default, new CacheItemRemovedCallback(CachedItemRemoveCallBack));
}
DateTime? date2 = (DateTime?)Cache["Date2"];
if (!date2.HasValue) // date2 == null
{
date2 = DateTime.Now;
Cache.Insert("Date2", date2, null, DateTime.Now.AddSeconds(40), TimeSpan.Zero,
CacheItemPriority.Default, new CacheItemRemovedCallback(CachedItemRemoveCallBack));
}
// Set values in labels
lblDate.Text = date1.Value.ToShortDateString();
lblTime.Text = date1.Value.ToLongTimeString();
lblDate1.Text = date2.Value.ToShortDateString();
lblTime1.Text = date2.Value.ToLongTimeString();
}
private void CachedItemRemoveCallBack(string key, object value, CacheItemRemovedReason reason)
{
if (key == "Date1" || key == "Date2")
{
Cache.Remove("Date1");
Cache.Remove("Date2");
}
}

例子中创建了“Date1” 和 “Date2”缓存。“Date1” 在20秒后过期“Date2”为40秒。但是由于我们注册了移除的回调函数,当“Date1” 或 “Date2”其中一个过期都会执行CachedItemRemoveCallBack 方法,在这个方法中移除了两个缓存条目,ASP.NET还提供了处理缓存条目更新时的回调函数CacheItemUpdateCallback

[JQuery]基于jQuery的GridView-Flexigrid(2)-扩展和修复

mikel阅读(845)

上篇 我们简单介绍了下Flexigrid的基本情况,参数说明和功能介绍,同时秀了一下我修改后的样式,本篇我准备给大家介绍一下如何去扩展 Flexigrid的功能还有修复它一些存在的bug。为了方便比较,我同样也给原版的Flexigrid做了个Demo,同时提供四个的应用修改后代码 的Flexigrid Demo以供大家参考,希望本文对你有所帮助

废话少说,我们就此开始吧;

第一项:自然是重新定义的皮肤

这些只需修改对饮的CSS即可实现,只是非常长,就不贴出来了,有兴趣有耐心的朋友可以去研究下代码。

第二项:在首列添加一个checkbox列

1:首先在参数中添加一个showcheckbox的参数
2:然后再输出头时判断该属性,如果为真则输出一个列包含checkbox(用于全选)

1.if (p.showcheckbox) {
2.      var cth = $('<th/>');
3.      var cthch = $('<input type="checkbox"/>');
4.      cthch.addClass("noborder")
5.      //给该列添加一些自定义的属性,在生成数据行时需要用到这些属性
6.      cth.addClass("cth").attr({ 'axis': "col-1", width: "22", "isch": true }).append(cthch);
7.      $(tr).append(cth);
8.  }

 

 

3:然后在生成数据行时通过,因为数据行的生成的依据完全是根据thead中th的属性来创建的,这样我们可以通过上面设置的isch属性在制定的列上创建checkbox列

01.$.each(data.rows,function(i,row) //循环数据行
02.{
03. var tr = document.createElement('tr');
04. if (i % 2 && p.striped) tr.className = 'erow';
05. if (row.id) tr.id = 'row' + row.id;
06.  $('thead tr:first th',g.hDiv).each( //获取列头,循环列头来生成数据单元格,这里有个性能问题,即每次循环数据行都要检索列头,事实上没有必要
07.    function (){...});
08. ...
09.});

4:设置checkbox头列不参与拖拽列

5:给checkbox头列添加全选的事件实现

1.if (chkall.length > 0) {
2.                       chkall[0].onclick = g.checkAllOrNot;
3.                       return;
4.                   }
01.checkAllOrNot: function(parent) {
02.       var ischeck = $(this).attr("checked");
03.       $('tbody tr', g.bDiv).each(function() {
04.           if (ischeck) {
05.               $(this).addClass("trSelected");
06.           }
07.           else {
08.               $(this).removeClass("trSelected");
09.           }
10.       });
11.       $("input.itemchk", g.bDiv).each(function() {
12.           this.checked = ischeck;
13.           //Raise Event
14.           if (p.onrowchecked) {
15.               p.onrowchecked.call(this);
16.           }
17.       });
18.   },

6:最后一项是新增一个onrowchecked的事件,即在每一行的的checkbox选中状态发生变化时触发某个事件,onrowchecked在参数中注册。

7:新增getCheckedRows方法获取Grid中的选中行,返回是行主键的数组

第三项:修改每次都要获取记录数的bug,如果返回的记录数小于0,即没有总获取记录数,则使用上一次的获取到的记录数。

即总是在当前index为第一页是才从返回值从获取页面否则,沿用上次。和服务器端配合,可减少count的次数提高性能

第四项:Toolbar中的button增加displayname

源码toolbar中button只有name没有displayname,添加一个区分一下,不然感觉就像在C#中写了个中文的类名

第五项:快速检索增加正则表达式验证,增加操作符参数

Flexigrid有个快速检索的功能,虽然不太常用,但是偶尔的场景游泳,添加了两个参数。一个是操作标识(即=,LIKE等)
另一个正则表达式验证,即对输入查询的值进行简单的校验

第六项可从外部集成行事件

增加参数rowhanlder,在生成行时绑定事件,如双击,右键等

第七项:在行上绑定数据

增加参数rowbinddata,配合第六个操作,如在双击事件中获取该行的数据

第八项:兼容JQuery 1.3+

当我兴致匆匆的升级了JQuery框架后,发现脚本开始报错了,于是只能阅读代码,一个一个修正。

第九项:修正了Json数据的row为null时脚本报错的问题
这个不知道算不算bug,反正是当我服务器端没有数据返回null,原来的脚本报错了,于是加了个判断

第十项:新增列不参与toggle,只需配置列的toggle=false

希望某列不参与显示隐藏控制,即在生成下拉控制器时判断该属性为真则跳过

第十一项:修改AddData的组装逻辑,优化事件附件,提升性能

原来的逻辑是通过Dom操作,将tr td生成,并添加到行列中,最后在通过检索循环触发单元格的proccess事件和行默认事件(如单击选中事件),而且在上诉两个行为中存在致使浏览器重 绘Dom的操作。还存在一些不必要的循环,这样的逻辑在表格行列较多,客户机性能较差,又是IE6的话影响非常之明显。即时在我的电脑上 ,在IE6下仍然是表现不佳。

所以调整为添加行列统一将生成的html push到数组一次性付给tbody,同时在生成单元格html时处理process事件(不要再次查找和循环,避免多次重绘dom)

第十二项:添加extParam参数可将外部参数动态注册到grid,实现如查询等操作

因为涉及到的修改较多,且多为跳跃式的(不连在一起),所以本文少贴代码了,大家可以自行从下载的代码中发现。如有疑问可留言或者EMAIl我(Xuanye.wan[at]gmail.com)

说了那么多,到底情况如何呢?眼见为实,看了我为大家准备的Demo吧

为了让大家有个直观的比较,我给原版的Flexigrid也写了个Demo,另外加上了一个跟踪(记录从Ajax请求完成,到Dom创建,事件附加所需的事件,只记录客户端时间),按在页面上F2可查看。

http://jscs.cloudapp.net/ControlsSample/OldGrid

下图是我的电脑访问时,IE6,IE7,IE8 的加载时间。

顺便说下,我的机器还可以的缘故差距可能不明显,但是当客户机配置较差时,2秒和半秒的效果就很明显

IE6 936毫秒

image

IE7 905毫秒(比IE6好不了多少哦)

image

IE8 624毫秒(25行6列)

image 

在Opera10 下是360毫秒

chome3 170毫秒

Firefox3.5 下市380毫秒

余下都是修改后FlexiGrid的实例:

第一个是数据源为Json的实例,为了和前者有个比较,也加上了跟踪,按F2查看,其实这里比上面多个事件即右键

http://jscs.cloudapp.net/ControlsSample/JsonGrid

同样我也截了在多个浏览器下处理能力

IE6 266毫秒

image

IE7 249毫秒

image

IE8 171毫秒

image

在Opera10 下是83毫秒

Chome3 下是77毫秒

FireFox 下市110 毫秒

 

第二是Xml数据源的实例,效果和前者基本一致,只是数据源不同

http://jscs.cloudapp.net/ControlsSample/XmlGrid

 

第三是将一个已经存在的Html表格格式化成一个flexigrid Style Table
http://jscs.cloudapp.net/ControlsSample/FormatGrid

 

第四是一个连接数据库的实例数据源为Json。演示Flexigrid如何和服务器端配合,以达到我们项目的效果,代码还是比较简单我在本文的结束会提供完整的源代码(包含前几次文章的)
http://jscs.cloudapp.net/ControlsSample/DbGrid

 

最后顺便说一下,我在首页做了个导航,大家也可以直接访问首页,来查看前几次的实例。

http://jscs.cloudapp.net/

 

本文的代码下载(Dbank的网盘)

备注:

1:下载代码中的App_Data文件夹中包含本文实例数据库的SQL语句,Grid的部分使用的数据库是Northwind,如只查看Grid部分直接使用Northwind的也可以;

2:本文所有实例采用ASP.NET MVC 1.0 ,请确保已安装相关项目模板。

最后你的支持是我继续写作的动力

本文欢迎转载,但请在显著位置标注作者和来源!

本文地址:http://www.cnblogs.com/xuanye/archive/2009/11/08/1598564.html

[JQuery]基于jQuery的GridView-FlexiGrid的使用和改造(1)--如何使用

mikel阅读(930)

要说JQuery下最好用的Grid控件是什么?

inGrid? No!功能太简单

image

jqGrid?刚研究的时候还是3.4版,界面老土,代码臃肿。。虽然功能强大,所以NO!

最新beta版,基于JQuery.UI 界面变好看了,但是也因为它变得更臃肿了,具体没有深入的研究了

image

在我心灰意冷准备从头自己动手时,发现了Flexigrid,才知道世界原来还是很美好,其Ext风格的外观,简洁的代码,

强大的功能都深深地吸引了我。于是就用它了。

image

虽然它文档欠缺,但是有3个比较有用的Demo可以参考,本来想写一下如何在ASP.NET MVC中使用它,G了一下,忽然

在CodeProject有一篇介绍的文章已经非常细致了:http://www.codeproject.com/KB/aspnet/MVCFlexigrid.aspx

大家直接访问查看即可。

虽然FlexiGrid的外观已然不错,但是灰色的默认风格却是我不大喜欢,所以我把它改成蓝色了。

image

HTML结构导致比较中规中矩的,即每个部分都有单独的div容器包裹,功能比较独立也可以通过属性设置是否显示,有一点需要注意的就是

表头和表格实际的内容不在一个容器中,这样可以达到下拉滚动时表头固定,而在横向滚动时同步表头滚动。

修改CSS过程繁杂而漫长,但最终的效果自己还是非常满意,这里就不做分析了,因为真的很多,所以就略过了吧。(代码统一在下节下载)

先来看看它的功能有哪些吧?官方的功能列表

  • Resizable columns  (重设列宽,酷)
  • Resizable height and width  (重设表格大小,这个好像实际应用的不多)
  • Sortable column headers  (改变列的顺序)
  • Cool theme (很酷的风格,现在就更酷了)
  • Can convert an ordinary table  (可以格式化一个普通的表格)
  • Ability to connect to an ajax data source (XML and JSON[new])  (支持多种数据格式)
  • Paging (支持分页)
  • Show/hide columns (支持显示隐藏列) 
  • Toolbar (new)  (支持工具栏)
  • Search (new)  (支持快速检索)
  • Accessible API  (易于使用的API)
  • Many more (其他。白搭)

还是和其他控件一下,第一步来看下参数吧,默认参数比较多,大多的参数都比较有用

01.// 引用默认属性
02.        p = $.extend({
03.            height: 200, //flexigrid插件的高度,单位为px
04.            width: 'auto', //宽度值,auto表示根据每列的宽度自动计算,在IE6下建议设置具体值否则会有问题
05.            striped: true, //是否显示斑纹效果,默认是奇偶交互的形式
06.            novstripe: false,//没用过这个属性
07.            minwidth: 30, //列的最小宽度
08.            minheight: 80, //列的最小高度
09.            resizable: false, //resizable table是否可伸缩
10.            url: false, //ajax url,ajax方式对应的url地址
11.            method: 'POST', // data sending method,数据发送方式
12.            dataType: 'json', // type of data loaded,数据加载的类型,xml,json
13.          errormsg: '发生错误', //错误提升信息
14.            usepager: false, //是否分页
15.            nowrap: true, //是否不换行
16.            page: 1, //current page,默认当前页
17.            total: 1, //total pages,总页面数
18.            useRp: true, //use the results per page select box,是否可以动态设置每页显示的结果数
19.            rp: 25, // results per page,每页默认的结果数
20.            rpOptions: [10, 15, 20, 25, 40, 100], //可选择设定的每页结果数
21.            title: false, //是否包含标题
22.            pagestat: '显示记录从{from}到{to},总数 {total} 条', //显示当前页和总页面的样式
23.            procmsg: '正在处理数据,请稍候 ...', //正在处理的提示信息
24.            query: '', //搜索查询的条件
25.            qtype: '', //搜索查询的类别
26.            qop: "Eq", //搜索的操作符
27.            nomsg: '没有符合条件的记录存在', //无结果的提示信息
28.            minColToggle: 1, //允许显示的最小列数
29.            showToggleBtn: true, //是否允许显示隐藏列,该属性有bug设置成false点击头脚本报错。
30.            hideOnSubmit: true, //是否在回调时显示遮盖
31.            showTableToggleBtn: false, //是否显示【显示隐藏Grid】的按钮
32.            autoload: true, //自动加载,即第一次发起ajax请求
33.            blockOpacity: 0.5, //透明度设置
34.            onToggleCol: false, //当在行之间转换时,可在此方法中重写默认实现,基本无用
35.            onChangeSort: false, //当改变排序时,可在此方法中重写默认实现,自行实现客户端排序
36.            onSuccess: false, //成功后执行
37.            onSubmit: false, // 调用自定义的计算函数,基本没用       
38.            //Style
39.            gridClass: "bbit-grid"//样式          
40.        }, p);

另外的两个属性colModel,buttons 不是默认属性,内容说明如下

colModel : 列定义数组  

一个数组,数组的元素说明如下
colModel 参数说明:
display :显示名称
必须设置 ,类型:string, 默认值:无
name :字段名称
必须设置 ,类型:string,默认值:无
width :宽度
必须设置 , 类型:string ,默认值:无
sortable:是否可排序
类型:boolen , 默认值:false
process:处理程序
类型:function ,可格式化单元格
hide :是否隐藏
类型: boolen,默认值:false

buttons : 工具栏Button定义  

一个数组,数组的元素说明如下
buttons 参数说明:
name :Botton的标识
类型:string , 默认值:无
bclass :样式
类型:boolen,默认值:无
onpress :当button被点击时触发的事件
接受button的name为第一个参数,Grid为第二个参数的一个function
separator :是否分隔符
和前面四个属性互斥,当这个属性设置为True时,输出一个分隔符号,不是一个button 默认值:false

参数说明完毕,至于如何使用,那么请参考文中介绍的那篇文章吧?

虽然Flexigrid已然算是优秀,但是问题还是有?比如:

1:如果在列首添加checkbox列(默认不支持),

2:如何给行附加事件(如右键或双击)或者在最后列添加操作列?同时获取该列的数据?

3: 如何能够兼容 jQuery 1.3+?(默认不兼容)

4:如何改善性能问题(IE的脚本执行能力实在是可怜,特别在IE6下,当行列多时,总是有2-3秒的停滞)

5:如何让某列不参与Toggle?

…………………………

这些我将在下篇分析如何实现上述问题.都是我在实际项目中所解决的问题,修改列表

1:修改每次都要获取记录数的bug,如果返回的记录数小于0,即没有总获取记录数,则使用上一次的获取到的记录数
2008-12-30 
2:showToggleBtn 设置为false 时,点击头报错的bug(未修改)
3:修改提示信息为中文 
2008-12-30
4:修改默认样式,提供蓝色皮肤
2008-12-31
5:Toolbar中的button增加displayname;
6:快速检索增加正则表达式验证
7:增加选择列和全选功能 ,修改默认行点击选中为False。
8:可从外部集成行事件-示例:集成右键功能
2009-1-15
9:修改当jQuery升级到1.3.1后的bug
2009-2-4
10: 添加Resize方法
2009-02-16
11:优化Table的动态添加方式
2009-02-17
12:修正了Json数据的row为null时脚本报错的问题
2009-02-18
13 :新增getCheckedRows方法获取Grid中的选中行,返回是行主键的数组
2009-3-6
14: 添加grid获取Option的方法
2009-7-31
15
分页的样式略作调整,给按钮加上title
2009-8-3
16
新增列不参与toggle,只需配置列的toggle=false
修改了添加数据的逻辑,提高了性能 60% 左右
2009-8-18

你的支持是我继续写作的动力。

本文地址:http://www.cnblogs.com/xuanye/archive/2009/11/04/1596244.html

转载请注明原文地址和作者

[C#]c#扩展方法奇思妙用高级篇六:WinForm 控件选择器

mikel阅读(1318)

转载:http://www.cnblogs.com/ldp615/archive/2009/11/08/1598596.html

  在Web开发中,JQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象。但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器。好在我们有扩展方法,可以很方便的打造一个。

 我们先看几个类图,深入认识一下我们常用的WinForm控件:

ScrollableControl 

图1  ScrollableControl类图

ButtonBase图2  ButtonBase类图

TextBoxBase

图3  TextBoxBase类图

ListControl

图4  ListControl类图

Label

图5  Label类图

Other

图6  其它常用

 从图1中可以看出,Form与Button、Label一样,也是一个Control。

 WinForm中的一些控件(如Form、GroupBox、Panel)可以包含其它控件,我们可以通过Control类的Controls属性进行遍历。控件是可以层层包含的,如下图:

Form1 

图7  示例窗体

 Form1是顶级控件,它包含了四个子控件:groupBox1、groupBox2、button1、button2。groupBox1和groupBox2中也包含了多个控件。层层包含最终形成了一个树型结构。

 我们打造的WinForm的控件选择器,实质上就是一个树的遍历器。下是就是该选择器的参考实现代码: 

 1     public static IEnumerable<T> GetControls<T>(this Control control, Func<T, bool> filter) where T : Control
 2     {
 3         foreach (Control c in control.Controls)
 4         {
 5             if (c is T)
 6             {
 7                 T t = c as T;
 8                 if (filter != null)
 9                 {
10                     if (filter(t))
11                     {
12                         yield return t;
13                     }
14                     else
15                     {
16                         foreach (T _t in GetControls<T>(c, filter))
17                             yield return _t;
18                     }
19                 }
20                 else
21                     yield return t;
22             }
23             else
24             {
25                 foreach (T _t in GetControls<T>(c, filter))
26                     yield return _t;
27             }
28         }
29     }

  有了GetControls选择器,我们就可以在WinForm中进行一些“复杂”应用,示例如下(以图7为例): 

 1     // 构造函数
 2     public Form1()
 3     {
 4         InitializeComponent();
 5         //禁用所有Button
 6         this.GetControls<Button>(null).ForEach(b => b.Enabled = false);
 7         //反选groupBox1中CheckBox
 8         this.GetControls<CheckBox>(c => c.Parent == groupBox1)
 9             .ForEach(c => c.Checked = !c.Checked);
10         //将label1的前景色设为红色
11         this.GetControls<Label>(l => l.Name == "label1").FirstOrDefault().ForeColor
12             = Color.Red;
13     }

 附上常用的ForEach扩展:

1     public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
2     {
3         foreach (var item in source) 
4             action(item);
5     }

 感觉如何?欢迎批评指正!(代码仅供参考)

 

 本人系列文章《c#扩展方法奇思妙用》,敬请关注!

[WEB]支持UCenter的PHP建站程序一览

mikel阅读(839)

  建站程序是站长运营网站的根本,如何结合整合各个不同系统的程序、数据表、架构,提供统一的网站会员系统,一直是困扰很多站长的问题,而使用UCenter可以较为简单的实现不同系统之间的整合问题。

  UCenter是康盛创想推出的免费开源的建站工具,是各个建站产品之间信息直接传递的一个工具,康盛的Team在其Discuz论坛上收集了一批官方支持UCenter的建站产品,以对其进行双向推广,这里我对这个列表进行一些补充,添加一些最新的官方和非官方的支持UCenter的产品。

  支持 UCenter 建站程序一览表

  一、Discuz!

  http://www.comsenz.com/products/discuz
  论坛(BBS)程序站长应用率第一,php,开源,70万以上用户
  康盛创想官方支持UCenter产品,官方Discuz!论坛基础之上推出的UCenter产品
  历史版本 Discuz! 6.1.0
  当前版本 Discuz! 7.0.0

  二、UCenter Home

  http://www.comsenz.com/products/uchome
  国内SNS(社交网络)建站程序站长应用率第一,php,开源,5万以上用户
  康盛创想官方支持UCenter产品
  历史版本 UCenter Home 1.0.0 UCenter Home 1.2.0 UCenter Home 1.5.0
  当前版本 UCenter Home 2.0.0

  三、SupeSite

  http://www.comsenz.com/products/supesite
  网络社区站长常用的CMS产品,php,依托康盛创想社区产品开发
  康盛创想官方支持UCenter产品。
  历史版本 SupeSite 6.0.0_UC
  当前版本 SupeSite 7.0.0

  四、帝国CMS(ecms)

  http://www.phome.net 
  php型CMS程序站长应用目前支持率较高,php,2009年12月8日开源。
  官方支持UCenter
  历史版本 帝国 eCMS 5.1
  当前版本 帝国 eCMS V6.0测试版

  五、PHPcms
  
  http://www.phpcms.cn
  php型CMS程序中小门型应用目前支持率较高,php,开源产品。
  官方支持UCenter
  历史版本 PHPcms 2008 正式版
  当前版本 PHPcms 2008 SP1 正式版

  六、HDwiki 
  
  http://kaiyuan.hudong.com
  国内Wiki程序应用率第一,php,开源
  官方支持UCenter
  历史版本 HDWiki 3.0.0 HDWiki 4.0.0 HDWiki 4.0.2
  当前版本 HDWiki 4.0.5 正式版

  七、PBdigg
  
  http://www.pbdigg.com
  Digg类CMS,php
  官方支持UCenter
  当前版本 PBdigg 2.0

  八、爱聚合
  
  http://www.aijuhe.net
  国内独创的聚合型CMS,php,根据关键词自动聚合资讯、话题、图片和视频4大类内容
  官方支持UCenter
  历史版本 爱聚合 AiJuhe 4.0.0 AiJuhe V5.0
  当前版本 爱聚合 中文版 AiJuhe V6.0

  九、Modoer
  
  http://www.modoer.com
  点评功能CMS,php
  官方支持UCenter
  历史版本 Modoer 1.1
  当前版本 Modoer v1.2 正式版

  十、Feedig
  
  http://www.feedig.com
  feed类博客聚合CMS,php,主要针对UCenter home开发版本
  官方支持 UCenter
  当前版本 Feedig for Ucenter Home

  十一、ECShop
  
  http://www.ecshop.com
  商城类(B2C)建站程序,php
  官方支持 UCenter
  当前版本 ECShop 2.6.1

  十二、ECMall
  
  http://ecmall.shopex.cn
  商城类(C2C)建站程序,php
  官方支持UCenter
  当前版本 ECMall 1.1 final

  十三、SupeV
  
  http://union.ku6.com
  影视CMS,php
  官方支持UCenter
  当前版本 SupeV 1.01

  十四、落伍分类信息(ebcms)
  
  http://www.php.com.cn
  分类信息CMS,php
  官方支持UCenter
  历史版本 ebcms 1.0
  当前版本 落伍php分类v2.0 beta版本

  十五、 织梦CMS(DedeCms)
  
  http://www.dedecms.com
  php型CMS程序中小门型应用目前支持率较高,php,开源。
  官方支持UCenter
  历史版本 DedeCms 5.3
  当前版本 DedeCms 5.5

  十六、赛问(cyask)
  
  http://www.cyask.com
  php的问答类应用,类似百度知道,开源。
  官方支持UCenter
  当前版本 Cyask3.2
  
  十七、PHPsay

  http://www.phpsay.com
  基于PHP+MYSQL架构的WEB2.0开源家族贴吧系统,类似百度贴吧。
  支持UCenter
  当前版本 PhpSay 2.0.6

  十八、Mediawiki 1.13.2
  
  http://www.mediawiki.org
  Mediawiki 1.13.2+UCenter GBK整合精简版
  整合方案:http://www.discuz.net/thread-1077748-1-2.html

  ……


原创文章如转载,请注明:转载自月光博客 [ http://www.williamlong.info/ ]
本文链接地址:http://www.williamlong.info/archives/1967.html

[测试]Nunit框架在VS2005环境下单步调试

mikel阅读(893)

1、  安装Nunit ,可以去官方网站下载最新版本(http://www.nunit.org/

2、  工程属性->配置属性->调试->启动操作里把调试模式改为程序,然后把启动应用程序设置为你的nunitguiexe

 

 

3、  调用命令行程序(路径=系统盘:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\) sn.exe -k mytest.snk

然后把创建好的mytest.snk加入的工程中。设置参见下图(选中工程右键--Properties--Signning)

 

4、  设置FRIMLEC.UnitTest为启动项,然后在代码里设置断点,直接点运行,就ok了。

 

5、  单步调试过程中

单元测试类需要继承与DatabaseFixture

 

6、  单元测试成功

 

7、  单元测试失败

 

版权

作者:灵动生活

出处:http://www.cnblogs.com/ywqu

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。