步步为营-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 注意

时间: 2024-07-30 20:13:53

步步为营-83-用户控件的相关文章

WPF MVVM 用户控件完成分页

项目中经常会有分页查询的情况,在WPF中我们可以通过用户控件完成分页 一下为分页控件的页面代码, <UserControl x:Class="Foundation.UCtrl.NextPageControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&qu

用户控件与页面间相互给各自的控件赋值

用户控件 ->页面 ((Label)this.Parent.Page.FindControl("AAA")).Text = "ABC"; AAA:页面控件ID Label:页面控件类型 页面 -> 用户控件 ((HiddenField)POPUSER_1.FindControl("hidNO")).Value = "VNBB"; POPUSER_1:用户控件ID HiddenField:用户控件中需要处理的控件的类

用户控件,动态创建添加用户控件

用户控件的制作步骤 1,新建一个项目,文件>新建>项目. 2,添加>新建项>用户控件.文件类型为.cs 使用用户控件 在用户控件设计业点击工具栏中的生成项,选择第一项生成解决方案,或直接点F6: 生成成功后在windows窗体的工具栏最顶端就会显示此用户控件 动态添加控件 输入一个值为n,点击按钮,动态生成n个按钮,并编号号 private void button1_Click(object sender, EventArgs e) { //先获取用户输入的是几 int count

WinForm用户控件、动态创建添加控件、timer控件--2016年12月12日

好文要顶 关注我 收藏该文 徐淳 关注 - 1 粉丝 - 3 0 0 用户控件: 通过布局将多个控件整合为一个控件,根据自己的需要进行修改,可对用户控件内的所有控件及控件属性进行修改使用 动态创建添加控件: 1 //定义控件类型 2 Button btn = new Button(); 3 //控件名称……等属性,也可以直接绑定各种事件 4 btn.Name = "mybutton" + i.ToString(); 5 //添加到窗体 this 可以替换为 容器控件 6 this.Co

无边框窗体和用户控件以及权限

无边框窗体: 就是吧窗体的边框去掉,然后自己做按钮设置功能. 无边框窗体的移动: 将下面代码直接复制粘贴,将窗体的鼠标按下事件的方法改成下面方法的名字就可以直接使用 1 //窗体移动API 2 [DllImport("user32.dll")] 3 public static extern bool ReleaseCapture(); 4 [DllImport("user32.dll")] 5 public static extern bool SendMessag

js清空web用户控件的值

假设你的用户控件里面有: <asp:DropDownList ID="DropDownList1" runat="server"> <asp:ListItem Text="111" Value="111"></asp:ListItem> </asp:DropDownList> 然后你在aspx页面中注册这个控件: <%@ Register Src="~/WebUs

用户控件(二)--常见4 种路径问题解决:

二.路径:1.问题: 添加到用户控件中的图片以及超链接 都会有固定的路径,当将用户控件用到其他页面中后,对应的页面路径需要发生变化,否则无法正常作用显示:解决: 在添加到用户控件中的 HTML 标记或者标准控件中添加:runat= server id=“id名”:这样服务端会根据使用情况自动更正图片或者超链接路径:注意: 超链接可以直接使用标准控件:Hyperlink 它里面直接带 runat=server: 2.问题?样式表中值的路径:(例)background-image:url(路径) 解

winfrom获取用户控件里的控件对象

如何获取用户控件里的控件对象呢,其实思路也是很简单的, 比如有一个panel 用户控件 里面有许多的其他控件. 那么要找出一个Label控件怎么找呢,好的.现在我们就开始 首先,一个foreach循环获得所有控件. 然后根据类型筛选出这个类型的所有控件.然后就可以用Name来判断了 foreach(var lb in mi_image1.Controls) {    if (lb is Label)    {         Label obj = lb as Label;   //如果把循环改

028.用户控件、生命周期

1.控件父类型ControlFindControl(寻找子控件)Controls 子控件集合 2.AutoPostBack 允许自动回发作用:允许控件向服务器端提交请求 3.生命周期:页面对象从创建到销毁的过程,也就是处理请求的过程.在Page_Load()中需要判断IsPostBack 4.错误处理页面级别:当前页面的错误全局:整个应用程序的错误配置文件:整个应用程序错误,不能捕获异常,只能转向. 5.用户控件(自定义的服务端控件)目的:重用界面元素及代码<%--注册用户控件,Src指向控件,

用户控件UserControl图片资源定位

MEF编程实现巧妙灵活松耦合组件化编程,一些细节需要花费不小心思去处理: 其中组件中若包含用户控件,且需要访问图片资源,那么需要做以下设置 1. 用户控件(usercontrol)所在工程目录下,创建图片目录,假设创建images文件夹,然后添加1.png图片 2. 设置1.png图片属性-->生成操作-->Resource 3. 创建一个目录Views,扔个用户控件a.xaml,拖放图片控件ImageBrush 4. 那么ImageBrush的图片资源属性应如下设置: <ImageBr