2012年7月10日 星期二

GridView 批次刪除功能(複選多個資料列)_1

這個範例主要是在介紹「批次刪除功能」,用GridView快速建置資料列並加以手動修改樣版,使用者按下「全選」按鈕來選擇GridView下所有的資料列,或是透過每列資料列前的CheckBox來「複選」多個資料列,按下「刪除」按鈕把所選取的資料列刪除。

◎以上程式範例AspNet42.aspx,如在頁框下不能操作,請開新視窗操作
◎如果有問題歡迎您提出,dnowba很需要有人和我一起討論

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Me.Button2.Visible = False
        End If
    End Sub

    Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
        For i As Integer = 0 To Me.GridView1.Rows.Count - 1
            CType(Me.GridView1.Rows(i).FindControl("CheckBox1"), CheckBox).Checked = True
        Next

        Me.Button1.Visible = False
        Me.Button2.Visible = True
    End Sub

    Protected Sub Button2_Click(sender As Object, e As System.EventArgs) Handles Button2.Click
        For i As Integer = 0 To Me.GridView1.Rows.Count - 1
            CType(Me.GridView1.Rows(i).FindControl("CheckBox1"), CheckBox).Checked = False
        Next

        Me.Button2.Visible = False
        Me.Button1.Visible = True
    End Sub

    Protected Sub Button3_Click(sender As Object, e As System.EventArgs) Handles Button3.Click
        Me.Label1.Text = Nothing

        For i As Integer = 0 To Me.GridView1.Rows.Count - 1
            Dim myCheckbox As CheckBox = Me.GridView1.Rows(i).FindControl("CheckBox1")
            Dim mySelect As Label = Me.GridView1.Rows(i).FindControl("Label1")
            If myCheckbox.Checked = True Then
                Me.Label1.Text &= "[" & mySelect.Text & "]   "
            End If
        Next

        '從上面的 For...Next迴圈可以得到二個結果
        '一種是使用者有選取資料列   →Label1 會產生連接的字串
        '一種是使用者沒有選取資料列 →Label1 沒有字串
        '所以底下用Label1有沒有值來當作判別的條件,而不是以資料列有沒有選取
        If Me.Label1.Text <> Nothing Then
            Me.Label1.Text = "你已經刪除了" & Me.Label1.Text
        Else
            Me.Label1.Text = "你沒有選取任何刪除項目"
        End If

    End Sub

程式碼如上,使用者執行範例的時候可以發現並沒有真正的刪除資料(從程式碼也可以看出來,沒有觸發事件是和ADO.NET有關),一來是因為這篇主要是要討論「樣式、外觀」上的做法,一來是因為我不可能真的開這個權限讓各位使用者真正刪除資料(如果真開的話,沒多久這個範例就沒有資料列了吧」

這篇討論的主題是外觀的設定,所以主要也是討論和外觀有關係的程式碼


外觀的參考來源:

因為是介紹「批次執行」功能,所以我就找了自已常看到的相關應用網站做參考,遠在天邊近在眼前的就是Google部落格 blogger 裡文章管理的頁面,如下圖。

我想這種功能應該是很常見,不過我向來很偏愛google設計應用網站時的簡潔有力。那些程式高手真的是沒話說,不在表面上班門弄斧…不把畫面搞得太複雜,很喜歡學習。

不過層次不同就是不同,在參考時受足了苦頭…要用比較低階的程式能力來詮釋高階的語法… 只能說這篇文章是「既下不了廚房,更出不了廳堂」,整個就是在「偷吃步」,不過「偷吃步」的過程自已覺得還蠻有趣的,就也介紹給大家。image


在GridView的每個資料列前加入CheckBox控制項,實現複選功能

畫面上新增一個GridView,並做好資料繫結DataBind。只要使用簡單的select陳述式就可以了(若是要實現刪除功能的話,請別忘了PK主索引鍵的那個欄位要選到)
怎麼完成的細節不多說,需要學習的話,請參考
ADO.NET 與ASP.NET 的溝通橋梁:資料繫結控制項image

重點在這裡,我們要在GridView資料繫結完成後,在控制項上編輯欄位
在欄位上加上一個TemplateField,放到最前面一欄。這個TemplateField是一個空白的資料欄位,可以讓我們放置控制項。
image

在畫面上我們就可以切換到GridView的樣板編輯模式(在GridView上選擇智慧標籤裡的編輯樣板),透過下拉式視窗選擇顯示「Column[0]」,Column[0]的意思就是第一欄 (電腦是從0開始算起,例如第三欄就是Column[2]…),因為所有欄位只有一欄是Template模式,其他欄位都還是預設的table,所以顯示上面也只有第一欄提供五種模式的樣式編輯。
image

在ItemTemplate上加上CheckBox控制項。
image

切換到一般檢視畫面(結束樣板編輯) ,GridView的每一個資料列前就會有CheckBox,這些CheckBox就可以讓我們實現複選的功能。
image


設計「全選/取消全選」功能 和 「刪除」功能 的樣式
(偷吃步的精華,請細細品味)

在參考了blogger文章管理網頁的外觀後,我很心儀他那個按鈕上面不是用文字顯示,而是用圖案,這看起來平凡的東西,在我這種低偕的程式設計者來說,就是很難,因為在ASP.NET裡使用既有的控制項,按鈕加圖片,很直覺的就是用ImageButton這個控制項…

好了,就決定是你了…ImageButton
當務之急是找圖,我偏愛google按鈕的簡約風,那就找找看吧,怎麼找?
心生一計,直接在blogger文章管理網頁上點選右鍵,選擇檢查元素。
image

展開了這個網頁的HTML碼,游標隨意遊走,總算給我找到了這個刪除按鈕的標籤(下圖反白處)…標記上是有一個image,<image>裡也定義了src屬性,這src就是圖檔位置啦,點他一下。不過怎麼人家用的是<button>不是<ImageButton>?Button可以不寫文字放圖片的嗎?很懷疑但先不管啦。
image

畫面會由Elements跳到Resources,就是這個網頁的所有文件資源,找一也順利了拿到了圖。
image

接下來勾選的按鈕圖案也是這樣找…
不過…怎麼這個標記寫的是input type=”checkbox”,哇哩,checkbox可以長得像按鈕嗎?
唉~很肯定的是,這是google自已設計的控制項…果真點一下按鈕,按鈕的圖就變勾選,再按一下就沒有勾勾了…太神奇了。

image 找圖的結果就是…他是三張圖組成的…名字是我自已取的,check0是取消選取的圖,check1是全選的圖案,這二張我想我還有能力實現…但是checkhover這個「滑鼠經過按鈕」時的圖是怎樣…有點招架不住了。
(收穫也不少,從截圖可以看到我把網頁上能用的小圖示都抓下來了)
image

什麼?怎麼你的瀏覽器沒有上面的的功能?我用的不是IE,是用Chrome,自從Chrome 的這個功能健全後,我很常偷偷看別人的前台程式碼。研究CSS之類的…很棒的附加功能。

先不管了,在疑點重重之下,先用ImageButton,把圖片套套看感覺如何。結果如下…慘不忍睹…圖片自動填滿整個按鈕。和blooger的按鈕比起來感覺也太差了…人家的按鈕是放在按鈕的中間捏…(這個時候心裡又反應了一下,把圖放在網頁的中間…這好像是用CSS 玩background 時center 之類的設置…
image

因此…這就是按鈕改為圖片顯示的契機啦…
我這個步驟就是用CSS的方式偷吃步…讓Button上面也能顯示Image。注意下圖的屬性外觀,Button控制項的外觀屬性中,裡頭並沒有image之類的屬性,為了要能放圖片,我是用了CssClass來設定的。
image

這是樣式設計的最後一步了,我們在此範例的HTML碼上(寫的位置是在<head>裡),加入style樣式表,分別代表刪除、全選、取消選取的圖案。寫完以後就可以在Button上套用CssClass了。

<head runat="server">
    <title></title>

<style type="text/css"> 
.aDeleteButton
{ 
background:url(images/delete.png) no-repeat center;
}
.aCheck0
{ 
background:url(images/check0.png) no-repeat center;
}
.aCheck1
{ 
background:url(images/check1.png) no-repeat center;
}
</style>
</head>

至於人家blogger是用一顆Button來同時實現全選/全不選,我這邊是放二顆按鈕把這二種功能分開來,當然我也可以只靠一顆按鈕搞定…比方說用點session的小手段紀錄,Button按一下session值就變1,再按一下,如果是1就變回0,如果是0就變回1,然後用0或1來判別要讀哪個style,這個做法用說的好像有點抽象,有機會再示範= =,我想反正都是小手段,我這個用二個按鈕的做法,在呼叫程序的時候,寫起來應該也比較輕鬆。

至於在事件的撰寫上我就不加細說,整個範例最重要的三件應該是:
1、行21、22,Button_click事件中,我們設定按一下Button1就會把Button1自已隱藏起來(Visible=false),並顯示Button2(Visible=true),來偷天換日。
2、For Next迴圈,裡頭的判斷句在GridView、FormView這樣的大型控制項應該是一種範本了,甚至應該說,通常有繫結多個子選項的控制項,就會使用到,如果要再深入了解邏輯面,我推薦可以看一下CheckBox和CheckBoxList的使用範例
3、關於FindControl的使用方式,我目前沒有寫比較針對這個物件的範例。有小小說明一下的如ASP.NET GridView上刪除欄位資料時,出現confirm box 確認視窗


關於GridView的複選、刪除功能

很肯定的是GridView本身是沒有帶這個功能的。當然確定沒有之前是有試一下別的方式。因為以前學習過CommandField,知道GridView上是有「樞紐分析表選取模式」,例如我之前寫的GridView 的選取醒目效果,可以透過選取來達到任務。不過僅限於單選。

而如果是刪除功能的話,例如我之前寫的,ASP.NET GridView上刪除欄位資料時,出現confirm box 確認視窗,也是僅限於單項來和資料庫聯繫。

所以要能「批次」「一次多選」「複選」的功能就要自已想辦法。

在使用編輯欄位間,也無意間發現有個叫做CheckBoxField的可添加欄位,不過和BoundField放在一起,自已又實作過HyperLinkField,其實大概就知道這是要資料庫的資料欄位繫結的玩意兒 (唉~ASP.NET讓我不用寫程式,但是感覺中毒愈來愈深,一直想靠裡面的控制項存活)…這個CheckBoxField讓我想到了另一種的應用方式,和這篇「批次刪除」是差不多的。
image

補充一下,我們這個範例裡添加的CheckBox不隨資料庫起舞,也完全沒有PostBack互動,就和一般的Input(Checkbox)是一樣的,只負責一件事,就是檢查使用者選了還是沒選。


關於樣板(樣版)和樣式


樣板是一組 HTML 項目和控制項,可以組成控制項特定部分的配置,像GridView上,我們就可以透過樣板編輯模式,分別設計二個模板
◎PagerTemplate:換頁的顯示外觀
◎EmptyDataTemplate:當撈取不到資料時的顯示外觀
這是在GridView以table生成資料列時所能控制的外觀
如果某一欄轉成Template就能設定該欄的其他外觀

以本範例的例子,GridView後的HTML原始碼,就可以看得出來(如下),行6-行25就是與樣板相關的程式碼,分別定義不同的外觀。

        <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
            AutoGenerateColumns="False" BackColor="White" BorderColor="#CCCCCC" 
            BorderStyle="None" BorderWidth="1px" CellPadding="4" DataKeyNames="id" 
            DataSourceID="SqlDataSource1" ForeColor="Black" GridLines="Horizontal" 
            PageSize="5">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="CheckBox1" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="id" HeaderText="id" InsertVisible="False" 
                    ReadOnly="True" SortExpression="id" />
                <asp:BoundField DataField="test_time" HeaderText="test_time" 
                    SortExpression="test_time" />
                <asp:BoundField DataField="class" HeaderText="class" SortExpression="class" />
                <asp:TemplateField HeaderText="title" SortExpression="title">
                    <EditItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("title") %>'></asp:TextBox>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Bind("title") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <FooterStyle BackColor="#CCCC99" ForeColor="Black" />
            <HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
            <SelectedRowStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" />
            <SortedAscendingCellStyle BackColor="#F7F7F7" />
            <SortedAscendingHeaderStyle BackColor="#4B4B4B" />
            <SortedDescendingCellStyle BackColor="#E5E5E5" />
            <SortedDescendingHeaderStyle BackColor="#242121" />
        </asp:GridView>

在ASP.NET裡,不同的控制項支援不同的樣板 (不是所有控制項都有,大型的如GridView、DetailsView、FormView等等才會有),控制項支援哪幾種樣板的說明在MSDN裡很詳盡:
http://msdn.microsoft.com/zh-tw/library/h59db326(v=vs.100).aspx

樣式和控制項沒有什麼關聯,就是 CSS 的設定,只要找得到標籤,就能設定該標記的的外觀。例如本範例中的行,就是透過樣式設計按鈕的外觀。

2 則留言:

Related Posts Plugin for WordPress, Blogger...
// Dnow Function