首页 >> 编程知识

ASP.Net2.0的集合操作 --- List? 、Petshop4.0任何引用样式表.

ASP.Net2.0的集合操作 --- List?



在我以前的一篇随笔中曾提到不要在代码中散布遍历集合的操作.而是将遍历集合的操作放入集合本身. 
当时就想在.Net1.0中需要自己做Typed Collection,这样当然可以把遍历集合的操作放入集合本身. 
可是在.Net2.0中提供了泛型机制,我总不能为了隐藏遍历集合的操作而复古(自己做Typed Collection)吧. 
幸运的是发现.Net2.0已经为我想到这点了.你会发现在.Net2.0的List<T>中提供了ForEach(Action<T>)这么一个方法. 


 class Program 
    { 
        static void Main(string[] args) 
        { 
            List<string> strs = new List<string>(); 
            strs.Add("hello"); 
            strs.Add("world"); 
 
            strs.ForEach(Console.WriteLine)
        }       
    } 
怎么样? 看不到foreach(string str in strs)这样的操作了吧. 
为什么要这样做? 具体原因以及.Net1.0下的实现方法请见here(文章有点长, 耐心点喔, 看完应该有收获的)  

不过, List<T>对我来说还不够完美. 它无法实现对集合中满足特定条件的所有成员做某件事. 
也就是提供一个类似于下面这样的方法: 
 

ForSpecification(Predicate<T>, Action<T>);  

如果这样岂不是完美了? 既然做了ForEach为什么MS不做ForSpecification呢? 

现在我要想实现这样的功能只能用Find(Predicate<T>)方法找出集合中符合条件的元素, 然后再对它进行遍历(真丑陋) 

干脆象.Net1.0下自己实现一个集合操作的辅助类吧. 不过有了泛型的支持,实现方法肯定比以前的简单很多.不过目的和思想都是一样的. 


 class Algorithm 
    { 
 
        public static void ForSpecification<T>(IEnumerable<T> collection, Action<T> action, Predicate<T> filter) 
        { 
            foreach (T obj in collection) 
            { 
                if (filter(obj)) 
                     action(obj); 
            }            
        } 
    } 



class Program 
    { 
        static void Main(string[] args) 
        { 
            IList<string> strs = new List<string>(); 
            strs.Add("hello"); 
            strs.Add("world"); 
            strs.Add("hide"); 
 
            Algorithm.ForSpecification<string>( 
                strs, 
                Console.WriteLine,
                delegate(string str) 
                { 
                    //return true;        Hide will be output 
                    return str.Contains("o");   //if string contains 'o' then output 
                }); 
        }       
    } 

ok? 即使不支持ForEach以及Find方法的集合也可以使用这个辅助类来完成相应的操作. 
其实还可以在辅助类中添一些方法,比如让集合中的元素相加,并返回结果, 留给大家自己实现吧. 


Feedback
#1楼    回复  引用  查看     
2005-04-25 20:40 by CsOver 
关注更多关于.net2.0的文章!
#2楼    回复  引用  查看     
2005-05-05 22:09 by Ninputer 
也许这样可以,但是…… 
strs.Find(delegate(string obj){return obj.StartsWith("A");}).ForEach(delegate(string obj){Console.WriteLine(obj);}); 

我觉得这代码已经属于“WriteOnly”了
#3楼    回复  引用  查看     
2005-05-05 22:19 by Ninputer 
其实我希望这段代码可以这样: 
Console.WriteLine(For Each str In strs Which str.StartsWith("A")) 

如果VB的开发人员听取我的意见,让VB同时具有Python般的字符串特性和Fortan般的重复输入语句的话……
#4楼    回复  引用  查看     
2005-05-06 00:30 by idior 
Console.WriteLine(For Each str In strs Which str.StartsWith("A")) 

这个... 有点玄乎了吧. 
java的风格是已有的能做就不去加入新的功能, 比如stuct delegate 

C#固然可以有所创新, 但也不能走的太远对吧. 
#5楼 [楼主]   回复  引用  查看     
2005-05-06 10:08 by idior 
另外如果这样的话. 
strs.Find(delegate(string obj){return obj.StartsWith("A");}).ForEach(delegate(string obj){Console.WriteLine(obj);}); 

需要两次遍历, 不是吗?
#6楼    回复  引用  查看     
2005-08-18 11:24 by Ninputer 
发现VBF可以解决这个问题: 

[VB] 
strs.ForEach(Condition(Of String)(AddressOf StartsWithA, ConsoleWriteLine(Of String)()) 'StartsWithA要另写 

[C#] 
strs.ForEach(new Condition<string>(delegate(string obj){return obj.StartsWith("A"); }, delegate(string obj){Console.WriteLine(obj);} ); 

而你的方法,在C# 3.0中将变得更加优美动人(买个关子,呵呵)
#7楼 [楼主]   回复  引用  查看     
2005-08-18 11:35 by idior 
@Ninputer 
[C#] 
strs.ForEach(new Condition<string>(delegate(string obj){return obj.StartsWith("A"); }, delegate(string obj){Console.WriteLine(obj);} ); 

有这个方法吗? 

你想说lamda表达式? 呵呵 不如写篇文章介绍一下吧. 现在有pdc的资料了吗?
#8楼    回复  引用  查看     
2005-08-18 15:33 by Ninputer 
目前还没到可以公开的时候吧,我可以告诉你那个特性的名字叫extension methods :). 

lambda表达式也也是好东西呀。将lambda表达式和extension都用上,这个问题就有了最清晰的表达方式: 

[C#] 
strs.ForSpecification(|s|s.StartsWith("A"), delegate(string obj){ Console.WriteLine(obj); }); 

目前不知道VB9要不要加入lambda表达式,观望中……


Petshop4.0任何引用样式表.



petshop里的样式表.是怎么引用到页面的? 我在页面里面没有找到 <link href 
等待回复

4.0用的母版页 
都在主题文件夹 
..\Web\App_Themes\PetShop 
SkinFile.skin 
StyleSheet.css

default.aspx这个页面并没有用到母版页呀.

配置文档里设置了皮肤 
theme="PetShop" 


ASP.NET中CSS样式表是否必须放在App_Themes下面?

我放在其他目录下,想以编程的方式动态加入到页面中,有什么办法没有?

1. 修改标题:
this.Header.Title = "This is the new page title.";

2. 添加CSS样式:
Style style = new Style();
style.ForeColor = System.Drawing.Color.Navy;
style.BackColor = System.Drawing.Color.LightGray;
this.Header.StyleSheet.CreateStyleRule(style, null, "body");

3. 链接外部的CSS样式表:
HtmlLink link = new HtmlLink();
link.Attributes.Add("type", "text/css");
link.Attributes.Add("rel", "stylesheet");
link.Attributes.Add("href", "~/newstyle.css");
this.Header.Controls.Add(link); 


1、主题是什么

   主题由一组元素组成:外观、级联样式表 (CSS)、图像和其他资源。主题将至少包含外观。主题是在网站或 Web 服务器上的特殊目录中定义的。主题是一组Web Control的属性设置的集合,提供一种简单的方法设置控件的样式属性。

·         主题只在Web Control中有效

·         母板页(Master Page)上不能设置主题,但是主题可以在内容页面上设置

·         主题上设置的Web Control的样式覆盖页面上设置的样式

·         如果在页面上设置EnableTheming="false",主题无效

·         要在页面中动态设置主题,必须在页面生命周期Page_Preinit事件之前

·         主题包括.skin和.css文件

2、.skin是什么文件

.skin是外观文件,它包含各个控件(例如,Button、Label、TextBox 或 Calendar 控件)的属性设置。控件外观设置类似于控件标记本身,但只包含您要作为主题的一部分来设置的属性。例如,下面是 Button 控件的控件外观:

<asp:button runat="server" BackColor="lightblue" ForeColor="black" />

在 theme 文件夹中创建 .skin 文件。一个 .skin 文件可以包含一个或多个控件类型的一个或多个控件外观。可以为每个控件在单独的文件中定义外观,也可以在一个文件中定义所有主题的外观。有两种类型的控件外观 -“默认外观”和“已命名外观”:

·         当向页应用主题时,默认外观自动应用于同一类型的所有控件。如果控件外观没有 SkinID 属性,则是默认外观。例如,如果为 Calendar 控件创建一个默认外观,则该控件外观适用于使用本主题的页面上的所有 Calendar 控件。(默认外观严格按控件类型来匹配,因此 Button 控件外观适用于所有 Button 控件,但不适用于 LinkButton 控件或从 Button 对象派生的控件。)

·         已命名外观是设置了 SkinID 属性的控件外观。已命名外观不会自动按类型应用于控件。而应当通过设置控件的 SkinID 属性将已命名外观显式应用于控件。通过创建已命名外观,可以为应用程序中同一控件的不同实例设置不同的外观。

3、如何为相同控件定义不同的Skin

    使用SkinID为控件定义不同的skin,例如

<asp:Label runat=server Text="ThemedLabel" BackColor="Red" /> -label的缺省外观          <asp:Label runat=server SkinId="BoldLabel" Text="ThemedLabel_WithSkinId" BackColor="Blue" Font-Bold="true" /> - 命名为BoldLabel 的Label外观

   因此页面没有指定SkinId的label自动应用缺省外观,Label的SkinID设置为BoldLabel的Label控件应用BoldLabel外观

4、如何组织主题文件内容

   Theme文件下可以包含多个.Skin文件,所以可以多种方式组织你的主题文件,所有的主题文件在应用于页面之前会合并。

·         一个.skin文件包含所有的控件的外观定义

·         每个控件一个.skin文件

·         相同SkinID的控件放在一个.skin文件中

5、有没有办法定义好的Theme文件在多个程序中共享

服务器上的任何网站以及任何网站中的任何页面都可以引用全局主题,使用全局的主题可以在各个应用程序之间共享,例如你想创建一个全局共享的主题theme1。IIS 服务器上的全局主题放置位置类似于 \Inetpub\wwwroot\aspnet_client\system_web\v2.0.xxxxx\Themes\Theme1

应用程序级别的主题会覆盖全局的主题,例如你在应用程序中也定义了Theme1的主题,那么在应用程序级的Theme1主题将覆盖全局的主题Theme1

 

6、StyleSheetTheme是什么

   主题还可以包含级联样式表(.css 文件)。将 .css 文件放在主题目录中时,样式表自动作为主题的一部分应用。使用文件扩展名 .css 在主题文件夹中定义样式表。设置页面的 StyleSheetTheme 属性将主题作为样式表主题来应用。如果您希望能够设置页面上的各个控件的属性,同时仍然对整体外观应用主题,则可以将主题作为样式表主题来应用。EnableTheming="false"情况下StyleSheetTheme仍然有效。通过重写属性StyleSheetTheme来动态修改页面上的主题样式

 public override string StyleSheetTheme
 {
    get{ retrun "MyStyleSheetTheme"; } 
 }

7、主题(Theme/Skin)资源

一组相当不错的Theme,可以直接应用的项目开发中

    Theme预览:http://www.dotnettreats.com/SampleThemes/Default.aspx
    Theme下载:http://www.dotnettreats.com/tools/Default.aspx

这两天一直在学习ASP.NET,membership,skin,masterPage等,功能十分强大,由于决策层要求暂时不需要权限功能,所以就不提membership了,我就学习skin写下技术总结。

skin相对与css功能差不多,它结合ASP.NET更能方便的换皮肤,使页面风格统一,也可以让用户自己选择喜欢的界面,提高软件的可用性。

 protected void Page_PreInit()
  {
      Page.Theme = Request.QueryString["Theme"];
  }

 <div>
        <asp:Calendar ID="Calendar1" runat="server" Height="256px" Style="position: relative" Width="240px"
                    
            ></asp:Calendar>
       <div>
      <h2>选择你喜欢的皮肤</h2> 
      <a href="testcal.aspx?Theme=SkinFile">皮肤1</a> 
      <a href="testcal.aspx?Theme=SkinFile2">皮肤2</a>
    </div>



ASP.NET2.0之Theme(主题)
使用主题


定义的主题样式后缀为skin
指定主题
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Theme="myTheme"%>
在这个页面编辑模式时的控件样式未发生变化,浏览的时候就会发生变化,这个是典型的例子。对于我这样不懂美化界面的人才说,定义样式还是比较难的,因为在编辑模式当中无法直接预览样式。可以把Theme换成StylesheetTheme属性, 这样就可以直接在编辑模式中显示结果样式了。这里存在着样式修改的优先级.定义StylesheetTheme属性的话,可以在页面上再次修改样式.Theme优先级别最高。结果都是一样的
使用themes
1、在1个页面中应用Theme:
      如果想在某1个页面中应用Theme,直接在aspx文件中修改<%@ Page Theme="..." %>,比如你想这个页面应用default2 theme,设置<%@ Page Theme="..." %>就OK
 
2、在所有页面应用同1个Theme:
      如果要在所有页面上使用相同的Theme,在web.config中的<system.web>节点下加上句<pages theme="..."/>
3、让控件不应用Theme:
   有时我们不希望应用.skin中的风格,这时你只需设置控件的EnableTheming属性为false的时候就可以了。
 
另外要注意的是定义了Theme,页面的属性设置会失效。要页面属性生效。需要使用StylesheetTheme代替Theme。如下代码所示
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" StylesheetTheme="myTheme"%>
除此之外,我们还可以通过代码访问Theme。注意Page.Theme一定要在Page_PreInit事件之中或者之前定义,代码如下:
protected void Page_PreInit()
{
    Page.Theme = Server.HtmlEncode("myTheme");
}
 
还可以指定空间使用特性的样式
比如两个IMG控件,指定两个不同的图片,需指定SkinID属性
<asp:ImageButton ID="ImageButton1" runat="server" SkinID="OKButton" />
<asp:ImageButton ID="ImageButton2" runat="server" SkinID="CancelButton" />
 
不使用主题,使用CSS来改变
使用Style类
void Page_Load(Object sender, EventArgs e)
{
    Style myStyle = new Style();
 
    myStyle.BackColor = Color.Yellow;
    myStyle.ForeColor = Color.Green;
    myStyle.BorderStyle = BorderStyle.Dashed;
    myStyle.BorderWidth = new Unit(4);
 
    txtTextBox1.ApplyStyle( myStyle );
    txtTextBox2.ApplyStyle( myStyle );
    txtTextBox3.MergeStyle( myStyle );
}
添加样式表
<%@ Page Language="C#" %>
 
<script runat="Server">
 
void lbtnScript_Click(object s, EventArgs e)
{
    myLabel.CssClass = "myClass1";
}
 
void lbtnVerdana_Click(object s, EventArgs e)
{
    myLabel.CssClass = "myClass2";
}
 
</script>
 
<html>
<head>
 <style>
 
.myClass1
{
 font: 18pt script;
 color: blue;
}
 
.myClass2
{
 font: 24pt verdana;
 color: red;
}
 
</style>
<title>CssClassDynamic.aspx</title>
</head>
<form id="Form1" runat="Server">
    <asp:Label ID="myLabel" Text="Here is some text!" runat="Server" />
    <hr>
    <asp:LinkButton ID="lbtnScript" Text="Show Script!" OnClick="lbtnScript_Click" runat="Server" />
    <asp:LinkButton ID="lbtnVerdana" Text="Show Verdana!" OnClick="lbtnVerdana_Click" runat="Server" />
</form>
</body>
</html>
 
控件应用style属性的顺序如下:
a、StyleSheetTheme引用的风格
b、代码设定的控件属性(覆盖StyleSheetTheme)
c、Theme引用的风格(覆盖前面2个)
ASP.NET2.0之MasterPage
在网上看到一段关于MasterPage和aspx页面的区别
You create a Master Page in pretty much the same way as you create a normal ASP.NET page. A Master Page can contain the same Web controls, User controls, HTML content, and scripts that you would add to a standard ASP.NET page. There are three important differences between a Master Page and a normal ASP.NET page.
First, unlike a normal ASP.NET page, the name of a Master Page must end with the special extension .master. This extension marks the page as a Master Page. Furthermore, an ASP.NET application is configured so that you cannot request pages with the .master extension. It doesn't make sense to request a Master Page directly. Instead, you request content pages based on the Master Page.
Second, a Master Page includes a <%@ Master %> directive instead of the normal <%@ Page %> directive. The <%@ Master %> directive supports many of the same attributes as the <%@ Page %> directive. For example, you can specify the programming language of the page with the directive <%@ Master Language="vb" %>.
The final difference between a Master Page and a normal ASP.NET page is that a Master Page can contain zero or more ContentPlaceHolder controls. A ContentPlaceHolder control can be used only within a Master Page. This control marks an area of a Master Page that can be overridden by a particular content page.[引用地址]
 
类似Theme的应用方式,我们做一个简单的例子,对于需要在不同场合由于不同内容来替换的地方用:ContentPlaceHolder组件来定义就行。这样,一个模板就制作好了。
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="myMasterPage.master.cs" Inherits="myMasterPage" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Untitled Page</title>
</head>
    <form id="form1" runat="server">      
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </form>
</body>
</html>
下面建立一个你要显示内容的ASPX页面。将里面的所有html元素全清掉。注意保留下:
<%@ Page Language="C#" MasterPageFile="~/myMasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
或者是在Page_PreInit事件添加Master页
protected void Page_PreInit(object sender, EventArgs e)
{
    this.MasterPageFile = "~/myMasterPage.master";
}
  

参考网址: http://hr.tfcoal.com/portal/blog/tabid/56/EntryID/55/Default.aspx
ASP.Net2.0的集合操作 --- List? 、Petshop4.0任何引用样式表.(本文完毕)
下一篇:asp.net AJAX中的CascadingDropDown控件使用心得
上一篇:ASP.NET 学习笔记之PlaceHolder控件