asp.net控件開發基礎(12) --------爲子控件添加樣式

上一篇討論了視圖狀態的用法,讓我們再回到第八篇的時候.從第八篇的時候跳了很大篇幅來繼續講屬性,然後接着講類型轉換器,再接着講視圖狀態.繞到現在才接着講複合控件的樣式的使用,因爲上面講的東西是緊密聯繫的.如果已經理解自定義視圖狀態管理,那這一篇則看起來相關的簡單.

1.複合控件中樣式屬性概述

在第六篇的時候已經介紹過樣式的使用了,在複合控件中你同樣可以用此方法給控件定義多個樣式屬性,但此方法很適合像label這樣非複合控件.

當然複合控件可以適當的定義其自身的樣式屬性,同時你還需要爲其子控件提供樣式,典型的控件如GridView控件,如下圖




它有很多不同種類的列,而每種不同的列則有不同的樣式集合屬性,如果將其每個樣式屬性均暴露爲頂級屬性,那樣式屬性將變得很混亂.

我們可以用此方法爲複合控件的子控件定義樣式,實現每個子控件對應Style類型的複雜樣式屬性,將樣式屬性暴露爲複合控件的頂級屬性,這樣更容易管理複合控件樣式屬性.

2.複合控件中樣式屬性實現(爲子控件提供樣式)

Style類本身繼承IStateManager 接口,並實現了接口方法.在第五篇我們曾重寫CreateControlStyle方法,如下


        protected override Style CreateControlStyle()
        
{

            
return new Style(ViewState);
        }


其初始化的時候即存儲樣式信息在視圖狀態中,而其自定義的樣式的狀態管理機制則跟上一篇非常的相似.你需要重寫Control類的狀態管理的幾個方法來實現樣式的狀態管理.還是以登錄控件爲例.

(1)先自定義樣式集合屬性

定義方法跟上一篇視圖狀態中的Address屬性很相似

如下代碼

   #region 樣式屬性
        [
        Category(
"Styles"),
        DefaultValue(
null),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty),
        Description(
            
"應用於按鈕的樣式")
        ]
        
public virtual Style ButtonStyle
        
{
            
get
            
{
                
if (_buttonStyle == null)
                
{
                    _buttonStyle 
= new Style();
                    
if (IsTrackingViewState)
                    
{
                        ((IStateManager)_buttonStyle).TrackViewState();
                    }

                }

                
return _buttonStyle;
            }

        }


        [
        Category(
"Styles"),
        DefaultValue(
null),
        DesignerSerializationVisibility(
            DesignerSerializationVisibility.Content),
        PersistenceMode(PersistenceMode.InnerProperty),
        Description(
            
"應用於文本框的樣式")
        ]
        
public virtual Style TextBoxStyle
        
{
            
get
            
{
                
if (_textBoxStyle == null)
                
{
                    _textBoxStyle 
= new Style();
                    
if (IsTrackingViewState)
                    
{
                        ((IStateManager)_textBoxStyle).TrackViewState();
                    }

                }

                
return _textBoxStyle;
            }

        }

        
#endregion


(2)自定義視圖狀態管理

因爲此處定義了兩個樣式集合屬性,所以用到了Triplet這個輔助類,其跟Pair類一樣都是輔助類,而其可以存儲三個相關對象的基本結構.如果你要儲存三個以上就不能用這兩個輔助類了,實現方法還是很簡單的.

如下代碼


       #region 自定義視圖狀態
        
protected override void LoadViewState(object savedState)
        
{
            
if (savedState == null)
            
{
                
base.LoadViewState(null);
                
return;
            }

            
else
            
{
                Triplet t 
= savedState as Triplet;

                
if (t != null)
                
{
                    
base.LoadViewState(t.First);

                    
if ((t.Second) != null)
                    
{
                        ((IStateManager)ButtonStyle).LoadViewState(t.Second);
                    }


                    
if ((t.Third) != null)
                    
{
                        ((IStateManager)TextBoxStyle).LoadViewState(t.Third);
                    }

                }

                
else
                
{
                    
throw new ArgumentException("Invalid view state .");
                }

            }

        }


        
protected override object SaveViewState()
        
{
            
object baseState = base.SaveViewState();
            
object buttonStyleState = null;
            
object textBoxStyleState = null;

            
if (_buttonStyle != null)
            
{
                buttonStyleState 
=
                    ((IStateManager)_buttonStyle).SaveViewState();
            }


            
if (_textBoxStyle != null)
            
{
                textBoxStyleState 
=
                    ((IStateManager)_textBoxStyle).SaveViewState();
            }


            
return new Triplet(baseState,
                buttonStyleState, textBoxStyleState);

        }


        
protected override void TrackViewState()
        
{
            
base.TrackViewState();
            
if (_buttonStyle != null)
            
{
                ((IStateManager)_buttonStyle).TrackViewState();
            }

            
if (_textBoxStyle != null)
            
{
                ((IStateManager)_textBoxStyle).TrackViewState();
            }

        }

        
#endregion


(3)爲子控件添加樣式集合屬性

上面工作做好後,然後你就可以在呈現方法Render方法或RenderContent方法中爲子控件添加樣式集合屬性,如下代碼

if (_buttonStyle != null)
            
{
                submitButton.ApplyStyle(ButtonStyle);
            }


            
if (_textBoxStyle != null)
            
{
                nameTextBox.ApplyStyle(TextBoxStyle);
                emailTextBox.ApplyStyle(TextBoxStyle);
            }


來看一下效果,屬性面板已經有子控件樣式集合屬性了,這樣就更容易管理樣式了.




定義子控件樣式就這麼的簡單,主要難點還是在於自定義視圖狀態管理,對自定義視圖狀態管理熟悉的話,看到這裏肯定很簡單,如果沒看明白就須先弄懂如何自定義視圖狀態管理.

注意點:asp.net2.0中複合控件可以直接繼承CompositeControl類即可,大家可以瞭解一下此類
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章