ASP.NET自定义控件组件开发 第一章 第三篇

 

第三篇:第一章的完结篇

系列文章链接:

ASP.NET自定义控件组件开发 第一章 待续

ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

ASP.NET自定义控件组件开发 第一章 第三篇

ASP.NET自定义控件组件开发 第二章 继承WebControl的自定义控件

ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

ASP.NET自定义控件组件开发 第五章 模板控件开发

ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

ASP.NET2.0组件控件开发视频 初体验

第二章讲解:继承WebControl 的控件

相信大家看了前几篇文章后应该觉得自定义控件很简单,无非就是把一大堆的html代码包装一下就行了。不错,前

几篇写的控件确实很简单。不知道大家想过没有,难道我们每次写控件都要大费力气的把一大堆的html代码写进去吗。

不知道大家试了没有:如果在write.Write()方法中写的html代码有了错误,如果把<table..>写成了<talbe..>,在编译

的时候,编译器是不会发现错误,但是当我们把控件拖上来使用的时候,就发现控件的呈现错误。就是说,这样的错误只能

到最后才能被我们发现,这样我们又得回去改代码,然后重新的编译,生成。

我们开发的那个控件真的很好的,我们也也许没有考虑到浏览器版本的问题,因为不同的浏览器对html的不同版本的显

示还是有区别的。看看我们的代码,我们就敢保证我们的控件在所有的浏览器上都显示的是我们想要的结果吗?

基于上述原因,我们对之前的控件再来一次修改。

在.NET中,我们写代码经常用到他的智能感应功能,比如我们写完后加个".",然后,后面的一些属性,方法都显示出来

了 。而且在编译的时候,也提示我们一些错误信息。

下面我们就来改下:

1 amespace CreditCardForm
2 {
3     public class CreditCardForm3:CreditCardForm2 
4     {

因为我们之前开发的控件已经实现了很多的特性,我们不想再意义的重新实现,所以就继承前面已经有的控件,相信大家

都理解这点。

 writer.Write("<table style='width:287px;height:128px;border-width:0'>");
           

大家还记得这段代码吧,我们想显示一个table,而且确定他的一些属性等等。如前所说,出错的可能很大,而且兼容也

有问题。怎样改?

这样:

我们用.NET里面的专门用来生成这些html标记的一些方法和属性

1 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "287px");
2             writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "128px");
3             writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
4             writer.AddAttribute(HtmlTextWriterAttribute.Id, "mytable");
5             writer.RenderBeginTag(HtmlTextWriterTag.Table);

这段代码和上端代码的最终的显示结果都是一样的(都生成相同的html标记)。也许大家会认为这段代码很多,难道写

这么多的代码就是好的吗,还不如之前的方便。但是,想想之前所说的问题,这段代码就解决了那些问题。

代码我来解释下:用AddStyleAttribute方法来添加CCS样式;AddStyleAttribute添加非CSS样式,如name,id等,

用RenderBeginTag来添加开始的标记。还有一点就是这些代码都是“反的”:先定义样式,属性,最后才定义我们要写的

个table标记。就是说,想给某个标记加属性,要先写属性,

样式的语句,在写这个标记。

1 writer.RenderBeginTag(HtmlTextWriterTag.Table);

看看上面的代码,显示的是个table标记,如果想显示tr?这样做:

1  writer.RenderBeginTag(HtmlTextWriterTag.Tr);

大家应该明白我的意思了吧:HtmlTextWriterTag接不同的属性,就显示不同的标记。

还有一点要特别的注意,有开始,就是结束。我们用了一个RenderBeginTag方法,就一定要有个RenderEndTag方法

与之对应。

看个例子:

1  writer.RenderBeginTag(HtmlTextWriterTag.Td);
2             writer.Write(PaymentMethodText);
3             writer.RenderEndTag();

大家懂了吧!

我把代码贴上,大家看看,有问题就说!

  1 protected override void Render(HtmlTextWriter writer)
  2        {
  3            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "287px");
  4            writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "128px");
  5            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
  6            writer.AddAttribute(HtmlTextWriterAttribute.Id, "mytable");
  7            writer.RenderBeginTag(HtmlTextWriterTag.Table);
  8
  9            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 10
 11            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 12            writer.Write(PaymentMethodText);
 13            writer.RenderEndTag();
 14
 15            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 16            writer.AddAttribute(HtmlTextWriterAttribute.Name, "PaymentMethod");
 17            writer.AddAttribute(HtmlTextWriterAttribute.Id, "PaymentMethod");
 18            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
 19            writer.RenderBeginTag(HtmlTextWriterTag.Select);
 20
 21            writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");
 22            writer.RenderBeginTag(HtmlTextWriterTag.Option);
 23            writer.Write("Master");
 24            writer.RenderEndTag();
 25
 26            writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
 27            writer.RenderBeginTag(HtmlTextWriterTag.Option);
 28            writer.Write("Visa");
 29            writer.RenderEndTag();
 30
 31            writer.RenderEndTag();
 32            writer.RenderEndTag();
 33            writer.RenderEndTag();
 34
 35            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 36            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 37            writer.Write(CreditCardNoText);
 38            writer.RenderEndTag();
 39
 40            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 41            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
 42            writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");
 43            writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");
 44            writer.RenderBeginTag(HtmlTextWriterTag.Input);
 45            writer.RenderEndTag();
 46            writer.RenderEndTag();
 47            writer.RenderEndTag();
 48
 49            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 50            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 51            writer.Write(CardholderNameText);
 52            writer.RenderEndTag();
 53
 54            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 55            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
 56            writer.AddAttribute(HtmlTextWriterAttribute.Name, "CardholderName");
 57            writer.AddAttribute(HtmlTextWriterAttribute.Id, "CardholderName");
 58            writer.RenderBeginTag(HtmlTextWriterTag.Input);
 59            writer.RenderEndTag();
 60            writer.RenderEndTag();
 61            writer.RenderEndTag();
 62
 63            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 64            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 65            writer.Write(ExpirationDateText);
 66            writer.RenderEndTag();
 67
 68            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 69            writer.AddAttribute(HtmlTextWriterAttribute.Name, "Month");
 70            writer.AddAttribute(HtmlTextWriterAttribute.Id, "Month");
 71            writer.RenderBeginTag(HtmlTextWriterTag.Select);
 72            for (int month = 1; month < 13; month++)
 73            {
 74                writer.AddAttribute(HtmlTextWriterAttribute.Value, month.ToString());
 75                writer.RenderBeginTag(HtmlTextWriterTag.Option);
 76                writer.Write(month.ToString());
 77                writer.RenderEndTag();
 78            }
 79
 80            writer.RenderEndTag();
 81
 82            writer.Write("&nbsp");
 83
 84            writer.AddAttribute(HtmlTextWriterAttribute.Name, "Year");
 85            writer.AddAttribute(HtmlTextWriterAttribute.Id, "Year");
 86            writer.RenderBeginTag(HtmlTextWriterTag.Select);
 87
 88            for (int year =2008; year < 2015; year++)
 89            {
 90                writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());
 91                writer.RenderBeginTag(HtmlTextWriterTag.Option);
 92                writer.Write(year.ToString());
 93                writer.RenderEndTag();
 94            }
 95
 96            writer.RenderEndTag();
 97
 98            writer.RenderEndTag();
 99            writer.RenderEndTag();
100
101
102            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
103            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
104            writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
105            writer.RenderBeginTag(HtmlTextWriterTag.Td);
106            writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
107            writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
108            writer.RenderBeginTag(HtmlTextWriterTag.Input);
109            writer.RenderEndTag();
110            writer.RenderEndTag();
111            writer.RenderEndTag();
112
113           //table的结束标记
114            writer.RenderEndTag();
115
116           
117
118
119        }

下面开始说说。状态的管理,即ViewState;

之前的控件还有一个问题:

如下:

我们在页面后面写代码:

1 protected void Page_Load(object sender, EventArgs e)
2     {
3         if (!this.IsPostBack)
4         {
5             CreditCardForm2_1.PaymentMethodText = " 我的支付方式";
6             CreditCardForm2_1.CardholderNameText = "小洋";
7         }
8     }

运行页面看见:

但是当你点击”提交“按钮,页面马上就变为了如下:

变回来了!!!!?????

这里就要讲讲ASP.NET的页面保存值的方式:因为现在的ASP.NET网站是基于http这种无状态协议的。大家应该都懂。

在ASP.NET的我们提交的一个页面,虽然看起来是一样的,但是他们本质上已经不是同一个页面了。而是我们现在看见的页

面获取了之前提交的那个页面的一些状态值。关于这点,到第四章详细讲述”页面的生命周期“中讲。

所有我们就要用个ViewState来保存页面回传的值。这里我不想讲很多的理论东西,大家先看看现在的问题怎样解决:

public override string PaymentMethodText
        {
            get
            {
                return ViewState["PaymentMethodText"] != null ? (string)ViewState["PaymentMethodText"] : "支付方式";
            }
            set
            {
                ViewState["PaymentMethodText"] = value;
            }
        }

因为我们继承于CreditCardForm2,大家看看我们在CreditCardForm2中写的:

 1 
 2         [Browsable (true )]//在属性窗口中是否可见
 3         [Category ("Appearance")]//属性的分类,如,行为,外观,大家可以在属性窗口看见这样的分类
 4         [DefaultValue ("支付方式")]
 5         [Description ("支付方式")]//这些是显示在属性窗口底下的
 6 
 7          //virtual 方便以后二次开发
 8         public virtual string PaymentMethodText
 9         {
10             get
11             {
12                 return paymentMethod;
13             }
14             set
15             {
16                 paymentMethod = value;
17             }
18         }
19 

注意:Virtual。

这样之后,我们的控件就完成了。完整的代码如下:希望大家支持!

  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Web;
  5using System.Web.UI;
  6using System.Web.UI.WebControls;
  7
  8namespace CreditCardForm
  9{
 10    public class CreditCardForm3:CreditCardForm2 
 11    {
 12        public override string PaymentMethodText
 13        {
 14            get
 15            {
 16                return ViewState["PaymentMethodText"] != null ? (string)ViewState["PaymentMethodText"] : "支付方式";
 17            }
 18            set
 19            {
 20                ViewState["PaymentMethodText"] = value;
 21            }
 22        }
 23
 24        public override string CreditCardNoText
 25        {
 26            get
 27            {
 28                return ViewState["CreditCardNoText"] != null ? (string)ViewState["CreditCardNoText"] : "信用卡号";
 29            }
 30            set
 31            {
 32                ViewState["CreditCardNoText"] = value;
 33            }
 34        }
 35
 36        public override string CardholderNameText
 37        {
 38            get
 39            {
 40                return ViewState["CardholderNameText"] != null ? (string)ViewState["CardholderNameText"] : "持卡人";
 41            }
 42            set
 43            {
 44                ViewState["CardholderNameText"] = value;
 45            }
 46        }
 47
 48        public override string ExpirationDateText
 49        {
 50            get
 51            {
 52                return ViewState["ExpirationDateText"] != null ? (string)ViewState["ExpirationDateText"] : "过期时间";
 53            }
 54            set
 55            {
 56                ViewState["ExpirationDateText"] = value;
 57            }
 58        }
 59
 60        public override string SubmitButtonText
 61        {
 62            get
 63            {
 64                return ViewState["SubmitButtonText"] != null ? (string)ViewState["SubmitButtonText"] : "提交";
 65            }
 66            set
 67            {
 68                ViewState["SubmitButtonText"] = value;
 69            }
 70        }
 71        protected override void Render(HtmlTextWriter writer)
 72        {
 73            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "287px");
 74            writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "128px");
 75            writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
 76            writer.AddAttribute(HtmlTextWriterAttribute.Id, "mytable");
 77            writer.RenderBeginTag(HtmlTextWriterTag.Table);
 78
 79            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 80
 81            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 82            writer.Write(PaymentMethodText);
 83            writer.RenderEndTag();
 84
 85            writer.RenderBeginTag(HtmlTextWriterTag.Td);
 86            writer.AddAttribute(HtmlTextWriterAttribute.Name, "PaymentMethod");
 87            writer.AddAttribute(HtmlTextWriterAttribute.Id, "PaymentMethod");
 88            writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
 89            writer.RenderBeginTag(HtmlTextWriterTag.Select);
 90
 91            writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");
 92            writer.RenderBeginTag(HtmlTextWriterTag.Option);
 93            writer.Write("Master");
 94            writer.RenderEndTag();
 95
 96            writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
 97            writer.RenderBeginTag(HtmlTextWriterTag.Option);
 98            writer.Write("Visa");
 99            writer.RenderEndTag();
100
101            writer.RenderEndTag();
102            writer.RenderEndTag();
103            writer.RenderEndTag();
104
105            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
106            writer.RenderBeginTag(HtmlTextWriterTag.Td);
107            writer.Write(CreditCardNoText);
108            writer.RenderEndTag();
109
110            writer.RenderBeginTag(HtmlTextWriterTag.Td);
111            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
112            writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");
113            writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");
114            writer.RenderBeginTag(HtmlTextWriterTag.Input);
115            writer.RenderEndTag();
116            writer.RenderEndTag();
117            writer.RenderEndTag();
118
119            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
120            writer.RenderBeginTag(HtmlTextWriterTag.Td);
121            writer.Write(CardholderNameText);
122            writer.RenderEndTag();
123
124            writer.RenderBeginTag(HtmlTextWriterTag.Td);
125            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
126            writer.AddAttribute(HtmlTextWriterAttribute.Name, "CardholderName");
127            writer.AddAttribute(HtmlTextWriterAttribute.Id, "CardholderName");
128            writer.RenderBeginTag(HtmlTextWriterTag.Input);
129            writer.RenderEndTag();
130            writer.RenderEndTag();
131            writer.RenderEndTag();
132
133            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
134            writer.RenderBeginTag(HtmlTextWriterTag.Td);
135            writer.Write(ExpirationDateText);
136            writer.RenderEndTag();
137
138            writer.RenderBeginTag(HtmlTextWriterTag.Td);
139            writer.AddAttribute(HtmlTextWriterAttribute.Name, "Month");
140            writer.AddAttribute(HtmlTextWriterAttribute.Id, "Month");
141            writer.RenderBeginTag(HtmlTextWriterTag.Select);
142            for (int month = 1; month < 13; month++)
143            {
144                writer.AddAttribute(HtmlTextWriterAttribute.Value, month.ToString());
145                writer.RenderBeginTag(HtmlTextWriterTag.Option);
146                writer.Write(month.ToString());
147                writer.RenderEndTag();
148            }
149
150            writer.RenderEndTag();
151
152            writer.Write("&nbsp");
153
154            writer.AddAttribute(HtmlTextWriterAttribute.Name, "Year");
155            writer.AddAttribute(HtmlTextWriterAttribute.Id, "Year");
156            writer.RenderBeginTag(HtmlTextWriterTag.Select);
157
158            for (int year =2008; year < 2015; year++)
159            {
160                writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());
161                writer.RenderBeginTag(HtmlTextWriterTag.Option);
162                writer.Write(year.ToString());
163                writer.RenderEndTag();
164            }
165
166            writer.RenderEndTag();
167
168            writer.RenderEndTag();
169            writer.RenderEndTag();
170
171
172            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
173            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
174            writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
175            writer.RenderBeginTag(HtmlTextWriterTag.Td);
176            writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
177            writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
178            writer.RenderBeginTag(HtmlTextWriterTag.Input);
179            writer.RenderEndTag();
180            writer.RenderEndTag();
181            writer.RenderEndTag();
182
183            writer.RenderEndTag();
184
185           
186
187
188        }
189    }
190}
191

ASP.NET自定义控件组件开发 第一章 第三篇 第一章的完结篇的更多相关文章

  1. ASP.NET自定义控件组件开发 第一章 第三篇

    原文:ASP.NET自定义控件组件开发 第一章 第三篇 第三篇:第一章的完结篇 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待 ...

  2. ASP.NET自定义控件组件开发 第一章 第二篇 接着待续

    原文:ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 很感谢大家给我的第一篇ASP.NET控件开发的支持!在写这些之前,我也看了 ...

  3. ASP.NET自定义控件组件开发 第一章 待续

    原文:ASP.NET自定义控件组件开发 第一章 待续 第一章:从一个简单的控件谈起 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  4. ASP.NET自定义控件组件开发 第一章 第一章:从一个简单的控件谈起

    第一章:从一个简单的控件谈起 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第三 ...

  5. ASP.NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  6. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经 ...

  7. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡

    原文:ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl 后篇 --事件冒泡 CompositeControl  后篇 --事件冒泡 系列文章链接: ASP.NET ...

  8. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  9. ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

随机推荐

  1. CentOS6.5下源码安装多个MySQL实例及复制搭建

    多实例安装本节是在CentOS6.5下源码安装MySQL5.6.35的基础上,在同一台机器增加一个MySQL实例.参考Centos中安装多个mysql数据的配置实例,安装目录为/usr/local/m ...

  2. angular 基本树结构

    HTML: http://www.ngnice.com/showcase/#/tree/basic <link rel="stylesheet" href="vie ...

  3. Sqoop学习笔记_Sqoop的基本使用二(sqoop的import与export)

    Sqoop抽取从mysql抽取到hive sqoop抽取到mysql一样有两种方式一种是用command line的方式,一种是用sqoop opt文件调用的方式.(由于两种sqoop一已经记录了,现 ...

  4. 嘴巴题6 BZOJ3450JoyOI1952 Easy

    Time Limit: 10 Sec Memory Limit: 128 MB Submit: 936 Solved: 698 [Submit][Status][Discuss] Descriptio ...

  5. IQueryable与IEnumerable使用区别

    IQueryable会将查询语法转化为SQL查询语句,去数据库查询:IEnumerable则查询整张表,加载到内存中,再进行筛选. 所以,当查询的数据量较大的时候,则使用IQueryable.反之,数 ...

  6. MacOS 读写 NTFS 即插即用.

    1. 安装osxfusehttps://osxfuse.github.io/ 2. 安装brewhttps://brew.sh/index_zh-cn.html 3. 安装ntfs-3gbrew in ...

  7. tornado nginx 同源(Access-Control-Allow-Origin)错误处理记录

    如果以下两个步骤操作完还是没有解决问题,可能是因为程序出了别的错误,因为后来的调试中不论出什么问题它都是会返回同源错误..呵呵哒 1.在nginx.conf里配置server,在location里添加 ...

  8. SQL语句中GROUP BY的问题

    今天查询数据库时用到集合函数sum(drp),遇到问题: 百度后,确定如下问题:当select后面查询字段有sum(drp)以外的字段时,必须使用group by函数,对数据进行排序,且查询字段中除s ...

  9. SPSS统计分析案例:无空白列重复正交试验设计方差分析

    SPSS统计分析案例:无空白列重复正交试验设计方差分析 前面有讲过 SPSS正交试验设计及其方差分析 一篇文章,包含了一个典型的正交试验案例.然而在实际应用当中,主观客观条件复杂多变,在试验设计中就要 ...

  10. 取消 ios 上下滑动