我要把page上的一个控件动态移动到本页面的panel上去,
我在page_load中,使用了 panel1.controls.add(dropdownlist1);
虽然移动过去了,但是dropdownlist1的内容不变了,总是他原来的静态值,我发现在这个语句运行前textbox1.text是正确的值,于是我在上下添加两句
string s=dropdownlist1.text;
panel1.controls.add(dropdownlist1);
dropdownlist1.text=s;
这样虽然可以,但是我的dropdownlist1的事件不能正确触发了。
非常非常着急,大家帮我想想办法?

解决方案 »

  1.   

    string s=dropdownlist1.text;
    panel1.controls.add(dropdownlist1);
    dropdownlist1.Autopostback=true;//加这句试试看
      

  2.   

    把控件移动到其他控件中去,相当于动态创建控件.
    所以改变他的值,每次post_back都要做.
      

  3.   

    我试了一下,没有任何问题:<asp:DropDownList ID="DropDownList1" runat="server">
        <asp:ListItem>1</asp:ListItem>
        <asp:ListItem>2</asp:ListItem>
        <asp:ListItem>3</asp:ListItem>
    </asp:DropDownList>
    <hr />
    <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px">
    </asp:Panel>
    <asp:Button ID="Button1" runat="server" Text="Button" />
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.Panel1.Controls.Add(Me.DropDownList1)
    End Sub
      

  4.   

    静态控件添加了那些事件处理
    ===========
    在页面的这个方法里找.
    private void InitializeComponent()
    {    
     
    }
      

  5.   

    <asp:DropDownList ID="DropDownList1" runat="server">
        <asp:ListItem>1</asp:ListItem>
        <asp:ListItem>2</asp:ListItem>
        <asp:ListItem>3</asp:ListItem>
    </asp:DropDownList>
    <hr />
    <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px">
    </asp:Panel>
    <asp:Button ID="Button1" runat="server" Text="Button" />
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
            Me.SmartNavigation = True
            Me.Panel1.Controls.Add(Me.DropDownList1)
        End Sub    Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
            Me.Button1.Text = Me.DropDownList1.SelectedValue
        End Sub控件移动到的新位置是对的,选择结果是对的,事件也是触发的。
      

  6.   

    to:sp1234 
    =========
    楼主在后台动态加了个dropdown的. item 然后就会出现问题.
      

  7.   

    哦,事件确实有问题!总是默认原来的值是第一个。我做了这么多动态的程序,从来没有这样Move控件过,我似乎从来没有动过这个念头,也没有注意这个现象。对我来说,“动态”就意味着清除和创建控件实例。如果你不方便在设计时将DropDownList放入Panel,那么完全可以使用ascx文件来写DropDownList并且动态产生并放入Panel。
      

  8.   

    台动态加了个dropdown的. item 会出问题,直接用也会出问题,无论我怎么点,总是第一项,选不上第二项,我的环境是2005。
      

  9.   

    动态内容应该放在ascx上动态加载。至于很多MultiView的演示程序那类,将多个Panel的Visible属性动态设置,很不好,为了显示一个区域必须创建其它所有不可见区域的控件没有必要,最多仅需要保存其数据而不需要创建控件。我不知道你为什么一定会要“挪动到选项卡上”这个做法。下面我做了一个对比:        <asp:DropDownList ID="DropDownList1" runat="server">
                <asp:ListItem>1</asp:ListItem>
                <asp:ListItem>2</asp:ListItem>
                <asp:ListItem>3</asp:ListItem>
            </asp:DropDownList>
            <hr />
            <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px">
            </asp:Panel>
            <asp:Button ID="Button1" runat="server" Text="Button" />    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Load
            Me.SmartNavigation = True
            'Me.Panel1.Controls.Add(Me.DropDownList1) '这行让整个页面其它地方的逻辑也乱了
            Dim Test As New DropDownList
            Test.ID = "test"
            Me.Form.Controls.Add(Test)
            If Not IsPostBack Then
                With Test.Items
                    .Add("1")
                    .Add("2")
                    .Add("3")
                End With
            End If
            AddHandler Test.SelectedIndexChanged, _
              AddressOf DropDownList1_SelectedIndexChanged
            'Me.Panel1.Controls.Add(Test)  '这行影响Test的处理逻辑
        End Sub    Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
            Dim d As DropDownList = sender
            Me.Button1.Text = d.ID + " " + d.SelectedValue
        End Sub可见,那些写在设计器上“静态产生”的DropDownList如果 Move,不但自己乱了,别的地方的控件也乱了。动态产生的DropDownlist如果Move,只有自己乱了。但不管怎样,反正Value和事件都是乱了。
      

  10.   

    非常感谢sp1234,你说的对,但是我要的是这个功能,
    把一些程序员写的静态界面,变成能够支持用户自定义的动态界面。我要用动态元素替换静态元素而又要保留原静态元素的事件处理程序。我实现的动态,要以静态为前提,也就是说开发人员在原有的静态界面
    上添加了我的组件,就自动变为动态界面了,这个在cs上实现很容易的,
    不知道为什么webform这么吃力。不移动他们的控件也可以,但是我动态
    生成的控件怎么能  添加他们原来为静态控件编写的事件处理程序呢?
      

  11.   

    反过来思考也可以,我有一个全动态界面,上面的任何元素都是最终用户可自定义的,这个好实现,但问题是我怎么让开发人员面对这个白板编程呢? 我希望能够实现静态编程,动态调用。也就是说开发人员面对一个具体的form编码,我运行时用一个动态的form代替它。这下明白没有?
      

  12.   

    我所知道的任何动态东西都是动态加载的控件,包括用户控件。在web上我从来没有考虑多动态就是将静态移动到某个区域。每一个程序员,自己开发自己的ascx,互相不干扰,他们并不在一个aspx上去开发静态的东西。下面我还是把上面的功能举个代码例子:首先定义一个动态加载区域的用户控件的通用接口,这样隐藏内部的实现细节(外部不用知道内部的控件等),在文件Dynamic.vb中定义类型如下:Public MustInherit Class Dynamic
        Inherits UserControl    Public MustOverride Property SelectedValue() As String    Public Event Hi()    Protected Sub onHi()
            RaiseEvent Hi()
        End Sub
    End Class
    然后,某一个程序员开发一个动态加载的含DropdownList的组件,在文件WebUserControl.ascx中设计,前后台代码如下:<%@ Control Language="VB" AutoEventWireup="false" CodeFile="WebUserControl.ascx.vb"
        Inherits="WebUserControl" %>
    <asp:DropDownList ID="DropDownList1" runat="server">
        <asp:ListItem>1</asp:ListItem>
        <asp:ListItem>2</asp:ListItem>
        <asp:ListItem>3</asp:ListItem>
    </asp:DropDownList>
    Partial Class WebUserControl
        Inherits Dynamic    Public Overrides Property SelectedValue() As String
            Get
                Me.EnsureChildControls()
                Return Me.DropDownList1.SelectedValue
            End Get
            Set(ByVal value As String)
                Me.EnsureChildControls()
                Me.DropDownList1.SelectedValue = value
            End Set
        End Property    Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
            Me.onHi()
        End Sub
    End Class
    主页面的前后台代码是(前台代码省略了<Form>及其以外的部分):
       <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px">
       </asp:Panel>
       <asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="True" Text="装入控件" />
       <asp:Button ID="Button1" runat="server" Text="Button" />Partial Class _Default
        Inherits System.Web.UI.Page    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Load
            Me.SmartNavigation = True
            abc()
        End Sub    Protected Sub Dynamic_SelectedIndexChanged()
            Me.Button1.Text = dyna.SelectedValue
        End Sub    Private dyna As Dynamic    Private Sub abc()
            Dim C As Control = Me.Panel1.FindControl("test")
            If C IsNot Nothing Then Me.Panel1.Controls.Remove(C)
            If Me.CheckBox1.Checked Then
                dyna = Me.LoadControl("WebUserControl.ascx")
                dyna.ID = "test"
                Me.Panel1.Controls.Add(dyna)
                AddHandler dyna.Hi, AddressOf Dynamic_SelectedIndexChanged
            End If
        End Sub    Protected Sub CheckBox1_CheckedChanged(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
            abc()
        End Sub
    End Class这里用一个CheckBox控制动态装入用户控件,并且在用另外一个按钮刻意刷新主页面的时候保持用户控件(如果装入的话)的状态和事件。
      

  13.   

    这个例子仅仅是用一个CheckBox来选择是否增加用户控件,因为仅有一个已知的用户控件。实际程序当中,通常是用ViewState来记录到底在显示哪一个用户控件(的路径),稍微改几行代码。所增加的用户控件,往往是从数据库中拿来的,也就是说只要在数据库中增加一条记录、再把ascx上传到网站上,程序就自动知道有新的选项程序可以加入了。可见我所重复的那个意思的意义:动态内容是程序员分开独立写的,不是把他们集中在一个页面上去写。在你定义好接口之后(例如这里的类 Dynamic),每个程序员各自开发自己的ascx。你开发主控制程序的时候,根本不用预先知道都有哪些ascx,完全可以从数据库、配置文件等里边读取控件数据然后动态加载。
      

  14.   

    你描述的情景和我关心的不同,你实现的是插件模式,你的各个axcx是独立的,没有管理者,我要的form是个管理者,在这个form里面要写大量的相关组件的级联操作,比如函数关系,改变底色,互相验证 级联的下拉列表等等。而这些组件的布局又是由最终用户决定的。所以才有这样的需求。如果仅仅是加载和布局,当然没有必要提供一个静态环境了。我提供的静态环境是给一个程序员去写静态程序的,也不是很多个程序员共同写。
      

  15.   

    你钻到概念牛角尖里去了。什么叫做你提供的“静态环境”,这个环境对于别人是静态ascx开发,对于你是动态的 LoadControl方法使用。这“动静”态本来就是灵活的概念。“插件模式”?你是以抠字眼的方式理解设计的。因为你说作的是一个选项卡,所以我才实现为动态装载的控件。如果你的前提条件是“我不要动态产生控件”,那么你就看不到任何动态产生控件的程序。移动控件位置,不是正常的asp.net控件开发思路,我没有在任何一个asp.net集成控件或者成熟项目上见过。很显然,asp.net页面很多过程都要遵循控件树的结构递归处理数据,例如整理所有控件的ClientID,收集ViewState等。
      

  16.   

    sp1234,所谓插件模式是指,插件内部和外部没有任何关系,只有容器的父子关系,你所指出的ascx就是这种模式,但我要的是几个ascx之间互相操作的管理。虽然你也很累,但拜托你看懂我的题目,你提供的ascx的静态变成是局部的,我要的是整体的。你提供的是动态“显示”静态控件或组件,我要实现的是 动态“管理”静态模型。不是一个概念。移动控件位置,不是正常的asp.net控件开发思路,我没有在任何一个asp.net集成控件或者成熟项目上见过。是否可以理解为不能实现呢?如果真的不能实现,我就想别的办法了。我发现给控件添加服务器事件后就会出问题,否则没有错误,如果是这样我可以不用任何服务器事件,只用客户端事件。
      

  17.   

    即使是MasterPage,它最终也是被打破然后抽去其中内容控件作为页面的用户控件动态插入页面的。你让程序员把控件设计在页面上,就能避免装载了吗?所有控件都要在页面实例化之后装载,只不过写在设计器上由页面自己产生的代码装载,动态部分由自己写的LoadControl代码装载,没有多大的区别。你使用的Move控件方法,是会破坏页面上自己以及其它控件状态的。你会不断地有处理不完的异常情况,而且页面越开发,异常越是没完没了地出现。
      

  18.   

    “插件内部和外部没有任何关系,只有容器的父子关系”你实际上太小看插件了。你看我的例子,难道没有看到 Dynamic 作为协议吗?控制协议是组件之间关系的核心,插件以这个基本的道理为基础,而不是仅仅知道父子关系就能用的起来。本来这个例子既有插件的例子,也有控件之间的控制协议的例子,前者肯定会以后者为基础嘛。我觉得你在这两个方面闪烁其词。本来你是不知道动态的东西如何加载,你只能让想到先让页面加载了控件然后你再移动到目标位置。可是你极力否认自己的问题出在装载组件方面,极力归结为别人没有给你一个控制控件的方法。这就好像是别人给你做了一顿饭,你却说“我现在肚子饿害怕饿死了,可是你却给我做了一顿饭,这与我担心的不同”。
      

  19.   

    你提供的ascx的静态变成是局部的,我要的是整体的。你提供的是动态“显示”静态控件或组件,我要实现的是 动态“管理”静态模型。不是一个概念。
    ——————————————————————————————————————————
    局部还是整体,显示还是管理,这些都是很虚的词。关键是看你的细节是如何做的。我说出了任何区域都可以使用数据库、配置文件动态改变,而开发这个主程序的时候、这个工厂的建造完全可以在工厂里生产产品之前,这是我所认为的整体、管理的概念。另外,我说出你的思路其实不过让页面在装载的时候把所有控件都装载,然后你再移动它们的位置、设置它们的Visible之类的。这在c/s上也是极其不必要的做法。在web上,每一次服务器处理页面实例都要“重建”页面,而不是像c/s那样仅仅在最初建立一次。在web上有很多依赖控件树的机制,例如如果你没有给一个动态控件设置准确的ID,如果下次装载的最初时刻它的相对位置与上次输出之前最后时刻相比改变了,它就不会被asp.net认识到了,状态、事件等也就乱了。我以这个帖子用个简单的例子完整说明用户控件的设计方法,首当其冲是要说明Dynamic作为接口协议的作用,说明方法、属性、事件在接口与用户控件的定义和重写方法,以便将客户/服务双方分清职责。如果你不打算在项目中把成熟的应用程序总结为自己的控件,希望把这个例子也能让别人看到,相信这会对很多人有益。
      

  20.   

    看过!www.softit.com.cn中国软件网最大的软件资讯平台!
      

  21.   

    sp1234 不要枉下结论 说 我看不懂你的代码,这是我三年前的做法。 Dynamic 作为协议 也没有用,虽然我当年也这么用,但是仍然只是一个增强型的插件。你对我的结构还没有认识。我早就在cs下使用新的模式了:
    我的东西是一个不可见的组件,只要你把它放到窗体上。我就能把你原来的静态程序转换为动态程序,动态添加删除移动控件,动态数据库绑定,在这些动态的同时还能保持原来静态窗口中的代码可以使用。比如我的窗体是客户档案,客户的各个字段之间彼此有复杂的关系,这些关系是通过本窗口内的静态编码实现的,而我增加的动态机制是为他增加了最重用户自定义的功能,我根本不用知道他要实现什么,也不必告诉他们有什么接口,也不必管理他们。
      

  22.   

    如果你有时间 帮我看看下面的问题也可以,两个问题解决一个 我的方案就完整了。
    http://community.csdn.net/Expert/topic/5240/5240699.xml?temp=.1409418
      

  23.   

    再说清楚一点吧,我要实现的是界面和控制的完全分离。比如我动态生成了一个客户卡片窗体(窗体后面没有任何代码)。
    开发人员以前手写了一个静态的客户卡片窗体。现在我要让我的动态窗体挂到原来的静态窗体上去。(按照控件名称对应就可以)。
    我要毁掉原来静态窗口的界面,但是保留其控制功能。有必要告诉大家,这个在cs下已经实现了两年了。
    在bs模式下也可以实现,只不过我现在的模型不是可视化的,可视化了就有刚才提到的“移动”以后出错的问题。
      

  24.   

    唉,其实你应该首先清楚一个道理:既然你在这里也说了你只懂cs不懂bs,就不要轻易把“出错”硬说成是“实现”。原理都给你讲的透,关键是你自己能不能去看。
      

  25.   

    就算你已经在cs下实现一个程序有12年了,也要结合asp.net的原理去设计。这里不是cs开发的论坛,我并不想去评论你的那个cs下的用窗口来取代控件的做法怎么样。
      

  26.   

    1.C/S和B/S的事情有一个主要的差别,就是表现层的状态的持久。CS的表现层是持续运行在客户端的内存中,其状态当然在内存中持久。但BS的页面要在客户端和服务器端多次往返,所以需要ViewState等方式来持久。2.你的DropDownList当前在哪里以及选中什么就是视图的状态,而且不能好像在B/S中那样持久在客户端的内存中。为什么提交好它没有反映新的状态,这就是你要处理的问题。3.你要明白为什么你拿到了错误的状态,首先你必须承认你没有按ASP.NET设计好的模式去做,因为ASP.NET设计好的模式就是页面生命周期中一个阶段一个阶段的处理下去,特定的阶段允许操作特定的状态,不会出现读取错误版本的状态的事情。我的看法和 sp1234 的一样,你要用ASP.NET就要按照它设计好的规则去用,不喜欢的话可以换别的B/S框架,但这应该是现今为止最像C/S的框架了,只不过还是有些细节你没有注意到而已。4.你想了解这个框架的话,特别是针对你这个问题所需要解决的状态读取问题,建议你看看这篇文章:
    http://www.cnblogs.com/cathsfz/archive/2006/11/19/564929.html
      

  27.   

    当你把ddl在服务器代码中动态添加到panel中,ddl生成的js代码dopostback中的id会变成子控件形式的id,所以找不到ddl控件了。
      

  28.   

    学习中------------------------------
    经营之道 http://info.7ecity.com/
      

  29.   

    在网上搜索得到一个可行的答案 设置panel.enableviewstate=false 可以。结贴了