Skip to content

8. A aplicação [SimuPaie] – versão 4 – ASP.NET / multi-view / página única


Leitura recomendada: referência [1], Desenvolvimento Web com ASP.NET 1.1, secções:

  • Componentes de servidor e controladores de aplicação

  • Exemplos de aplicações MVC com componentes de servidor ASP


Vamos agora examinar uma versão derivada da aplicação ASP.NET de três camadas discutida anteriormente, que adiciona novas funcionalidades. A arquitetura da nossa aplicação evolui da seguinte forma:

O processamento de um pedido do cliente decorre da seguinte forma:

  1. O cliente faz uma solicitação à aplicação.
  2. A aplicação processa esta solicitação. Para tal, pode necessitar da assistência da camada [business], que, por sua vez, pode necessitar da camada [DAO] caso seja necessário trocar dados com a base de dados. A aplicação recebe uma resposta da camada [business].
  3. Com base nessa resposta, seleciona (3) a vista (= a resposta) a enviar ao cliente, fornecendo-lhe (4) as informações (o modelo) de que necessita.
  4. A resposta é enviada ao cliente (5)

Esta é uma arquitetura web conhecida como MVC (Modelo–Visão–Controlador):

  • [Aplicação] é o controlador. Este trata de todos os pedidos do cliente.
  • [Entradas, Simulação, Simulações, ...] são as vistas. Uma vista no .NET é código ASP/HTML padrão que contém componentes que precisam de ser inicializados. Os valores que devem ser fornecidos a estes componentes formam o modelo da vista.

Aqui, vamos implementar o padrão de design MVC da seguinte forma:

  • as vistas serão componentes [View] dentro de uma única página [Default.aspx]
  • o controlador é, então, o código [Default.aspx.cs] para esta página única.

Apenas aplicações básicas podem suportar esta implementação MVC. Na verdade, a cada pedido, todos os componentes da página [Default.aspx] são instanciados, ou seja, todas as vistas. Ao enviar a resposta, uma delas é selecionada pelo código de controlo da aplicação simplesmente tornando visível o componente [View] correspondente e ocultando os outros. Se a aplicação tiver muitas vistas, a página [Default.aspx] terá muitos componentes, e o custo de os instanciar pode tornar-se proibitivo. Além disso, o modo [Design] da página pode tornar-se incontrolável devido ao excesso de vistas. Este tipo de arquitetura é adequado para aplicações com poucas vistas e desenvolvidas por uma única pessoa. Quando pode ser adotada, permite o desenvolvimento de uma arquitetura MVC de forma muito simples. É isso que iremos explorar nesta nova versão.

8.1. As vistas da aplicação

As diferentes vistas apresentadas ao utilizador serão as seguintes:

  • a vista [VueSaisies], que exibe o formulário de simulação

Image

  • a vista [VueSimulation], utilizada para apresentar os resultados detalhados da simulação:

Image

  • a vista [VueSimulations], que lista as simulações realizadas pelo cliente

Image

  • a [EmptySimulationsView], que indica que o cliente não tem simulações ou já não tem mais simulações:

Image

  • a vista [ErrorView], que indica um ou mais erros:

Image

8.2. O projeto do Visual Web Developer para a camada [web]

O projeto do Visual Web Developer para a camada [web] é o seguinte:

  • em [1] encontramos:
  • o ficheiro de configuração da aplicação [Web.config] – é idêntico ao da aplicação anterior.
  • o ficheiro [Global.cs] que gere os eventos da aplicação web, neste caso o seu arranque – é idêntico ao da aplicação anterior, exceto que também gere o arranque da sessão do utilizador.
  • o formulário [Default.aspx] da aplicação – contém as várias vistas da aplicação.
  • Em [2] encontram-se as referências do projeto – são idênticas às da versão anterior

8.3. O ficheiro [Global.cs]

O ficheiro [Global.cs], que gere os eventos da aplicação web, é idêntico ao da aplicação anterior, exceto que também gere o início da sessão do utilizador:

Global.cs


using System;
using System.Web;
using Pam.Dao.Entites;
using Pam.Metier.Service;
using Spring.Context.Support;
using System.Collections.Generic;
using istia.st.pam.web;
 
namespace pam_v4
{
    public class Global : HttpApplication
    {
 
        // --- static application data ---
        public static Employe[] Employes;
        public static string Msg = string.Empty;
        public static bool Erreur = false;
        public static IPamMetier PamMetier = null;
 
        // application startup
        public void Application_Start(object sender, EventArgs e)
        {
...
        }
 
        // start user session 
        public void Session_Start(object sender, EventArgs e)
        {
            // put an empty simulation list in the session 
            Session["simulations"] = new List<Simulation>();
        } 
 
    }
}
  • Linhas 27–34: Tratamos do início da sessão. Colocaremos a lista de simulações realizadas pelo utilizador nesta sessão.
  • linha 30: É criada uma lista vazia de simulações. Uma simulação é um objeto do tipo [Simulation], que descreveremos em detalhe em breve.
  • linha 31: a lista de simulações é colocada na sessão associada à chave «simulations»

8.4. A classe [Simulation]

Um objeto do tipo [Simulation] é utilizado para encapsular uma linha da tabela de simulações:

Image

O seu código é o seguinte:


namespace Pam.Web
{
 
    public class Simulation
    {
        // simulation data 
        public string Nom { get; set; }
        public string Prenom { get; set; }
        public double HeuresTravaillees { get; set; }
        public int JoursTravailles { get; set; }
        public double SalaireBase { get; set; }
        public double Indemnites { get; set; }
        public double CotisationsSociales { get; set; }
        public double SalaireNet { get; set; }
 
        // manufacturers 
        public Simulation()
        {
 
        }
 
        public Simulation(string nom, string prenom, double heuresTravailllees, int joursTravailles, double salaireBase, double indemnites, double cotisationsSociales, double salaireNet)
        {
            {
                this.Nom = nom;
                this.Prenom = prenom;
                this.HeuresTravaillees = heuresTravailllees;
                this.JoursTravailles = joursTravailles;
                this.SalaireBase = salaireBase;
                this.Indemnites = indemnites;
                this.CotisationsSociales = cotisationsSociales;
                this.SalaireNet = salaireNet;
            }
        }
    }
}

Os campos da classe correspondem às colunas da tabela de simulação.

8.5. A página [Default.aspx]

8.5.1. Visão geral

A página [Default.aspx] contém vários componentes [View], um para cada vista. A sua estrutura é a seguinte:


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="pam_v4.PagePam" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Simulateur de paie</title>
</head>
<body background="ressources/standard.jpg">
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
    <asp:UpdatePanel runat="server" ID="UpdatePanelPam" UpdateMode="Conditional">
        <ContentTemplate>
            <table>
                <tr>
                    <td>
                        <h2>
                            Simulateur de calcul de paie</h2>
                    </td>
                    <td>
                        <label>
                            &nbsp;&nbsp;&nbsp</label>
                        <asp:UpdateProgress ID="UpdateProgress1" runat="server">
                            <ProgressTemplate>
                                <img src="images/indicator.gif" />
                                <asp:Label ID="Label5" runat="server" BackColor="#FF8000"
                                         EnableViewState="False" Text="Calcul en cours. Patientez ....">
                                        </asp:Label>
                            </ProgressTemplate>
                        </asp:UpdateProgress>
                    </td>
                    <td>
                       <asp:LinkButton ID="LinkButtonFaireSimulation" runat="server" 
                                CausesValidation="False" OnClick="LinkButtonFaireSimulation_Click">
                                    | Faire la simulation<br /></asp:LinkButton>
                       <asp:LinkButton ID="LinkButtonEffacerSimulation" runat="server"
                                     CausesValidation="False" OnClick="LinkButtonEffacerSimulation_Click">
                                    | Effacer la simulation<br /></asp:LinkButton>
                       <asp:LinkButton ID="LinkButtonVoirSimulations" runat="server" 
                                CausesValidation="False" OnClick="LinkButtonVoirSimulations_Click">
                                    | Voir les simulations<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonFormulaireSimulation" runat="server"
                                CausesValidation="False" OnClick="LinkButtonFormulaireSimulation_Click">
                                | Retour au formulaire de simulation<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonEnregistrerSimulation" runat="server"
                                CausesValidation="False" OnClick="LinkButtonEnregistrerSimulation_Click">
                                    | Enregistrer la simulation<br /></asp:LinkButton>
                        <asp:LinkButton ID="LinkButtonTerminerSession" runat="server"
                                CausesValidation="False" OnClick="LinkButtonTerminerSession_Click">
                                    | Terminer la session<br /></asp:LinkButton>
                    </td>
            </table>
            <hr />
            <asp:MultiView ID="Vues1" ActiveViewIndex="0" runat="server">
                <asp:View ID="VueSaisies" runat="server">
...
                </asp:View>
            </asp:MultiView>
            <asp:MultiView ID="Vues2" runat="server">
                <asp:View ID="VueSimulation" runat="server">
...
                </asp:View>
                <asp:View ID="VueSimulations" runat="server">
...
                </asp:View>
                <asp:View ID="VueSimulationsVides" runat="server">
...
                </asp:View>
                <asp:View ID="VueErreurs" runat="server">
...
                </asp:View>
            </asp:MultiView>
        </ContentTemplate>
    </asp:UpdatePanel>
    </form>
</body>
</html>
  • Linha 10: a tag para ativar extensões Ajax
  • linhas 11–73: o contentor UpdatePanel atualizado por chamadas Ajax
  • linhas 12–72: o conteúdo do UpdatePanel
  • linhas 13–52: o cabeçalho que aparecerá em todas as visualizações. Apresenta ao utilizador uma lista de ações possíveis sob a forma de uma lista de links.
  • linha 33: Observe o atributo CausesValidation="False", que garante que os validadores da página não serão executados implicitamente quando o link for clicado. Quando este atributo é omitido, o seu valor padrão é True. A validação da página pode ser realizada explicitamente no código do lado do servidor utilizando a operação Page.Validate.
  • Linhas 53–57: Um componente [MultiView] com uma única vista [VueSaisies]. Por este motivo, o número da vista a apresentar foi codificado na linha 53: ActiveViewIndex="0"
  • Linhas 53–67: um componente [MultiView] com quatro vistas: a vista [VueSimulation] (linhas 59–61), a vista [VueSimulations] (linhas 62–64), a vista [VueSimulationsVides] (linhas 65–67) e a vista [VueErreurs] (linhas 68–70). Um componente [MultiView] apresenta apenas uma vista de cada vez. Para apresentar a vista #i do componente Vues2, escreva o seguinte código:
Vues2.ActiveViewIndex=i

8.5.2. O cabeçalho en

O cabeçalho é composto pelos seguintes componentes:

N.º
Tipo
Nome
Função
1
LinkButton
LinkButtonRunSimulation
solicita o cálculo da simulação
2
LinkButton
LinkButtonClearSimulation
limpa o formulário de entrada
3
LinkButton
LinkButtonViewSimulations
exibe a lista de simulações já realizadas
4
LinkButton
LinkButtonSimulationForm
retorna ao formulário de entrada
5
LinkButton
LinkButtonSaveSimulation
guarda a simulação atual na lista de simulações
6
LinkButton
LinkButtonEndSession
encerra a sessão atual

8.5.3. A vista [ Saisies]

O componente [View] denominado [VueSaisies] é o seguinte:

N.º
Tipo
Nome
Função
1
Lista suspensa
EmployeeComboBox
Contém a lista de nomes dos funcionários
2
Caixa de Texto
Caixa de TextoHoras
Número de horas trabalhadas – número real
3
Caixa de Texto
TextBoxDays
Número de dias trabalhados – inteiro
4
Validador de campo obrigatório
Validador de campo obrigatórioHoras
verifica se o campo [2] [TextBoxHours] não está vazio
5
Validador de Expressão Regular
RegularExpressionValidatorHours
verifica se o campo [2] [TextBoxHours] é um número real >=0
6
Validador de Campo Obrigatório
Validador de Campo Obrigatório para Dias
verifica se o campo [3] [TextBoxDays] não está vazio
7
Validador de Expressão Regular
RegularExpressionValidatorDays
verifica se o campo [3] [TextBoxDays] é um número inteiro >=0

8.5.4. A vista [Simula e ativada]

O componente [View] denominado [SimulationView] é o seguinte:

Image

Consiste exclusivamente em componentes [Label] cujos IDs estão listados acima.

8.5.5. A vista [Simu lations]

O componente [View] denominado [SimulationView] é o seguinte:

N.º
Tipo
Nome
Função
1
GridView
GridViewSimulações
Contém a lista de simulações

As propriedades do componente [GridViewSimulations] foram definidas da seguinte forma:

  • em [1]: clique com o botão direito do rato na opção [GridView] / [AutoFormat]
  • em [2]: escolha um tipo de exibição para o [GridView]
  • em [3]: selecione as propriedades do [GridView]
  • em [4]: edite as colunas do [GridView]
  • em [5]: adicione uma coluna [BoundField] que será vinculada a uma das propriedades públicas do objeto a ser exibido na linha do [GridView]. O objeto exibido aqui será um objeto [Simulation].
  • em [6]: introduza o título da coluna
  • em [7]: especifique o nome da propriedade da classe [Simulation] que será associada a esta coluna.
  • [DataFormatString] especifica como os valores apresentados na coluna devem ser formatados.

As colunas do componente [GridViewSimulations] têm as seguintes propriedades:

N.º
Características
2
Tipo: Campo vinculado, Texto do cabeçalho: Nome, Campo de dados: Nome
3
Tipo: Campo Vinculado, Texto do Cabeçalho: Apelido, Campo de Dados: Apelido
4
Tipo: Campo Vinculado, Texto do Cabeçalho: Horas Trabalhadas, Campo de Dados: HorasTrabalhadas
5
Tipo: Campo Vinculado, Texto do Cabeçalho: Dias Trabalhados, Campo de Dados: DiasTrabalhados
6
Tipo: Campo Vinculado, Texto do Cabeçalho: Salário Base, Campo de Dados: SalárioBase, Formato de Dados: {0:C} (formato de moeda, C=Moeda) – exibirá o símbolo do euro.
7
Tipo: Campo Vinculado, Texto do Cabeçalho: Subsídios, Campo de Dados: Indemnites, Formato de Dados: {0:C}
8
Tipo: Campo Vinculado, Texto do Cabeçalho: Contribuições para a Segurança Social, Campo de Dados: Contribuições para a Segurança Social, Formato de Dados: {0:C}
9
Tipo: Campo Vinculado, Texto do Cabeçalho: Salário Líquido, Campo de Dados: SalárioLíquido, Formato de Dados: {0:C}

Note que o [DataField] deve corresponder a uma propriedade existente da classe [Simulation]. No final desta fase, todas as colunas do tipo [BoundField] foram criadas:

  • em [1]: as colunas criadas para o [GridView]
  • em [2]: a geração automática de colunas deve ser desativada quando o programador as define manualmente, como acabámos de fazer.

Ainda precisamos de criar a coluna do link [Remover]:

Image

  • em [1]: adicione uma coluna do tipo [CommandField / Delete]
  • em [2]: ButtonType=Link para ter um link na coluna em vez de um botão
  • em [3]: CausesValidation=False; clicar no link não acionará quaisquer verificações de validação que possam estar presentes na página. De facto, a eliminação de uma simulação não requer qualquer validação de dados.
  • em [4]: apenas o link de eliminação ficará visível.
  • em [5]: o texto deste link

8.5.6. A vista [Simulation sVides]

O componente [View] denominado [VueSimulationsVides] contém simplesmente texto:

 

8.5.7. A vista [E rros]

O componente [View] denominado [VueErreurs] é o seguinte:

N.º
Tipo
Nome
Função
1
Repetidor
RptErrors
exibe uma lista de mensagens de erro

O componente [Repetidor] permite repetir código ASP.NET/HTML para cada objeto numa fonte de dados, normalmente uma coleção. Este código é definido diretamente no código-fonte ASP.NET da página:


                <asp:Repeater ID="RptErreurs" runat="server">
                    <ItemTemplate>
                        <li>
                            <%# Container.DataItem %>
                        </li>
                    </ItemTemplate>
</asp:Repeater>
  • Linha 2: <ItemTemplate> define o código que será repetido para cada item na fonte de dados.
  • Linha 4: exibe o valor da expressão Container.DataItem, que se refere ao elemento atual na fonte de dados. Uma vez que este elemento é um objeto, o método ToString desse objeto é utilizado para o incluir na saída HTML da página. A nossa coleção de objetos será uma coleção List(Of String) contendo mensagens de erro. As linhas 3–5 incluirão sequências <li>Message</li> na saída HTML da página.

8.6. O controlador [Default.aspx.cs]

8.6.1. Visão geral

Voltemos à arquitetura MVC da aplicação:

  • [Default.aspx.cs], que é o código da página única [Default.aspx], é o controlador da aplicação.
  • [Global] é o objeto [HttpApplication] que inicializa a aplicação e possui uma referência à camada [business].

A estrutura do código do controlador [Default.aspx.cs] é a seguinte:


using System.Collections.Generic;
...
 
public partial class PagePam : Page
{
 
    private void setVues(bool boolVues1, bool boolVues2, int index)
    {
        // display the requested views 
        // boolVues1 : true if Vues1 multi-view is to be visible 
        // boolVues1 : true if the Vues2 multiview is to be visible 
        // index: index of the Vues2 view to be displayed 
...
    }
 
    private void setMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
    {
        // set menu options 
        // each Boolean is assigned to the Visible property of the corresponding link 
...
    }
 
    // page loading 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // initial request processing 
        if (!IsPostBack)
        {
...
        }
    }
 
    protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
...
    }
 
    protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
    {
....
    }
 
    protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
    {
...
    }
 
    protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
...
    }
 
    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
...
    }
 
    protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
...
    }
 
 
    protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
...
    }
}

Em resposta ao pedido inicial do utilizador (GET), apenas o evento Load nas linhas 24–31 é tratado. Para pedidos subsequentes (POST) efetuados através dos links do menu, são tratados dois eventos:

  1. o evento Load (linhas 24–31), mas a verificação booleana de Page.IsPostback (linha 27) garante que nada aconteça.
  2. o evento associado ao link que foi clicado:
  • linhas 33–36: processar o clique no link [1]
  • linhas 38–41: processar o clique no link [2]
  • linhas 43-46: processar o clique no link [3]
  • linhas 58–61: processar o clique no link [4]
  • linhas 48–51: processar o clique no link [5]
  • linhas 53-56: processar o clique no link [6]

Para extrair sequências de código que se repetem frequentemente, foram criados dois métodos internos:

  • setVues, linhas 7–14: define a(s) vista(s) a exibir
  • setMenu, linhas 16–21: define as opções do menu a exibir

8.6.2. O evento Load


Leitura recomendada: Referência [1], Desenvolvimento Web com ASP.NET 1.1:

  • a secção sobre o componente [Repeater] e a ligação de dados.

A primeira vista apresentada ao utilizador é a do formulário vazio:

Image

A inicialização da aplicação requer acesso a uma fonte de dados, o que pode falhar. Neste caso, a primeira página apresentada é uma página de erro:

Image

O evento [Load] é tratado de forma semelhante às versões anteriores do ASP.NET:


    // page loading 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // initial request processing 
        if (!IsPostBack)
        {
            // initialization errors? 
            if (Global.Erreur)
            {
                // display view [errors] 
...
                // menu positioning 
                ...
                return;
            }
            // loading employee names into the combo 
...
            // menu positioning 
...
            // view display [input] 
 ...
        }
}

Pergunta: Complete o código acima


8.6.3. Ação: Executar a simulação

A seguir, o ecrã (1) representa o pedido do utilizador e o ecrã (2) representa a resposta enviada ao utilizador pela aplicação web. A partir do ecrã inicial, o utilizador pode iniciar uma simulação:

Image

- (1): O utilizador solicita uma simulação

Image

- (2): Resultado da simulação

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


    protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
        // wage calculation 
        // valid page? 
        Page.Validate();
        if (!Page.IsValid)
        {
            // view display [input] 
            ...
            return;
        }
        // the page is validated - inputs are retrieved 
        double HeuresTravaillées = ...;
        int JoursTravaillés = ...;
        // we calculate the employee's salary 
        FeuilleSalaire feuillesalaire;
        try
        {
            feuillesalaire = ...
        }
        catch (PamException ex)
        {
            // display view [errors] 
...
            return;
        }
        // put the result in the session 
        Session["simulation"] = ...
        // displaying results 
...
        // display views [entry, employee, salary] 
        ...
        // menu display 
        ...
}

Pergunta: Complete o código acima


8.6.4. Ação: Guardar a simulação

Assim que a simulação estiver concluída, o utilizador pode solicitar o seu armazenamento:

- (1): Solicitar o salvamento da simulação atual

Image

- (2): A simulação é guardada e é apresentada a lista de simulações concluídas

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


    protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
        // save the current simulation in the list of simulations in the session 
        ...
        // the [simulations] view is displayed 
        ...
}

Pergunta: Complete o código acima


8.6.5. Ação: Voltar ao formulário de simulação


Leitura recomendada: referência [1], [Desenvolvimento Web com ASP.NET 1.1]: o papel do campo oculto _VIEWSTATE


Assim que a lista de simulações for exibida, o utilizador pode solicitar o regresso ao formulário de simulação:

Note que o ecrã (2) apresenta o formulário tal como foi preenchido. É importante lembrar que estas diferentes vistas pertencem à mesma página. Entre os pedidos, os valores dos controlos são preservados pelo mecanismo ViewState, caso a propriedade EnableViewState desses controlos esteja definida como true.

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


    protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
        // view display [input] 
        ...
        // menu positioning 
        ...
}

Pergunta: Complete o código acima


8.6.6. Ação: Limpar a simulação

De volta ao formulário de simulação, o utilizador pode solicitar a limpeza das entradas atuais:

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


    protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
    {
        // RAZ of the form 
        ...
}

Pergunta: Complete o código acima


8.6.7. Ação: Ver simulações

O utilizador pode solicitar a visualização das simulações que já criou:

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
    {
        // simulations are retrieved from the
        ...
        // are there any simulations? 
        if (...)
        {
            // view [simulations] visible 
...
        }
        else
        {
            // view [SimulationsVides] 
            ...
        }
        // set the menu 
        ...
    }

Pergunta: Complete o código acima


8.6.8. Ação: Eliminar uma simulação

O utilizador pode solicitar a eliminação de uma simulação:

O procedimento [GridViewSimulations_RowDeleting] que lida com esta ação pode ter o seguinte aspeto:


    protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        // simulations are retrieved from the
        ...
        // delete the designated simulation (e.RowIndex is the number of the deleted line)
        ...
        // are there any simulations left? 
        if (...)
        {
            // fill in the GridView 
 ...
        }
        else
        {
            // view [SimulationsVides] 
            ...
        }
}

Pergunta: Complete o código acima


8.6.9. Ação: Terminar sessão

O utilizador pode solicitar o encerramento da sua sessão de simulação. Isto descarta o conteúdo da sessão e apresenta um formulário vazio:

O procedimento que lida com esta ação pode ser semelhante ao seguinte:


    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
        // quit session 
        ...
        // display [entries] view 
        ...
        // menu positioning 
        ...
}

Pergunta: Complete o código acima


Exercício prático: Implemente a aplicação web anterior no seu computador. Adicione-lhe a funcionalidade Ajax.