Day 25 - 将 Yacht Manager 後台储存资料提取後,送至前台渲染 Yachts 版面重覆区块 - 前台 Master Page 制作 - ASP.NET Web Forms C#

=x= 🌵 Yachts 前台页面 - Yachts - Master Page 後端功能制作。


Yachts 页面资料分析介绍 :

📌 进到 Yachts 页面後会发现,点击游艇型号侧边栏画面会变动内容的包含 :

https://ithelp.ithome.com.tw/upload/images/20211009/20139487bbqi7SMgOb.jpg

  1. 红色区块 - 上方轮播图依照各型号拨放。
  2. 红色区块 - 内容区块的大小标题会变为该型号
  3. 红色区块 - 内部上方分页会因型号有无影片而决定是否出现 Video 内容分页钮
  4. 绿色区块 - 内容区块首次进入时会出现第一个型号的 Overview 内容分页,但切换内容分页後再点击不同型号,则会出现同内容分页但不同型号的对应内容;特殊情况的 Video 页面,则是如果在 Video 分页选其它型号时,选到的型号有 Video 页则会出现此型号的 Video 页,假设选到的型号没有 Video 内容,就会显示这个型号的 Overview 内容分页。

👺 从上面的拆分可以发现如果从绿色区块来看,他在切换内容分页时,不会变动的区块就是红色区块,所以红色区块我们就可以制作成 Master Page,而绿色区块则是 Content Page,但是因为区块如果点击游艇型号侧边栏则会对应改变红色跟绿色区块,因此主版页面的後置程序码需要处理这些变动的对应。



Yachts - Master Page 主版页面实作 :

1. 於前台档案资料夹右键新增 Master Page 并将原 Yachts_OverView.html 的<head><body>内的内容分别复制到 .Master 档案中。


2. 删除与 VIEWSTATE 有关的程序码。


3. 使用取代功能将 .html 都取代为 .aspx。


4. 游艇型号轮播图使用 Literal 控制项来送图片内容,细节参考如下 :

a. 紫色底线 : 用来隐藏上方轮播相簿,若要使用可参考下一步骤说明。
b. 红色区块 : 轮播相簿接收区块,使用 asp:Repeater 控制项 JavaScript 才能正确抓到。

https://ithelp.ithome.com.tw/upload/images/20211009/20139487pqRG8oLU1V.jpg


5. 将 <head> 内自动产生用来接收 <head> 内容资料的控制项移至 <head> 标签内最下方

https://ithelp.ithome.com.tw/upload/images/20211009/201394870hEp8sQ9qX.jpg

  • 🌵 如果有要使用隐藏相簿功能,jQuery 类别名称记得修正为框起的地方。


6. 左侧边栏游艇型号选单使用 asp:Literal 控制项接收资料

https://ithelp.ithome.com.tw/upload/images/20211009/20139487JsSJPGso6J.jpg


7. 内容分页选单用 asp:Literal 控制项接收资料,自动产生用来接收内容资料的控制项移至该处

https://ithelp.ithome.com.tw/upload/images/20211009/201394870ZrsVzHqgp.jpg


8. 在後置程序码 .master.cs 的 Page_Init 加入取得侧边栏游艇型号网址传值 GUID 的方法

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack) {
        //将型号对应 guid 存入 Session 与子页共用
        getGuid(); //要放在 Init 不然 Content 页会去先去抓 Session 而抓不到
    }
}
  • 👺 用除错模式可以发现换页时是先读 Content 页,再读 Master 页,所以才放在 Init。

  • 👺 执行顺序 : Content 页 Init > Master 页 Init > Content 页 Load > Master 页 Load。


9. 建立取得游艇型号对应 GUID 的 getGuid(); 方法逻辑如下

private void getGuid()
{
    //取得网址传值的型号对应 GUID
    string guidStr = Request.QueryString["id"];
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT TOP 1 guid FROM Yachts";
    SqlCommand command = new SqlCommand(sql, connection);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    if (reader.Read()) {
        //如果无网址传值就用第一笔游艇型号的 GUID
        if (String.IsNullOrEmpty(guidStr)) {
            guidStr = reader["guid"].ToString().Trim();
        }
    }
    connection.Close();
    //将 GUID 存入 Session 供上方列表共用
    Session["guid"] = guidStr;
}
  • 🌵 直接点 Yachts 页会无网址传值,直接用第一笔型号资料。

  • 🌵 点侧边栏时会更新型号网址传值 GUID。


10. 在 Page_Load 加入渲染主版画面各区块方法

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) {
        loadGallery(); //读取并渲染上方相簿轮播
        loadLeftMenu(); //读取并渲染左侧型号边栏
        loadTopMenu(); //读取并渲染型号内容上方标题及分页列
    }
}


11. 建立渲染上方相簿轮播的 loadGallery(); 方法程序逻辑如下

private void loadGallery()
{
    //建立资料表存资料
    DataTable dataTable = new DataTable();
    //新增表格栏位,预设从 1 开始, 设定栏位名称
    dataTable.Columns.AddRange(new DataColumn[1] { new DataColumn("ImageUrl") });

    //取得 Session 共用 GUID,Session 物件需转回字串
    string guidStr = Session["guid"].ToString();
    //依 GUID 取得游艇轮播图片资料
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT bannerImgPathJSON FROM Yachts WHERE guid = @guidStr";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guidStr", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    List<ImagePath> savePathList = new List<ImagePath>();
    if (reader.Read()) {
        string loadJson = HttpUtility.HtmlDecode(reader["bannerImgPathJSON"].ToString());
        savePathList = JsonConvert.DeserializeObject<List<ImagePath>>(loadJson);
        foreach (var item in savePathList) {
            //逐一填入图片路径栏位值
            dataTable.Rows.Add($"upload/Images/{item.SavePath}");
        }
    }
    connection.Close();

    //轮播图片必须用 Repeater 送不然 JavaScript 抓不到 HTML 标签会失败
    //设定用 Eval 绑定的轮播图片路径资料
    RepeaterImg.DataSource = dataTable; //设定资料来源
    RepeaterImg.DataBind(); //刷新图片资料
}

//型号轮播图片 JSON 资料
public class ImagePath
{
    public string SavePath { get; set; }
}


12. 建立渲染左侧型号边栏的 loadLeftMenu(); 方法程序逻辑如下

private void loadLeftMenu()
{
    string urlPathStr = System.IO.Path.GetFileName(Request.PhysicalPath);
    //取得游艇型号资料
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT * FROM Yachts";
    SqlCommand command = new SqlCommand(sql, connection);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    StringBuilder leftMenuHtml = new StringBuilder();
    while (reader.Read()) {
        string yachtModelStr = reader["yachtModel"].ToString();
        string isNewDesignStr = reader["isNewDesign"].ToString();
        string isNewBuildingStr = reader["isNewBuilding"].ToString();
        string guidStr = reader["guid"].ToString();
        string isNewStr = "";
        //依是否为新建或新设计加入标注
        if (isNewDesignStr.Equals("True")) {
            isNewStr = "(New Design)";
        }
        else if (isNewBuildingStr.Equals("True")) {
            isNewStr = "(New Building)";
        }
        leftMenuHtml.Append($"<li><a href='{urlPathStr}?id={guidStr}'>{yachtModelStr} {isNewStr}</a></li>");
    }
    connection.Close();

    //渲染左侧游艇型号选单
    LeftMenuHtml.Text = leftMenuHtml.ToString();
}
  • 🌵 依型号标注判断类型加入文字标示於型号後方。

  • 👺 连结位置要配合目前所在的内容分页设定,於 Video 页制作时,会建立如果跳转到没有影片连结的型号,会自动跳转成型号的 Overview 内容分页。


13. 建立渲染型号内容上方标题及分页列的 loadTopMenu(); 方法程序逻辑如下

private void loadTopMenu()
{
    //取得 Session 共用 GUID,Session 物件需转回字串
    string guidStr = Session["guid"].ToString();
    //依 GUID 取得游艇资料
    List<RowData> saveRowList = new List<RowData>();
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT * FROM Yachts WHERE guid = @guidStr";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guidStr", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    StringBuilder topMenuHtmlStr = new StringBuilder();
    StringBuilder dimensionsTableHtmlStr = new StringBuilder();
    if (reader.Read()) {
        string yachtModelStr = reader["yachtModel"].ToString();
        string contentHtmlStr = HttpUtility.HtmlDecode(reader["overviewContentHtml"].ToString());
        string loadJson = HttpUtility.HtmlDecode(reader["overviewDimensionsJSON"].ToString());
        string dimensionsImgPathStr = reader["overviewDimensionsImgPath"].ToString();
        string downloadsFilePathStr = reader["overviewDownloadsFilePath"].ToString();

        //加入渲染型号内容上方分类连结列表
        topMenuHtmlStr.Append($"<li><a class='menu_yli01' href='Yachts_OverView.aspx?id={guidStr}' >OverView</a></li>");
        topMenuHtmlStr.Append($"<li><a class='menu_yli02' href='Yachts_Layout.aspx?id={guidStr}' >Layout & deck plan</a></li>");
        topMenuHtmlStr.Append($"<li><a class='menu_yli03' href='Yachts_Specification.aspx?id={guidStr}' >Specification</a></li>");
        //加入渲染型号内容上方分类连结列表 Video 分页标签,有存影片连结网址才渲染
        saveRowList = JsonConvert.DeserializeObject<List<RowData>>(loadJson);
        if (!String.IsNullOrEmpty(saveRowList[0].SaveValue)) {
            topMenuHtmlStr.Append($"<li><a class='menu_yli04' href='Yachts_Video.aspx?id={guidStr}' >Video</a></li>");
        }

        //渲染画面
        //渲染上方小连结
        LabLink.InnerText = yachtModelStr;
        //渲染标题
        LabTitle.InnerText = yachtModelStr;
        //渲染型号内容上方分类连结列表
        TopMenuLinkHtml.Text = topMenuHtmlStr.ToString();
    }
    connection.Close();
}

//表格栏位 JSON 资料
public class RowData
{
    public string SaveItem { get; set; }
    public string SaveValue { get; set; }
}
  • 🌵 Video 分页标签记得要特别处理是否显示。


本日总结 :

📢 今天的内容可以复习如何设定主版页面,之前是在後台使用,这次是前台页面使用,这样可以大量减少重复的程序码内容,所有游艇型号内容分页共用相同逻辑的主版页面,里面侧边栏会依照目前所在内容分页而改变连结网址,是根据原始网站的模式,也可以都导回到各个型号的 Overview 页面会比较简单,但使用者操作体验较差,需要多做一次点选分页内容,才能比对不同型号的相同内容。

  • 明日将介绍制作 OverView - Content Page 後端的相关细节。

<<:  Day27Java StringⅡ

>>:  【25】ReLU 家族评比 个别使用ReLU LeakyReLU PReLU SELU 来训练

大共享时代系列_017_共享洗衣机

洗衣机,清洗着多少的脏污 旋转又旋转 时间一眨眼的就过去了... 你使用过自助洗衣或送洗服务吗? 家...

爬虫怎麽爬 从零开始的爬虫自学 DAY16 html基本介绍

前言 各位早安,书接上回我们完成了 python 基本知识的介绍,今天我们要来介绍 html 也就是...

Python 演算法 Day 2 - 理论基础 线性代数

Chap.I 理论基础 Part 1:线性代数 1. Getting Started with Eq...

【Day 09】C 的关系运算子与逻辑运算子

今天一开始,让我们先介绍一下,甚麽是关系运算子! 关系运算子 关系运算子顾名思义,就是用来比较两个变...

如何找到想要的工作?

如何找到想要的工作? 一个寻找自己的旅程 西元2020年,全世界陷入新冠疫情的笼罩。每天都有上万的人...