zoukankan      html  css  js  c++  java
  • 步步为营-83-用户控件

    使用ascx目的就是为了提高某部分功能的重复利用,和方法封装思想相似

    参考了http://blog.csdn.net/dyllove98/article/details/9152843.

    1需求:

    1.1 创建一个用户控件ascx B, 拉一个TextBox在这个控件上

    1.2 创建另一个用户控件ascx A 在这个用户控件上,拉一个Textbox 和一个按钮,是让用户在文本框输入数据,点一点铵钮,这样动态产生ascx B用户控件,呈现于ascx A用户控件的页面上。

    1.3 创建一个aspx网页。把用户控件ascxA引用至aspx网页上。再在aspx网页上拉一个按钮。让用户点一点这个铵钮,去获取动态产生的文本框的值,并显示于aspx网页上。

    2实现

    2.1 ascxB的创建(一个文本框)

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AscxB.ascx.cs" Inherits="Web.UserControl.AscxB" %>
    <asp:TextBox ID="txtB" runat="server"></asp:TextBox>

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Web.WebForm1" %>    //aspx页面

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AscxB.ascx.cs" Inherits="Web.UserControl.AscxB" %>  //ascx页面

    通过对比我们可以发现 a @标签不一样; b 继承的类不一样; c 内容不同(是否含有html代码)

    2.2 ascxA的创建(一个文本框TextBox,一个铵钮Button和一个容器PlaceHolder。在铵钮添加onclick事件OnClick="BtnGenerate_Click") 

    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AscxA.ascx.cs" Inherits="Web.UserControl.AscxA" %>
    <asp:TextBox ID="txtA" runat="server"></asp:TextBox>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <asp:Button ID="BtnGenerate" runat="server" Text="创建文本框" OnClick="BtnGenerate_Click" />
    <br />
    <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>

     2.3 为了能让AscxA动态加载到AscxB,通过接口实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.UI;
    
    namespace Web.Interface
    {
       public  interface IUserControl
        {
            UserControl GetUserControl();
        }
    }

    2.3 ascx B实现接口:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace Web.UserControls
    {
        public partial class AscxB : System.Web.UI.UserControl,Web.Interface.IUserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            public UserControl GetUserControl()
            {
                return this;
            }
        }
    }

    2.4 AscxA的后台代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web.UserControls
    
    {
        public partial class AscxA : System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            protected void BtnGenerate_Click(object sender, EventArgs e)
            {
                if (ViewState["yk"] == null)
                {
                    ViewState["yk"] = true;
                    DynamicGenerate();
                }
            }
    
            private void DynamicGenerate()
            {
                //获取文本框的值
                int j = 1;
                Int32.TryParse(this.txtA.Text.Trim(),out j);
    
                for (int i = 0; i < j; i++)
                {
                    //动态加载AscxB后,并转化为接口 -- 如果直接接受呢?
                   IUserControl uc = (IUserControl)this.LoadControl("~/AscxB.ascx");
                    //加载接口
                   this.PlaceHolder1.Controls.Add(uc.GetUserControl());
                    //加空格
                    this.PlaceHolder1.Controls.Add(new LiteralControl("&nbsp;&nbsp;"))
                      
                }
                 
            }
        }
    }

    2.5 创建一个网页.aspx,在此网页中,我们引用用户控件ascxa,还在拉一个铵钮,和个Literal控件,铵钮与Literal最开始状态是隐藏的,主要是用来获取数据与显示数据。

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestUserControl1.aspx.cs" Inherits="Web.TestUserControl1" %>
    
    <%@ Register Src="~/UserControl/AscxA.ascx" TagPrefix="uc1" TagName="AscxA" %>
    
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
    </head>
    <body>
       <uc1:AscxA runat="server" id="AscxA" />
        <br />
    
       <asp:Button ID="btnShowBContents" runat="server" Text="显示用户控件B中的值" Visible="false"/>
        <br />
        <asp:Literal ID="LiteralResult" runat="server" Visible="false"></asp:Literal>
    </body>
    </html>

    引用完控件以后,会多两行这个代码

    <%@ Register Src="~/UserControl/AscxA.ascx" TagPrefix="uc1" TagName="AscxA" %>

    用户自定义控件的相对路径,和名字

      <uc1:AscxA runat="server" id="AscxA" />

    2.6 在Ascx A用户控件,当有动态产生Ascx B控件之后,在网页的Button才会显示。如果没有产生过铵钮,网页Button就是隐藏起来。
    由于是否有控件产生是发生在ascx A用户控件,而隐藏的对象在网页上。这涉及到用户控件与网页之间的沟通与协调。
    为了减低程序的复杂度,创建一个接口,这个接口主体只有一个只写属性。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Web.Interface
    {
       public interface IShowable
        {
            bool Show { set; }
        }
    }

    2.7 接口写好了,我们在网页.aspx.cs实作这个接口。说明白一点,就是网页的铵钮只接受显示与隐藏,是谁来决定显示与隐藏,它管不了。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web
    {
        public partial class TestUserControl1 : System.Web.UI.Page,IShowable
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            protected void btnShowBContents_Click(object sender, EventArgs e)
            {
    
            }
    
            public bool Show
            {
                set { this.btnShowBContents.Visible = value; }
            }
        }
    }

    2.8 具体是谁来控制显示与隐藏呢,刚才所说,是在用户控件ascx A的动态产生ascx B之后,这个网页的Button就显示。因此,我们去用户控件ascx a的产生控件代码中添加:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web.UserControls
    
    {
        public partial class AscxA : System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                DynamicGenerate();
            }
    
            protected void BtnGenerate_Click(object sender, EventArgs e)
            {
                if (ViewState["yk"] == null)
                {
                    ViewState["yk"] = true;
                    DynamicGenerate();
                }
            }
    
            private void DynamicGenerate()
            {
                //获取文本框的值
                int j = 1;
                Int32.TryParse(this.txtA.Text.Trim(),out j);
    
                for (int i = 0; i < j; i++)
                {
                    //动态加载AscxB后,并转化为接口 -- 如果直接接受呢?
                   IUserControl uc = (IUserControl)this.LoadControl("~/AscxB.ascx");
                    //加载接口
                   this.PlaceHolder1.Controls.Add(uc.GetUserControl());
                    //加空格
                    this.PlaceHolder1.Controls.Add(new LiteralControl("&nbsp;&nbsp;"))
                      
                }
                 ((IShowable)this.Page).Show = true;
            }
        }
    }

    2.9有点疑问,怎样能把网页转为接口呢? 因为我们上面有把网页实现了IShowable这个接口。


    Ok, 我们回到网页cs,准备写铵钮click事件,来获取数据。不过获取数据起来,是有点困难,因为动态产生的控件,全是在用户控件ascx A中呈现,而且每呈现的文本框是来自ascx B。
    在网页中,怎样获取用户控件的ascx A的容器PlaceHolder呢? 还是写另外一个接口,是为了让网页.aspx.cs去读取用户控件的Ascx A的PlaceHolder。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.UI.WebControls;
    
    namespace Web.Interface
    {
       public interface IPlaceHolderable
        {
           PlaceHolder GetPlaceHolder();
        }
    }

    2.10 用户控件ascx A实用这个接口:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web.UserControls
    
    {
        public partial class AscxA : System.Web.UI.UserControl,IPlaceHolderable
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                DynamicGenerate();
            }
    
            protected void BtnGenerate_Click(object sender, EventArgs e)
            {
                if (ViewState["yk"] == null)
                {
                    ViewState["yk"] = true;
                    DynamicGenerate();
                }
            }
    
            private void DynamicGenerate()
            {
                //获取文本框的值
                int j = 1;
                Int32.TryParse(this.txtA.Text.Trim(),out j);
    
                for (int i = 0; i < j; i++)
                {
                    //动态加载AscxB后,并转化为接口 -- 如果直接接受呢?
                   IUserControl uc = (IUserControl)this.LoadControl("~/AscxB.ascx");
                    //加载接口
                   this.PlaceHolder1.Controls.Add(uc.GetUserControl());
                    //加空格
                   this.PlaceHolder1.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
                      
                }
                //设置 页面按钮显示
                 ((IShowable)this.Page).Show = true;
            }
            /// <summary>
            /// 实现接口 IPlaceHolder()
            /// </summary>
            /// <returns></returns>
            public PlaceHolder GetPlaceHolder()
            {
                return this.PlaceHolder1;
            }
        }
    }

    2.11 这样子,我们就可以在网页.aspx.cs的获取值的铵钮获取这个容器了。另外,由于容器根据用户的需求,也许不止单一次产生一个ascx B用户控件,也许会有好几个。我们怎样知道哪一个文本框TextBox是哪一个TextBox呢?
    还是写一个接口吧,

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.UI.WebControls;
    
    namespace Web.Interface
    {
       public interface ITextBoxable
        {
           TextBox GetTextBox();
        }
    }

    2.12 让用户控件AscxB来实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web.UserControls
    {
        public partial class AscxB : System.Web.UI.UserControl, Web.Interface.IUserControl,ITextBoxable
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            public UserControl GetUserControl()
            {
                return this;
            }
    
            public TextBox GetTextBox()
            {
                return this.txtB;
            }
        }
    }

    2.13 到现在为止,我们完全可以去网页代码中,去写铵钮的Click获取值的事件了:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Web.Interface;
    
    namespace Web
    {
        public partial class TestUserControl1 : System.Web.UI.Page,IShowable
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            protected void btnShowBContents_Click(object sender, EventArgs e)
            {
                //01 获取placeholder容器
                IPlaceHolderable ascxA = (IPlaceHolderable)this.AscxA;
                PlaceHolder ph = ascxA.GetPlaceHolder();
                //PlaceHolder ph = this.AscxA.GetPlaceHolder();
    
                //02 显示文本框的值
                string str = string.Empty;
    
                foreach (Control item in ph.Controls)
                {
                    if (item is ITextBoxable)
                    {
                        ITextBoxable txt = (ITextBoxable)item;
                        str += txt.GetTextBox().Text.Trim()+"<br/>";
                    }
                    if (str.Length>0)
                    {
                        this.LiteralResult.Visible = true;
                        this.LiteralResult.Text = str;
                    }
                }
            }
    
            public bool Show
            {
                set { this.btnShowBContents.Visible = value; }
            }
        }
    }

    2.4 注意 

     

  • 相关阅读:
    福大软工 · 第七次作业
    git分支重命名
    vscode左侧文件不同颜色标识含义
    正则表达式匹配指定字符区间的内容,且不包含指定字符
    git如何撤销工作区的修改
    git查看某个文件的提交历史
    扫盲篇--远程桌面连接
    git merge后如何撤销
    element-ui+vue-treeselect校验
    typeof 踩坑总结
  • 原文地址:https://www.cnblogs.com/YK2012/p/7107174.html
Copyright © 2011-2022 走看看