第二章 繼承於WebControl的自定義控件
到現在爲止,我已經寫了三篇關於自定義控件開發的文章,很感謝大家的支持!不知道大家對我講的方式有什麼好的建議,我儘量使自定義控件的技術讓更多的程序員同胞接受。好了,開發開始了!
本章還是延續上章的例子,開發一個CreditCardForm控件。
其實本章也不難,相信大家看完後,也覺得很簡單!
我們首先開談談繼承Control和WebControl的區別:其實二者最大的區別就是在,如果我們開發的控件繼承WebControl,那麼我們的控件就支持更多的CSS樣式。而繼承於Control的自定義控件的樣式相對就少些。
其實還有一個區別就在開發的規範上。我們來簡單的看看上一章的自定義控件的代碼,主要來看看Render方法中的代碼:大家只掃一眼就可以了。
1 protected override void Render(HtmlTextWriter writer)
2 {
3 //顯示table標記
4 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "287px");
5 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, "128px");
6 writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
7 writer.AddAttribute(HtmlTextWriterAttribute.Id, "mytable");
8 writer.RenderBeginTag(HtmlTextWriterTag.Table);
9
10 //顯示table類的標記 包含 tr ,td 還有一些textbox,下拉框等
11 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
12
13 writer.RenderBeginTag(HtmlTextWriterTag.Td);
14 writer.Write(PaymentMethodText);
15 writer.RenderEndTag();
16
17 writer.RenderBeginTag(HtmlTextWriterTag.Td);
18 writer.AddAttribute(HtmlTextWriterAttribute.Name, "PaymentMethod");
19 writer.AddAttribute(HtmlTextWriterAttribute.Id, "PaymentMethod");
20 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
21 writer.RenderBeginTag(HtmlTextWriterTag.Select);
22
23 writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");
24 writer.RenderBeginTag(HtmlTextWriterTag.Option);
25 writer.Write("Master");
26 writer.RenderEndTag();
27
28 writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
29 writer.RenderBeginTag(HtmlTextWriterTag.Option);
30 writer.Write("Visa");
31 writer.RenderEndTag();
32
33 writer.RenderEndTag();
34 writer.RenderEndTag();
35 writer.RenderEndTag();
36
37 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
38 writer.RenderBeginTag(HtmlTextWriterTag.Td);
39 writer.Write(CreditCardNoText);
40 writer.RenderEndTag();
41
42 writer.RenderBeginTag(HtmlTextWriterTag.Td);
43 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
44 writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");
45 writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");
46 writer.RenderBeginTag(HtmlTextWriterTag.Input);
47 writer.RenderEndTag();
48 writer.RenderEndTag();
49 writer.RenderEndTag();
50
51 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
52 writer.RenderBeginTag(HtmlTextWriterTag.Td);
53 writer.Write(CardholderNameText);
54 writer.RenderEndTag();
55
56 writer.RenderBeginTag(HtmlTextWriterTag.Td);
57 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
58 writer.AddAttribute(HtmlTextWriterAttribute.Name, "CardholderName");
59 writer.AddAttribute(HtmlTextWriterAttribute.Id, "CardholderName");
60 writer.RenderBeginTag(HtmlTextWriterTag.Input);
61 writer.RenderEndTag();
62 writer.RenderEndTag();
63 writer.RenderEndTag();
64
65 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
66 writer.RenderBeginTag(HtmlTextWriterTag.Td);
67 writer.Write(ExpirationDateText);
68 writer.RenderEndTag();
69
70 writer.RenderBeginTag(HtmlTextWriterTag.Td);
71 writer.AddAttribute(HtmlTextWriterAttribute.Name, "Month");
72 writer.AddAttribute(HtmlTextWriterAttribute.Id, "Month");
73 writer.RenderBeginTag(HtmlTextWriterTag.Select);
74 for (int month = 1; month < 13; month++)
75 {
76 writer.AddAttribute(HtmlTextWriterAttribute.Value, month.ToString());
77 writer.RenderBeginTag(HtmlTextWriterTag.Option);
78 writer.Write(month.ToString());
79 writer.RenderEndTag();
80 }
81
82 writer.RenderEndTag();
83
84 writer.Write(" ");
85
86 writer.AddAttribute(HtmlTextWriterAttribute.Name, "Year");
87 writer.AddAttribute(HtmlTextWriterAttribute.Id, "Year");
88 writer.RenderBeginTag(HtmlTextWriterTag.Select);
89
90 for (int year =2008; year < 2015; year++)
91 {
92 writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());
93 writer.RenderBeginTag(HtmlTextWriterTag.Option);
94 writer.Write(year.ToString());
95 writer.RenderEndTag();
96 }
97
98 writer.RenderEndTag();
99
100 writer.RenderEndTag();
101 writer.RenderEndTag();
102
103
104 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
105 writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
106 writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
107 writer.RenderBeginTag(HtmlTextWriterTag.Td);
108 writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
109 writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
110 writer.RenderBeginTag(HtmlTextWriterTag.Input);
111 writer.RenderEndTag();
112 writer.RenderEndTag();
113 writer.RenderEndTag();
114
115 //table的結束標記
116 writer.RenderEndTag();
117
118
119
120
121 }
相信這段代碼大家都和熟悉。在這段代碼的作用主要顯示了一個table 以及table 之中的標記元素。
如果一這個控件已經寫好了,加入我們想要改改table的樣式,如把border設爲1,或者改變顯示的顏色等,那麼我們就
要再次打開這段代碼,修改代碼。其實這就不好。爲什麼?
其實這個方法中的代碼做了四件事:
1.顯示控件最外層的包含標記,即table
2.顯示最外層標記的一些屬性,如border.id等
3.顯示控件的主要內容 ,如,顯示輸入框,下拉框,按鈕。
4.顯示控件最外層包含標記的結束標記。
這樣看來,這個方法的職責就有四個。大家應該還記得面向對象設計的原創:單一職責。雖然這個元素一般用在類上,
但是我們更加要注意,這個原則用的宗旨:使對象只有一個變化的因素。這個原則也用在方法的設計上。
就是說,我們如果想要改變最外層標記table一些屬性,我們就影響了其他三個職責。同理,我們想改變其他的元素或者
內容,結果可想而知。
爲此,繼承WebControl的控件就更加的規範和靈活:
其實,繼承於WebControl的控件的顯示還是在Render方法中顯示,只是這個Render方法已經不由我們來寫了:
如下:
1
2 protected override void Render(HtmlTextWriter writer)
3 {
4 RenderBeginTag(writer);
5 RenderContens(writer);
6 RenderEndTag(writer);
7
8 }
因爲我們之前說,Render方法的職責有四個。所以WebControl的Render方法就把這些職責分離了。以後我們能就
可以獨立的改變一個因素了。大家也許奇怪:不是說有四個職責嗎,但是上面只是顯示了三個方法,其實在
RenderBeginTag()方法中包含顯示最外層標記樣式的方法。
所以我們只要分別重寫這三個方法,一個繼承WebControl的自定義的控件就成了。不要怕,方法很多,但是很簡單,而
且代碼我們都懂,之前差不多都講了的。
我想把寫成後的控件給大家看看,讓大家看下我們本章的目標:
大家看見沒有:是不是支持的樣式多了!!!
好了,我們來寫吧:不難哦:)
首先看看我們要的寫方法以及他們的功能:
protected override void Render(HtmlTextWriter writer)
{
//顯示最外層包含標記開始的標記,即,顯示<table ..>
RenderBeginTag(writer);
//顯示table標記內的內容,如<tr><td><input />等
RenderContens(writer);
//顯示最外層包含標記結束標記</table
RenderEndTag(writer);
}
現在的思路很清晰吧,首先來顯示<table....>
很簡單,只要如下就可以了。
1 protected override HtmlTextWriterTag TagKey
2 {
3 get
4 {
5 return HtmlTextWriterTag.Table;
6 }
7 }
不要奇怪,因爲RenderBeginTag()方法內部實際是調用了這個屬性來顯示的最外層的包含標記的。
好了,第一步就寫完了啊!簡答吧!
下面來顯示table的樣式,因爲我們的控件的最外層的標記是table,顯示他的樣式只要這樣就OK了。
1 protected override Style CreateControlStyle()
2 {
3 return new TableStyle(ViewState);
4 }
又寫完了一部分。。不難吧!接着看啊!
如果你的最外層的標記是<div >那麼,上面的那個方法你都不用寫.
下面就寫了RenderContent方法,不難,只記住這個方法的職責:顯示最外層標記的內容:
如下:
1 protected override void RenderContents(HtmlTextWriter writer)
2 {
3 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
4 writer.RenderBeginTag(HtmlTextWriterTag.Td);
5 writer.Write(PaymentMethod);
6 writer.RenderEndTag();
7
8 writer.RenderBeginTag(HtmlTextWriterTag.Td);
9
10 writer.AddAttribute(HtmlTextWriterAttribute.Id, PaymentMethodListId);
11 writer.AddAttribute(HtmlTextWriterAttribute.Name, PaymentMethodListName);
12 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
13 writer.RenderBeginTag(HtmlTextWriterTag.Select);
14
15 writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");
16 writer.RenderBeginTag(HtmlTextWriterTag.Option);
17 writer.Write("Master");
18 writer.RenderEndTag();
19
20 writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
21 writer.RenderBeginTag(HtmlTextWriterTag.Option);
22 writer.Write("Visa");
23 writer.RenderEndTag();
24
25 writer.RenderEndTag();
26
27 writer.RenderEndTag();
28 writer.RenderEndTag();
29 //****************************************************************************
30 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
31 writer.RenderBeginTag(HtmlTextWriterTag.Td);
32 writer.Write(CreditCardNo);
33 writer.RenderEndTag();
34
35 writer.RenderBeginTag(HtmlTextWriterTag.Td);
36 writer.AddAttribute(HtmlTextWriterAttribute.Id, CreditCardNoTextId);
37 writer.AddAttribute(HtmlTextWriterAttribute.Name, CreditCardNoTextName);
38 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
39 writer.RenderBeginTag(HtmlTextWriterTag.Input);
40 writer.RenderEndTag();
41
42 writer.RenderEndTag();
43 writer.RenderEndTag();
44 //**************************************************************************************
45
46 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
47 writer.RenderBeginTag(HtmlTextWriterTag.Td);
48 writer.Write(CardholderName);
49 writer.RenderEndTag();
50
51 writer.RenderBeginTag(HtmlTextWriterTag.Td);
52 writer.AddAttribute(HtmlTextWriterAttribute.Name, CardholderNameTextName);
53 writer.AddAttribute(HtmlTextWriterAttribute.Id, CardholderNameTextId);
54 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
55 writer.RenderBeginTag(HtmlTextWriterTag.Input);
56 writer.RenderEndTag();
57
58 writer.RenderEndTag();
59 writer.RenderEndTag();
60 //***************************************************************************************
61
62 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
63 writer.RenderBeginTag(HtmlTextWriterTag.Td);
64 writer.Write(ExpirationDate);
65 writer.RenderEndTag();
66
67 writer.RenderBeginTag(HtmlTextWriterTag.Td);
68 writer.AddAttribute(HtmlTextWriterAttribute.Name, MonthListName);
69 writer.AddAttribute(HtmlTextWriterAttribute.Id, MonthListId);
70 writer.RenderBeginTag(HtmlTextWriterTag.Select);
71
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 writer.RenderEndTag();
80
81 /////////////////////////////////////
82
83 writer.Write(" ");
84
85 /////////////////////////////////////
86 writer.AddAttribute(HtmlTextWriterAttribute.Name, YearListName);
87 writer.AddAttribute(HtmlTextWriterAttribute.Id, YearListId);
88 writer.RenderBeginTag(HtmlTextWriterTag.Select);
89
90 for (int year = 2008; year < 2015; year++)
91 {
92 writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());
93 writer.RenderBeginTag(HtmlTextWriterTag.Option);
94 writer.Write(year.ToString());
95 writer.RenderEndTag();
96 }
97 writer.RenderEndTag();
98
99 writer.RenderEndTag();
100 writer.RenderEndTag();
101 //*****************************************************************************
102
103 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
104 writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
105 writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
106 writer.RenderBeginTag(HtmlTextWriterTag.Td);
107 writer.AddAttribute(HtmlTextWriterAttribute.Name, SubmitButtonName);
108 writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
109 writer.AddAttribute(HtmlTextWriterAttribute.Id, SubmitButtonId);
110 writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
111 writer.RenderBeginTag(HtmlTextWriterTag.Input);
112 writer.RenderEndTag();
113
114 writer.RenderEndTag();
115 writer.RenderEndTag();
116
117 //******************************************************************************
118
119
120 }
這樣就完了,大家看看上面的代碼,很熟悉吧,是啊,只是把我們之前的代碼分割開了,寫在不同的地方!
最後的那個RendEndTag(),你不寫!因爲,你override那個TagKey時,就已經調用了結束標記的方法。這樣,一個繼承WebControl的控件就完了!
好了,寫完了:完整的代碼如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Web;
5 using System.Web.UI;
6 using System.Web.UI.WebControls;
7
8 namespace CreditCardForm
9 {
10 public class CreditCardForm5:WebControl
11 {
12 #region 重寫包含標記
13
14 protected override Style CreateControlStyle()
15 {
16 return new TableStyle(ViewState);
17 }
18
19 protected override HtmlTextWriterTag TagKey
20 {
21 get
22 {
23 return HtmlTextWriterTag.Table;
24 }
25 }
26
27 //public virtual string BackImageUrl
28 //{
29 // get
30 // {
31 // return ((TableStyle)ControlStyle).BackImageUrl;
32 // }
33 // set
34 // {
35 // ((TableStyle)ControlStyle).BackImageUrl = value;
36 // }
37 //}
38
39
40 #endregion
41 #region ID
42 protected virtual string PaymentMethodListId
43 {
44 get
45 {
46 return "PaymentMethod";
47 }
48 }
49
50 protected virtual string CreditCardNoTextId
51 {
52 get
53 {
54 return "CreditCardNo";
55 }
56 }
57
58 protected virtual string CardholderNameTextId
59 {
60 get
61 {
62 return "CardholderName";
63 }
64 }
65
66 protected virtual string MonthListId
67 {
68 get
69 {
70 return "Month";
71 }
72 }
73
74 protected virtual string YearListId
75 {
76 get
77 {
78 return "Year";
79 }
80 }
81
82 protected virtual string SubmitButtonId
83 {
84 get
85 {
86 return "Submit";
87 }
88 }
89
90 #endregion
91 #region name
92 protected virtual string PaymentMethodListName
93 {
94 get
95 {
96 return "PaymentMethod";
97 }
98 }
99
100 protected virtual string CreditCardNoTextName
101 {
102 get
103 {
104 return "CreditCardNo";
105 }
106 }
107
108 protected virtual string CardholderNameTextName
109 {
110 get
111 {
112 return "CardholderName";
113 }
114 }
115
116 protected virtual string MonthListName
117 {
118 get
119 {
120 return "Month";
121 }
122 }
123
124 protected virtual string YearListName
125 {
126 get
127 {
128 return "Year";
129 }
130 }
131
132 protected virtual string SubmitButtonName
133 {
134 get
135 {
136 return "Sumit";
137 }
138 }
139 #endregion
140
141 #region 屬性
142 public virtual string PaymentMethod
143 {
144 get
145 {
146 return ViewState["PaymentMethod"] != null ? (string)ViewState["PaymentMethod"] : "支付方式";
147
148 }
149 set
150 {
151 ViewState["PaymentMethod"] = value;
152 }
153 }
154
155 public virtual string CreditCardNo
156 {
157 get
158 {
159 return ViewState["CreditCardNo"] != null ? (string)ViewState["CreditCardNo"] : "信用卡號";
160 }
161 set
162 {
163 ViewState["CreditCardNo"] = value;
164 }
165 }
166
167 public virtual string CardholderName
168 {
169 get
170 {
171 return ViewState["CardholderName"] != null ? (string)ViewState["CardholderName"] : "持卡人";
172 }
173 set
174 {
175 ViewState["CreditCardName"] = value;
176 }
177 }
178
179 public virtual string ExpirationDate
180 {
181 get
182 {
183 return ViewState ["ExpirationDate"]!=null ?(string)ViewState ["ExpirationDate"]:"過期時間";
184 }
185 set
186 {
187 ViewState["ExpirationDate"] = value;
188 }
189 }
190
191 public virtual string SubmitButtonText
192 {
193 get
194 {
195 return ViewState["SubmitButtonText"] != null ? (string)ViewState["SubmitButtonText"] : "提交";
196 }
197 set
198 {
199 ViewState["SubmitButtonText"] = value;
200 }
201
202 }
203 #endregion
204 protected override void RenderContents(HtmlTextWriter writer)
205 {
206 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
207 writer.RenderBeginTag(HtmlTextWriterTag.Td);
208 writer.Write(PaymentMethod);
209 writer.RenderEndTag();
210
211 writer.RenderBeginTag(HtmlTextWriterTag.Td);
212
213 writer.AddAttribute(HtmlTextWriterAttribute.Id, PaymentMethodListId);
214 writer.AddAttribute(HtmlTextWriterAttribute.Name, PaymentMethodListName);
215 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
216 writer.RenderBeginTag(HtmlTextWriterTag.Select);
217
218 writer.AddAttribute(HtmlTextWriterAttribute.Value, "0");
219 writer.RenderBeginTag(HtmlTextWriterTag.Option);
220 writer.Write("Master");
221 writer.RenderEndTag();
222
223 writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
224 writer.RenderBeginTag(HtmlTextWriterTag.Option);
225 writer.Write("Visa");
226 writer.RenderEndTag();
227
228 writer.RenderEndTag();
229
230 writer.RenderEndTag();
231 writer.RenderEndTag();
232 //****************************************************************************
233 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
234 writer.RenderBeginTag(HtmlTextWriterTag.Td);
235 writer.Write(CreditCardNo);
236 writer.RenderEndTag();
237
238 writer.RenderBeginTag(HtmlTextWriterTag.Td);
239 writer.AddAttribute(HtmlTextWriterAttribute.Id, CreditCardNoTextId);
240 writer.AddAttribute(HtmlTextWriterAttribute.Name, CreditCardNoTextName);
241 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
242 writer.RenderBeginTag(HtmlTextWriterTag.Input);
243 writer.RenderEndTag();
244
245 writer.RenderEndTag();
246 writer.RenderEndTag();
247 //**************************************************************************************
248
249 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
250 writer.RenderBeginTag(HtmlTextWriterTag.Td);
251 writer.Write(CardholderName);
252 writer.RenderEndTag();
253
254 writer.RenderBeginTag(HtmlTextWriterTag.Td);
255 writer.AddAttribute(HtmlTextWriterAttribute.Name, CardholderNameTextName);
256 writer.AddAttribute(HtmlTextWriterAttribute.Id, CardholderNameTextId);
257 writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
258 writer.RenderBeginTag(HtmlTextWriterTag.Input);
259 writer.RenderEndTag();
260
261 writer.RenderEndTag();
262 writer.RenderEndTag();
263 //***************************************************************************************
264
265 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
266 writer.RenderBeginTag(HtmlTextWriterTag.Td);
267 writer.Write(ExpirationDate);
268 writer.RenderEndTag();
269
270 writer.RenderBeginTag(HtmlTextWriterTag.Td);
271 writer.AddAttribute(HtmlTextWriterAttribute.Name, MonthListName);
272 writer.AddAttribute(HtmlTextWriterAttribute.Id, MonthListId);
273 writer.RenderBeginTag(HtmlTextWriterTag.Select);
274
275 for (int month = 1; month < 13; month++)
276 {
277 writer.AddAttribute(HtmlTextWriterAttribute.Value, month.ToString());
278 writer.RenderBeginTag(HtmlTextWriterTag.Option);
279 writer.Write(month.ToString());
280 writer.RenderEndTag();
281 }
282 writer.RenderEndTag();
283
284 /////////////////////////////////////
285
286 writer.Write(" ");
287
288 /////////////////////////////////////
289 writer.AddAttribute(HtmlTextWriterAttribute.Name, YearListName);
290 writer.AddAttribute(HtmlTextWriterAttribute.Id, YearListId);
291 writer.RenderBeginTag(HtmlTextWriterTag.Select);
292
293 for (int year = 2008; year < 2015; year++)
294 {
295 writer.AddAttribute(HtmlTextWriterAttribute.Value, year.ToString());
296 writer.RenderBeginTag(HtmlTextWriterTag.Option);
297 writer.Write(year.ToString());
298 writer.RenderEndTag();
299 }
300 writer.RenderEndTag();
301
302 writer.RenderEndTag();
303 writer.RenderEndTag();
304 //*****************************************************************************
305
306 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
307 writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
308 writer.AddAttribute(HtmlTextWriterAttribute.Align, "center");
309 writer.RenderBeginTag(HtmlTextWriterTag.Td);
310 writer.AddAttribute(HtmlTextWriterAttribute.Name, SubmitButtonName);
311 writer.AddAttribute(HtmlTextWriterAttribute.Value, SubmitButtonText);
312 writer.AddAttribute(HtmlTextWriterAttribute.Id, SubmitButtonId);
313 writer.AddAttribute(HtmlTextWriterAttribute.Type, "submit");
314 writer.RenderBeginTag(HtmlTextWriterTag.Input);
315 writer.RenderEndTag();
316
317 writer.RenderEndTag();
318 writer.RenderEndTag();
319
320 //******************************************************************************
321
322
323 }
324
325 }
326 }
327
希望大家繼續支持啊!謝謝!