Skip to content

8. Додаток [SimuPaie] – версія 4 – ASP.NET / багатовидовий / односторінковий


Рекомендовані матеріали: довідник [1], Розробка WEB з ASP.NET 1.1, розділи:

  • Серверні компоненти та контролер додатків

  • Приклади додатків MVC із серверними компонентами ASP


Зараз ми розглядаємо похідну версію трирівневого додатка ASP.NET, який ми вивчали раніше, з доданими новими функціональними можливостями. Архітектура нашого додатка змінюється наступним чином:

Обробка запиту клієнта відбувається за такими етапами:

  1. клієнт надсилає запит до додатка.
  2. додаток обробляє цей запит. Для цього їй може знадобитися допомога шару [métier], якому, у свою чергу, може знадобитися шар [dao], якщо необхідно обмінятися даними з базою даних. Додаток отримує відповідь від шару [métier].
  3. Згідно з нею, воно вибирає (3) представлення (= відповідь), яке слід надіслати клієнту, надаючи йому (4) необхідну інформацію (шаблон).
  4. Відповідь надсилається клієнту (5)

Тут ми маємо веб-архітектуру, відому як MVC (Модель – Представлення – Контролер):

  • [Application] — це контролер. Він обробляє всі запити клієнта.
  • [Saisies, Simulation, Simulations, ...] — це представлення. Представлення у форматі .NET — це стандартний код ASP / HTML, що містить компоненти, які потрібно ініціалізувати. Значення, які потрібно надати цим компонентам, утворюють модель подання.

Тут ми реалізуємо шаблон проектування (design pattern) MVC наступним чином:

  • представленнями будуть компоненти [View] у межах єдиної сторінки [Default.aspx]
  • контролер — це код [Default.aspx.cs] цієї єдиної сторінки.

Лише базові додатки можуть підтримувати цю реалізацію MVC. Адже при кожному запиті інстанціюються всі компоненти сторінки [Default.aspx], а отже, і всі види. Під час відправлення відповіді код управління додатком обирає один із них, просто роблячи видимим відповідний компонент [View] та приховуючи інші. Якщо додаток має багато подання, сторінка [Default.aspx] матиме багато компонентів, і вартість їх інстанціювання може стати надто високою. Крім того, режим роботи сторінки [Design] може стати некерованим через надмірну кількість подання. Цей тип архітектури підходить для додатків з невеликою кількістю подань, які розробляє одна людина. Коли її можна застосувати, вона дозволяє дуже просто розробити архітектуру MVC. Саме це ми й розглянемо в цій новій версії.

8.1. Види додатка

Користувачеві будуть представлені такі види:

  • вікно [VueSaisies], яке відображає форму моделювання

Image

  • екран [VueSimulation], що використовується для відображення детальних результатів моделювання:

Image

  • погляд [VueSimulations], що містить перелік моделювань, виконаних клієнтом

Image

  • вигляд [VueSimulationsVides], який вказує, що у клієнта немає або більше немає моделювань:

Image

  • перегляд [VueErreurs], який вказує на одну або кілька помилок:

Image

8.2. Проєкт Visual Web Developer шару [web]

Проєкт Visual Web Developer шару [web] виглядає наступним чином:

  • у [1] міститься:
  • файл конфігурації [Web.config] додатка — ідентичний файлу попереднього додатка.
  • файл [Global.cs], який керує подіями веб-додатка, зокрема його запуском, — ідентичний файлу попереднього додатка, за винятком того, що він також керує запуском сеансу користувача.
  • форма [Default.aspx] додатка — містить різні види додатка.
  • У файлі [2] містяться посилання на проект — вони ідентичні тим, що були у попередній версії

8.3. Файл [Global.cs]

Файл [Global.cs], який керує подіями веб-додатка, ідентичний файлу попереднього додатка, за винятком того, що він додатково керує запуском сеансу користувача:

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
    {

        // --- статичні дані додатка ---
        public static Employe[] Employes;
        public static string Msg = string.Empty;
        public static bool Erreur = false;
        public static IPamMetier PamMetier = null;

        // запуск програми
        public void Application_Start(object sender, EventArgs e)
        {
...
        }

        // запуск сеансу користувача 
        public void Session_Start(object sender, EventArgs e)
        {
            // до сеансу додається порожній список симуляцій 
            Session["simulations"] = new List<Simulation>();
        } 

    }
}
  • рядки 27–34: тут обробляється запуск сеансу. У цей сеанс ми помістимо список симуляцій, виконаних користувачем.
  • рядок 30: створюється порожній список симуляцій. Симуляція — це об’єкт типу [Simulation], який ми детально розглянемо трохи пізніше.
  • рядок 31: список симуляцій розміщується в сесії, пов’язаній із ключем «simulations»

8.4. Клас [Simulation]

Об’єкт типу [Simulation] використовується для інкапсуляції рядка таблиці симуляцій:

Image

Його код такий:


namespace Pam.Web
{

    public class Simulation
    {
        // дані симуляції 
        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; }

        // конструктори 
        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;
            }
        }
    }
}

Поля класу відповідають стовпцям таблиці симуляцій.

8.5. Сторінка [Default.aspx]

8.5.1. Загальний огляд

Сторінка [Default.aspx] містить кілька компонентів [View], по одному для кожного виду. Її каркас має такий вигляд:


<%@ 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>
  • рядок 10: тег для розміщення розширень Ajax
  • рядки 11–73: контейнер UpdatePanel, що оновлюється за допомогою викликів Ajax
  • рядки 12–72: вміст контейнера UpdatePanel
  • рядки 13–52: заголовок, який буде присутній у кожному вигляді. Він показує користувачеві перелік можливих дій у вигляді списку посилань.
  • рядок 33: зверніть увагу на атрибут CausesValidation="False", завдяки якому валідатори сторінки не будуть виконуватися неявно при натисканні на посилання. Якщо цей атрибут відсутній, його значенням за замовчуванням є True. Перевірку сторінки можна виконати явно в коді, що виконується на стороні сервера, за допомогою операції Page.Validate.
  • рядки 53–57: компонент [MultiView] з єдиним видом [VueSaisies]. З цієї причини у рядку 53 було жорстко задано номер виду, що відображається: ActiveViewIndex="0"
  • рядки 53–67: компонент [MultiView] із чотирма видами: вид [VueSimulation] у рядках 59–61, вид [VueSimulations] у рядках 62–64, вид [VueSimulationsVides] у рядках 65–67, вид [VueErreurs] у рядках 68–70. Компонент [MultiView] відображає лише один вигляд за раз. Щоб відобразити вигляд № i компонента Vues2, слід написати такий код:
Vues2.ActiveViewIndex=i

8.5.2. Заголовок « »

Заголовок складається з таких компонентів:

Тип
Назва
Роль
1
LinkButton
LinkButtonFaireSimulation
запит на розрахунок симуляції
2
LinkButton
LinkButtonEffacerSimulation
очистити форму введення даних
3
LinkButton
LinkButtonVoirSimulations
відображає список вже виконаних моделювань
4
LinkButton
LinkButtonFormulaireSimulation
повертає до форми введення даних
5
LinkButton
LinkButtonEnregistrerSimulation
зберігає поточну симуляцію у списку симуляцій
6
LinkButton
LinkButtonTerminerSession
завершує поточну сесію

8.5.3. Вигляд [Saisies]

Компонент [View], названий [VueSaisies], має такий вигляд:

Тип
Назва
Роль
1
DropDownList
ComboBoxEmployes
Містить список імен співробітників
2
TextBox
TextBoxHeures
Кількість відпрацьованих годин — фактична кількість
3
TextBox
TextBoxJours
Кількість відпрацьованих днів – ціле число
4
RequiredFieldValidator
RequiredFieldValidatorHeures
перевіряє, чи поле [2] [TextBoxHeures] не є порожнім
5
RegularExpressionValidator
RegularExpressionValidatorHeures
перевіряє, чи поле [2] [TextBoxHeures] є дійсним числом >=0
6
RequiredFieldValidator
RequiredFieldValidatorJours
перевіряє, чи поле [3] [TextBoxJours] не є порожнім
7
RegularExpressionValidator
RegularExpressionValidatorJours
перевіряє, чи поле [3] [TextBoxJours] є цілим числом >=0

8.5.4. Поле [Simulation]

Компонент [View] з назвою [VueSimulation] має такий вигляд:

Image

Він складається виключно з компонентів [Label], серед яких ID зазначені вище.

8.5.5. Вигляд [Simulations]

Компонент [View], названий [VueSimulations], має такий вигляд:

Тип
Назва
Роль
1
GridView
GridViewSimulations
Містить список симуляцій

Властивості компонента [GridViewSimulations] визначено таким чином:

  • у [1]: клацніть правою кнопкою миші на [GridView] / опція [Mise en forme automatique]
  • на [2]: вибрати тип відображення для [GridView]
  • у [3]: вибрати властивості для [GridView]
  • в [4]: редагувати стовпці [GridView]
  • у [5]: додати стовпець типу [BoundField], який буде пов'язаний (bound) з однією з публічних властивостей об'єкта, що відображається у рядку [GridView]. Об’єкт, що відображається тут, буде об’єктом типу [Simulation].
  • у [6]: вкажіть назву стовпця
  • у [7]: вказати назву властивості класу [Simulation], яка буде пов’язана з цим стовпцем.
  • [DataFormatString] вказує, як мають бути відформатовані значення, що відображаються у стовпці.

Стовпці компонента [GridViewSimulations] мають такі властивості:

Властивості
2
Тип: BoundField, HeaderText: Ім’я, DataField: Ім’я
3
Тип: BoundField, HeaderText: Прізвище, DataField: Ім’я
4
Тип: BoundField, HeaderText: Відпрацьовані години, DataField: HeuresTravaillees
5
Тип: BoundField, HeaderText: Відпрацьовані дні, DataField: JoursTravailles
6
Тип: BoundField, HeaderText: Базова заробітна плата, DataField: SalaireBase, DataFormatString: {0:C} (валютний формат, C = валюта) — відображатиме символ євро.
7
Тип: BoundField, HeaderText: Допомога, Поле даних: Indemnites, DataFormatString: {0:C}
8
Тип: BoundField, HeaderText: Соціальні внески, DataField: CotisationsSociales, DataFormatString: {0:C}
9
Тип: BoundField, HeaderText: Чиста заробітна плата, DataField: SalaireNet, DataFormatString: {0:C}

Слід звернути увагу на те, що поле [DataField] має відповідати існуючій властивості класу [Simulation]. За підсумками цього етапу було створено всі стовпці типу [BoundField]:

  • в [1]: стовпці, створені для [GridView]
  • в [2]: автоматичне створення стовпців має бути вимкнено, коли розробник сам їх визначає, як ми щойно зробили.

Залишилося створити стовпець посилань [Retirer]:

Image

  • у [1]: додати стовпець типу [CommandField / Supprimer]
  • у [2]: ButtonType=Link, щоб у стовпці було посилання, а не кнопка
  • у [3]: CausesValidation=False — клік на посилання не призведе до виконання перевірок, які можуть бути на сторінці. Адже видалення симуляції не вимагає перевірки даних.
  • у [4]: буде видно лише посилання на видалення.
  • у [5]: текст цього посилання

8.5.6. Вигляд [SimulationsVides]

Компонент [View] із назвою [VueSimulationsVides] містить лише текст:

 

8.5.7. Вигляд [Erreurs]

Компонент [View] з назвою [VueErreurs] має такий вигляд:

Тип
Назва
Роль
1
Ретранслятор
RptErreurs
відображає список повідомлень про помилки

Компонент [Repeater] дозволяє повторювати код ASP.NET / HTML для кожного об’єкта джерела даних, зазвичай колекції. Цей код визначається безпосередньо у вихідному коді ASP.NET на сторінці:


                <asp:Repeater ID="RptErreurs" runat="server">
                    <ItemTemplate>
                        <li>
                            <%# Container.DataItem %>
                        </li>
                    </ItemTemplate>
</asp:Repeater>
  • рядок 2: <ItemTemplate> визначає код, який буде повторюватися для кожного елемента джерела даних.
  • рядок 4: відображає значення виразу Container.DataItem, який позначає поточний елемент джерела даних. Оскільки цей елемент є об’єктом, для його включення до потоку HTML на сторінці використовується метод ToString цього об’єкта. Наша колекція об’єктів буде колекцією List(Of String), що містить повідомлення про помилки. У рядках 3–5 послідовності <li>Message</li> будуть включені до потоку HTML сторінки.

8.6. Контролер [Default.aspx.cs]

8.6.1. Загальний огляд

Повернемося до архітектури MVC додатка:

  • [Default.aspx.cs] — це код управління окремою сторінкою, а [Default.aspx] — контролер додатка.
  • [Global] — це об’єкт типу [HttpApplication], який ініціалізує додаток і має посилання на рівень [métier].

Структура коду контролера [Default.aspx.cs] така:


using System.Collections.Generic;
...

public partial class PagePam : Page
{

    private void setVues(bool boolVues1, bool boolVues2, int index)
    {
        // відображаються запитувані види 
        // boolVues1: true, якщо багатовидовий перегляд «Види1» має бути видимим 
        // boolVues1: true, якщо мультивигляд «Види2» має бути видимим 
        // index: індекс виду з «Vues2», який потрібно відобразити 
...
    }

    private void setMenu(bool boolFaireSimulation, bool boolEnregistrerSimulation, bool boolEffacerSimulation, bool boolFormulaireSimulation, bool boolVoirSimulations, bool boolTerminerSession)
    {
        // встановлюються параметри меню 
        // кожен логічний параметр присвоюється властивості Visible відповідного посилання 
...
    }

    // завантаження сторінки 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // обробка початкового запиту 
        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)
    {
...
    }
}

При першому запиті (GET) користувача обробляється лише подія Load у рядках 24–31. При наступних запитах (POST), зроблених через посилання в меню, обробляються дві події:

  1. подія Load (24–31), але перевірка логічного значення Page.IsPostback (рядок 27) призводить до того, що ніяких дій не буде виконано.
  2. подія, пов’язана з посиланням, на яке натиснули:
  • рядки 33–36: обробляють клік на посилання [1]
  • рядки 38–41: обробляють клік на посилання [2]
  • рядки 43–46: обробляють клік на посилання [3]
  • рядки 58–61: обробляють клік на посилання [4]
  • рядки 48–51: обробляють клік на посилання [5]
  • рядки 53–56: обробляють клік на посилання [6]

Для виокремлення часто повторюваних фрагментів коду було створено два внутрішні методи:

  • setVues, рядки 7–14: визначає, який вигляд або які види потрібно відобразити
  • setMenu, рядки 16–21: визначає опції меню, які потрібно відобразити

8.6.2. Подія Load


Рекомендовані матеріали: довідка [1], Розробка WEB з ASP.NET 1.1:

  • розділ «Компонент [Repeater] та зв’язок даних».

Першим, що бачить користувач, є порожня форма:

Image

Для ініціалізації додатка необхідний доступ до джерела даних, який може завершитися невдачею. У цьому випадку першою сторінкою буде сторінка помилок:

Image

Подія [Load] обробляється аналогічно до попередніх версій ASP.NET:


    // завантаження сторінки 
    protected void Page_Load(object sender, System.EventArgs e)
    {
        // обробка початкового запиту 
        if (!IsPostBack)
        {
            // помилки ініціалізації? 
            if (Global.Erreur)
            {
                // відображення сторінки [erreurs] 
...
                // розміщення меню 
                ...
                return;
            }
            // завантаження імен співробітників у комбінований список 
...
            // розташування меню 
...
            // відображення виду [saisie] 
 ...
        }
}

Завдання: доповніть наведений вище код


8.6.3. Дія: Провести симуляцію

У наведеному нижче прикладі екран, позначений (1), — це запит користувача, а екран, позначений (2), — відповідь, яку йому надсилає веб-додаток. З головного екрана користувач може розпочати симуляцію:

Image

- (1): користувач подає запит на моделювання

Image

- (2): результат симуляції

Процедура, яка обробляє цю дію, може виглядати наступним чином:


    protected void LinkButtonFaireSimulation_Click(object sender, System.EventArgs e)
    {
        // розрахунок заробітної плати 
        // сторінка дійсна? 
        Page.Validate();
        if (!Page.IsValid)
        {
            // перегляд сторінки [saisie] 
            ...
            return;
        }
        // сторінка дійсна — дані, введені користувачем, збережено 
        double HeuresTravaillées = ...;
        int JoursTravaillés = ...;
        // розраховується заробітна плата працівника 
        FeuilleSalaire feuillesalaire;
        try
        {
            feuillesalaire = ...
        }
        catch (PamException ex)
        {
            // відображення подання [erreurs] 
...
            return;
        }
        // результат зберігається в сесії 
        Session["simulation"] = ...
        // виведення результатів 
...
        // відображення переглядів [saisie, employe, salaire] 
        ...
        // відображення меню 
        ...
}

Завдання: доповніть наведений вище код


8.6.4. Дія: Записати симуляцію

Після завершення симуляції користувач може подати запит на її збереження:

- (1): запит на збереження поточної симуляції

Image

- (2): симуляція збережена, і відображається список виконаних симуляцій

Процедура, що обробляє цю дію, може виглядати наступним чином:


    protected void LinkButtonEnregistrerSimulation_Click(object sender, System.EventArgs e)
    {
        // поточне моделювання зберігається у списку моделювань, наявних у сесії 
        ...
        // відображення виду [simulations] 
        ...
}

Завдання: доповніть наведений вище код


8.6.5. Дія: Повернення до форми симуляції


Рекомендовані матеріали: довідка [1], [Développement WEB avec ASP.NET 1.1 ]: роль прихованого поля _VIEWSTATE


Після відображення списку симуляцій користувач може повернутися до форми симуляції:

Слід зауважити, що на екрані (2) форма відображається саме так, як її було заповнено. Тут слід пам’ятати, що ці різні види належать до однієї й тієї ж сторінки. Між різними запитами значення компонентів зберігаються за допомогою механізму ViewState, якщо ці компоненти мають властивість від EnableViewState до true.

Процедура, яка обробляє цю дію, може виглядати наступним чином:


    protected void LinkButtonFormulaireSimulation_Click(object sender, System.EventArgs e)
    {
        // відображення виду [saisie] 
        ...
        // розташування меню 
        ...
}

Завдання: доповніть наведений вище код


8.6.6. Дія: Скинути симуляцію

Повернувшись до форми симуляції, користувач може подати запит на видалення наявних даних:

Процедура, що обробляє цю дію, може виглядати наступним чином:


    protected void LinkButtonEffacerSimulation_Click(object sender, System.EventArgs e)
    {
        // RAZ форми 
        ...
}

Завдання: доповнити наведений вище код


8.6.7. Дія: Переглянути симуляції

Користувач може переглянути симуляції, які він уже виконав:

Процедура, що обробляє цю дію, може виглядати наступним чином:


protected void LinkButtonVoirSimulations_Click(object sender, System.EventArgs e)
    {
        // отримання симуляцій у сесії
        ...
        // чи є симуляції? 
        if (...)
        {
            // вигляд [simulations] видимий 
...
        }
        else
        {
            // показ [SimulationsVides] 
            ...
        }
        // зафіксовано меню 
        ...
    }

Завдання: доповніть наведений вище код


8.6.8. Дія: Видалити симуляцію

Користувач може подати запит на видалення симуляції:

Процедура [GridViewSimulations_RowDeleting ], яка обробляє цю дію, може виглядати наступним чином:


    protected void GridViewSimulations_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        // завантажуємо симуляції в сесію
        ...
        // видаляємо вказану симуляцію (e.RowIndex — номер видаленого рядка)
        ...
        // чи залишилися ще симуляції? 
        if (...)
        {
            // заповнюється GridView 
 ...
        }
        else
        {
            // перегляд [SimulationsVides] 
            ...
        }
}

Завдання: доповніть наведений вище код


8.6.9. Дія: Завершити сесію

Користувач може подати запит на завершення своєї сесії моделювання. Це призводить до скидання вмісту сесії та відображення порожньої форми:

Процедура, що обробляє цю дію, може виглядати наступним чином:


    protected void LinkButtonTerminerSession_Click(object sender, System.EventArgs e)
    {
        // сесія завершується 
        ...
        // відобразити вікно [saisies] 
        ...
        // розташування меню 
        ...
}

Завдання: доповніть наведений вище код


Практичне завдання: реалізуйте на комп’ютері попередній веб-додаток. Додайте до нього функціонал Ajax.