开发者

How to improve the design of a page with multiple case statements

My page contains: GridView1, GridView2, Button1, Button2, DropDownList1 I bind Gridviews to the table selected in dropdown like this:

Dim results as DataTable
Select Case ddl1.SelectedValue
    Case 0
        results = dtZero
    Case 1
        results = dtOne
    Case 2
        results = dtTwo
    Case 3
        results = dtThree
End Select
GridView1.DataSource = results
GridView1.DataBind()

Then I have two buttons with the following code:

Protected Sub btn1_Click(sender As Object, e As EventArgs) Handles btn2.Click
    Select Case ddl1.SelectedValue
        Case 0
            RunZero()
        Case 1
            RunOne()
        Case 2
            RunTwo()
        Case 3
            RunThree()
    End Select
End Sub

And

Protected Sub btn2_Click(sender As Object, e As EventArgs) Handles btn2.Click
    Select Case ddl1.SelectedValue
        Case 0
            RemoveZero()
        Case 1
            RemoveOne()
        Case 2
            RemoveTwo()
        Case 3
            RemoveThree()
    End Select
End Sub

For me it looks like a lot of overhead. How can I improve then design and only specify that I'm working on the following record in dropdown list without specifying the Case condition every time? Should I change my design or leave it like it is?

Update: RunZero, RunOne, RunTwo, RemoveZero, RemoveOne, RemoveTwo, RemoveThree 开发者_C百科- Execute six different stored procedures.


This was a fun one to solve. Thank you.

Sounds like you should be using actions.

First Create a class that will keep track of all your "operations" represented by your dropdownlist...

EDIT: Using Actions instead to show that you can use parameters for your functions if you want or not.

Class OpMode
    Public DropDownKey As String
    Public RunFunction As Action(Of Int32) 'This one will support a parameter'
    Public RemoveFunction As Action
    Public dt As Data.DataTable

    Sub New(DropDownKey As String, RunFunction As Action(Of Int32), RemoveFunction As Action, dt As Data.DataTable)
        Me.DropDownKey = DropDownKey
        Me.RunFunction = RunFunction
        Me.RemoveFunction = RemoveFunction
        Me.dt = dt
    End Sub
End Class

You should already have methods for running your procs.

EDIT: In this example I've allowed a parameter for the "Run" procs...

Private Sub RunOne(MyVariable As Int32)
    Response.Write("RunOne")
End Sub

Private Sub RunTwo(MyVariable As Int32)
    Response.Write("RunTwo")
End Sub

Private Sub RemoveOne()
    Response.Write("RemoveOne")
End Sub

Private Sub RemoveTwo()
    Response.Write("RemoveTwo")
End Sub

I assume you have those datatables somewhere...

Private dtOne As New Data.DataTable
Private dtTwo As New Data.DataTable

Create a readonly property to hold all your OpModes you want to use. It's light to recreate so no need to cache it.

Private ReadOnly Property OpModes As List(Of OpMode)
    Get
        Dim _OpModes As New List(Of OpMode)

        _OpModes.Add(New OpMode("1", AddressOf RunOne, AddressOf RemoveOne, dtOne))
        _OpModes.Add(New OpMode("2", AddressOf RunTwo, AddressOf RemoveTwo, dtTwo))

        Return _OpModes
    End Get
End Property

Make a function for searching through your list of opmodes for the one that matches your dropdownlist...

Private Function GetOpByDropDownKey(DropDownKey As String) As OpMode
    Return (From x In OpModes Where x.DropDownKey = DropDownKey).First
End Function

Make a click event that works for both buttons and invokes the appropriate method...

EDIT: In this example, the RunFunction has a parameter but the RemoveFunction does not.

Private Sub btn_Click(sender As Object, e As System.EventArgs) Handles btn1.Click, btn2.Click
    With GetOpByDropDownKey(dd1.SelectedValue)
        If sender Is btn1 Then
            .RunFunction(12345)
        Else
            .RemoveFunction()
        End If
    End With
End Sub

Now you can bind the correct datatable programmatically...

GridView1.DataSource = GetOpByDropDownKey(dd1.SelectedValue).dt
GridView1.DataBind()

This should be a lot easier to maintain once you get it working. You will have less places where you could have accidently forgotten to include an item in your case statement, since all that definition is defined once in your readonly property.

EDIT: (Removed note about delegates. Actions are all you need.)

I hope this helps you.


EDIT: This is suitable for VB.Net only, not ASP.Net.

A simpler way to acomplish this is to create a class with a ToString function and populate the list with that.

Class OpInfo

    Public Sub New(ByVal Text As String, ByVal DataTable As DataTableSelect, ByVal RunMethod As Action, ByVal RemoveMethod As Action)
        _Text = Text
        _DataTable = DataTable
        _RunMethod = RunMethod
        _RemoveMethod = RemoveMethod
    End Sub

    Public ReadOnly Property DataTable As DataTableSelect
        Get
            Return _DataTable
        End Get
    End Property
    Private _DataTable As DataTableSelect

    Public Sub Run()
        _RunMethod()
    End Sub
    Private _RunMethod As Action

    Public Sub Remove()
        _RemoveMethod()
    End Sub
    Private _RemoveMethod As Action

    Public Function Overrides ToString() As String
        Return _Text
    End Function
    Private _Text As String
End Class

You can populate the list with instances of this class. By type casting the selected item, you have access to all of its members.

Class Form1

    Public Sub New()
        InitializeComponents()
        ddl1.Items.Add(New OpInfo("Zero",  dtZero , AddressOf RunZero , AddressOf RemoveZero )
        ddl1.Items.Add(New OpInfo("One",   dtOne  , AddressOf RunOne  , AddressOf RemoveOne  )
        ddl1.Items.Add(New OpInfo("Two",   dtTwo  , AddressOf RunTwo  , AddressOf RemoveTwo  )
        ddl1.Items.Add(New OpInfo("Three", dtThree, AddressOf RunThree, AddressOf RemoveThree)
    End Sub

    Protected Sub ddl1_SelectedIndexChanged(sender As Object, e As EventArgs)
        If ddl1.SelectedIndex = -1 Then
            ' Code for when nothing is selected.
        Else
            GridView1.DataSource = CType(ddl1.SelectedItem, OpInfo).DataTable
            GridView1.DataBind()
        End If
    End Sub

    Protected Sub btn1_Click(sender As Object, e As EventArgs) Handles btn2.Click
        If ddl1.SelectedIndex <> -1 Then CType(ddl1.SelectedItem, OpInfo).Run
    End Sub

    Protected Sub btn2_Click(sender As Object, e As EventArgs) Handles btn2.Click
        If ddl1.SelectedIndex <> -1 Then CType(ddl1.SelectedItem, OpInfo).Remove
    End Sub
End Class
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜