带有TemplateField的Ddynamic GridView - LifeCycle中的混淆 [英] Ddynamic GridView with TemplateFields - confusion in LifeCycle

查看:136
本文介绍了带有TemplateField的Ddynamic GridView - LifeCycle中的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态创建的databound gridview。数据源基于几个DropDownLists返回一个对象(对象类型不同)。根据对象的类型,GridView必须显示特定于特定对象的字段。另外,还有一个DropDownList,它的SelectedValue决定一个对象的哪些列将被添加/排除在GridView上。



这是一个创建GridView的方法(我写入VB.NET,但C#也是非常受欢迎的):

pre $ Private $ CreateGridView(
Dim gv As New GridView
使用gv
.AllowSorting = True
.AutoGenerateColumns = False
.CssClass =gv
.EmptyDataText =列表为空
.ID =gv
.ShowFooter = True

.AlternatingRowStyle.Wrap = False
.EditRowStyle.Wrap = False
.FooterStyle.Wrap = False
.HeaderStyle.Wrap = False

.SortedAscendingCellStyle.CssClass =sortAscCell
.SortedAscendingHeaderStyle.CssClass =sortAscHeader
.SortedDescendingCellStyle.CssClass =sortDescCell
.SortedDescendingHeaderStyle.CssClass =sortDescHeader

AddHandler .RowDataBound,AddressOf gv_RowDataBound
AddHandler .DataBound,AddressOf gv_DataBound
AddHandler .RowUpdating,AddressOf gv_RowUpdating

.DataSource = odsEquipment.Select
.DataKeyNames = {equipmentID}
End With

For Each item As Dictionary In odsDictionary.Select
如果ddlStages.SelectedValue<> 然后
如果ddlStages.SelectedValue> = item.stage_id然后
Dim tf As New TemplateField()
tf.SortExpression = item.col
tf.HeaderTemplate = New GridViewTemplate (item.title,item.col)
tf.ItemTemplate =新的GridViewTemplate(DataControlRowType.DataRow,item.col,item.ctrlType,item.length)
tf.FooterTemplate =新的GridViewTemplate(DataControlRowType.Footer ,item.col,item.ctrlType,item.length)

gv.Columns.Add(tf)
End If
End If
Next

gv.DataBind()

divGV.Controls.Add(gv)
End Sub

GridView始终处于编辑模式,这意味着它的ItemTemplate是一个TexBox / DropDownList / CheckBox。这是一个ITemplate类:

  Imports System.Data 

公共类GridViewTemplate
Implements ITemplate

私有templateType作为DataControlRowType
私有标题作为字符串
私有columnBinding作为字符串
私有ctrlType作为字符串
私有长度作为整数

Public Sub New(ByVal vTitle As String,vColumnBinding As String)
templateType = DataControlRowType.Header
title = vTitle
columnBinding = vColumnBinding
End Sub

Public Sub New(ByVal type As DataControlRowType,ByVal vColumnBinding As String,ByVal vCtrlType As String,vLength As Integer)
templateType = type
columnBinding = vColumnBinding
ctrlType = vCtrlType
length = vLength
End Sub

Private Sub InstantiateIn(Container As Control)实现ITemplate.InstantiateIn
Select Case temp lateType
Case DataControlRowType.Header
Dim lb As New LinkBut​​ton()
lb.ID =lb+ columnBinding
lb.CommandName =Sort
lb. CommandArgument = columnBinding
lb.Text = title
container.Controls.Add(lb)
退出选择

Case DataControlRowType.DataRow
如果ctrlType = LabelThen
Dim lbl = New Label()
lbl.ID =lbl+ columnBinding
AddControl(lbl,container)
ElseIf ctrlType =TextBoxThen
Dim tb As New TextBox
tb.ID =tb+ columnBinding
tb.MaxLength = length
AddControl(tb,container)
ElseIf ctrlType =CheckBoxThen
Dim cb =新的CheckBox()
cb.ID =cb+ columnBinding
AddControl(cb,container)
ElseIf ctrlType =DropDownListThen
Dim ddl = New DropDownList()
ddl.ID = ddl+ columnBinding
AddControl(ddl,container)
结束如果
退出选择

Case DataControlRowType.Footer
如果ctrlType =LabelThen
tbFrom As New TextBox()
tbFrom.ID =tb+ columnBinding +From
container.Controls.Add(tbFrom)
Dim tbTo As New TextBox()
tbTo.ID =tb+ columnBinding +From
container.Controls.Add(tbTo)
ElseIf ctrlType =TextBoxThen
Dim tb As New TextBox
tb.ID =tb+ columnBinding
tb.MaxLength = length
container.Controls.Add(tb)
ElseIf ctrlType =CheckBoxThen
Dim cb = New CheckBox()
cb.ID =cb + columnBinding
container.Controls.Add(cb)
ElseIf ctrlType =DropDownListThen
Dim ddl = New DropDownList()
ddl.ID =ddl+ columnBinding
AddControl(ddl,container)
结束如果
退出选择

案例否
退出选择
结束选择
结束小组

Private Sub AddControl(ctrl作为控件,容器作为控件)
AddHandler ctrl.DataBinding,AddressOf OnDataBinding
container.Controls.Add(ctrl)
End Sub

Private Sub OnDataBinding(ByVal sender As Object,ByVal e As EventArgs)
如果sender.GetType = G etType(Label)Then
Dim lb As Label = DirectCast(sender,Label)
Dim container As GridViewRow = DirectCast(lb.NamingContainer,GridViewRow)
lb.Text = DataBinder.Eval(container .DataItem,columnBinding).ToString

ElseIf sender.GetType = GetType(TextBox)Then
Dim tb As TextBox = DirectCast(sender,TextBox)
Dim container As GridViewRow = DirectCast (tb.NamingContainer,GridViewRow)
tb.Text = DataBinder.Eval(container.DataItem,columnBinding).ToString

ElseIf sender.GetType = GetType(CheckBox)Then
Dim cb As CheckBox = DirectCast(sender,CheckBox)
Dim container As GridViewRow = DirectCast(cb.NamingContainer,GridViewRow)
cb.Checked = DataBinder.Eval(container.DataItem,columnBinding).ToString

ElseIf sender.GetType = GetType(DropDownList)然后
Dim ddl As DropDownList = Dire ctCast(sender,DropDownList)
Dim container As GridViewRow = DirectCast(ddl.NamingContainer,GridViewRow)
如果columnBinding =criticalityRating则
ddl.Items.Add()
对于i = 1到4
ddl.Items.Add(i)
下一个
ElseIf columnBinding =property_idThen
对于每个p作为PropertyMP在PropertyMPDB.GetProperties
ddl.Items.Add(New ListItem(p.propertyMP,p.property_id))
Next
End If
If templateType = DataControlRowType.DataRow Then
ddl.SelectedValue = DataBinder.Eval(container.DataItem,columnBinding).ToString
End If
End If
End Sub
End Class

DropDownLists绑定到它们自己的ObjectDataSources,并在标记中创建。



据我了解, GridView必须在Page.Init的每个回传中实例化。 Page.Load是为了创建gridview而迟到的,因为它不会维护ViewState并且不可能更新。但是,当我在Init上创建它时,DropDownLists尚未创建或DataBound,所以没有选定的值。我尝试在它们的Inits上填充DropDownLists,而不是将它们绑定到DataSource,但是当我更改SelectedValue时它抛出ViewState错误。



当我在Load上创建GridView时,一切正常,除了最重要的部分,更新...

任何人都可以帮我弄清楚我在哪里初始化/绑定GridView / DropDownLists?我一直在为此挣扎三天,在这里变得绝望:($ / b>

解决方案

没有找到解决方案,但找到了解决方法。



GridView被创建为OnInit,字段被添加在GridView Init上。所有的DropDownLists都是DataBound后,ObjectDataSource从DropDownLists接收其参数。



有一个DropDownList,它负责返回的对象的类型,当我改变SelectedValue之后,DropDownList被重新启动并且ObjectDataSource仍然有旧的值并返回错误的对象。是错误发生的地方 - 绑定GridView和带有错误字段的对象,取而代之的是,我使用了QueryString并做了一个回发,在下一次加载时,ObjectDataSource返回匹配GridView字段的正确对象。 / p>

I have a databound gridview that I create dynamically. The datasource returns an object based on the several DropDownLists (types of objects are different). Depending on the type of the object, the GridView must display certain fields specific only for the object. Also, there is a DropDownList whose SelectedValue decides which columns of an object will be added/excluded from the GridView.

Here is a method that creates the GridView (I write in VB.NET but C# is also very welcome):

Private Sub CreateGridView()
    Dim gv As New GridView
    With gv
        .AllowSorting = True
        .AutoGenerateColumns = False
        .CssClass = "gv"
        .EmptyDataText = "The list is empty"
        .ID = "gv"
        .ShowFooter = True

        .AlternatingRowStyle.Wrap = False
        .EditRowStyle.Wrap = False
        .FooterStyle.Wrap = False
        .HeaderStyle.Wrap = False

        .SortedAscendingCellStyle.CssClass = "sortAscCell"
        .SortedAscendingHeaderStyle.CssClass = "sortAscHeader"
        .SortedDescendingCellStyle.CssClass = "sortDescCell"
        .SortedDescendingHeaderStyle.CssClass = "sortDescHeader"

        AddHandler .RowDataBound, AddressOf gv_RowDataBound
        AddHandler .DataBound, AddressOf gv_DataBound
        AddHandler .RowUpdating, AddressOf gv_RowUpdating

        .DataSource = odsEquipment.Select
        .DataKeyNames = {"equipmentID"}
    End With

    For Each item As Dictionary In odsDictionary.Select
        If ddlStages.SelectedValue <> "" Then
            If ddlStages.SelectedValue >= item.stage_id Then
                Dim tf As New TemplateField()
                tf.SortExpression = item.col
                tf.HeaderTemplate = New GridViewTemplate(item.title, item.col)
                tf.ItemTemplate = New GridViewTemplate(DataControlRowType.DataRow, item.col, item.ctrlType, item.length)
                tf.FooterTemplate = New GridViewTemplate(DataControlRowType.Footer, item.col, item.ctrlType, item.length)

                gv.Columns.Add(tf)
            End If
        End If
    Next

    gv.DataBind()

    divGV.Controls.Add(gv)
End Sub

The GridView is always in Edit mode, meaning, it's ItemTemplate is a TexBox/DropDownList/CheckBox. Here is an ITemplate Class:

Imports System.Data

Public Class GridViewTemplate
    Implements ITemplate

    Private templateType As DataControlRowType
    Private title As String
    Private columnBinding As String
    Private ctrlType As String
    Private length As Integer

    Public Sub New(ByVal vTitle As String, vColumnBinding As String)
        templateType = DataControlRowType.Header
        title = vTitle
        columnBinding = vColumnBinding
    End Sub

    Public Sub New(ByVal type As DataControlRowType, ByVal vColumnBinding As String, ByVal vCtrlType As String, vLength As Integer)
        templateType = type
        columnBinding = vColumnBinding
        ctrlType = vCtrlType
        length = vLength
    End Sub

    Private Sub InstantiateIn(container As Control) Implements ITemplate.InstantiateIn
        Select Case templateType
            Case DataControlRowType.Header
                Dim lb As New LinkButton()
                lb.ID = "lb" + columnBinding
                lb.CommandName = "Sort"
                lb.CommandArgument = columnBinding
                lb.Text = title
                container.Controls.Add(lb)
                Exit Select

            Case DataControlRowType.DataRow
                If ctrlType = "Label" Then
                    Dim lbl = New Label()
                    lbl.ID = "lbl" + columnBinding
                    AddControl(lbl, container)
                ElseIf ctrlType = "TextBox" Then
                    Dim tb As New TextBox
                    tb.ID = "tb" + columnBinding
                    tb.MaxLength = length
                    AddControl(tb, container)
                ElseIf ctrlType = "CheckBox" Then
                    Dim cb = New CheckBox()
                    cb.ID = "cb" + columnBinding
                    AddControl(cb, container)
                ElseIf ctrlType = "DropDownList" Then
                    Dim ddl = New DropDownList()
                    ddl.ID = "ddl" + columnBinding
                    AddControl(ddl, container)
                End If
                Exit Select

            Case DataControlRowType.Footer
                If ctrlType = "Label" Then
                    Dim tbFrom As New TextBox()
                    tbFrom.ID = "tb" + columnBinding + "From"
                    container.Controls.Add(tbFrom)
                    Dim tbTo As New TextBox()
                    tbTo.ID = "tb" + columnBinding + "From"
                    container.Controls.Add(tbTo)
                ElseIf ctrlType = "TextBox" Then
                    Dim tb As New TextBox
                    tb.ID = "tb" + columnBinding
                    tb.MaxLength = length
                    container.Controls.Add(tb)
                ElseIf ctrlType = "CheckBox" Then
                    Dim cb = New CheckBox()
                    cb.ID = "cb" + columnBinding
                    container.Controls.Add(cb)
                ElseIf ctrlType = "DropDownList" Then
                    Dim ddl = New DropDownList()
                    ddl.ID = "ddl" + columnBinding
                    AddControl(ddl, container)
                End If
                Exit Select

            Case Else
                Exit Select
        End Select
    End Sub

    Private Sub AddControl(ctrl As Control, container As Control)
        AddHandler ctrl.DataBinding, AddressOf OnDataBinding
        container.Controls.Add(ctrl)
    End Sub

    Private Sub OnDataBinding(ByVal sender As Object, ByVal e As EventArgs)
        If sender.GetType = GetType(Label) Then
            Dim lb As Label = DirectCast(sender, Label)
            Dim container As GridViewRow = DirectCast(lb.NamingContainer, GridViewRow)
            lb.Text = DataBinder.Eval(container.DataItem, columnBinding).ToString

        ElseIf sender.GetType = GetType(TextBox) Then
            Dim tb As TextBox = DirectCast(sender, TextBox)
            Dim container As GridViewRow = DirectCast(tb.NamingContainer, GridViewRow)
            tb.Text = DataBinder.Eval(container.DataItem, columnBinding).ToString

        ElseIf sender.GetType = GetType(CheckBox) Then
            Dim cb As CheckBox = DirectCast(sender, CheckBox)
            Dim container As GridViewRow = DirectCast(cb.NamingContainer, GridViewRow)
            cb.Checked = DataBinder.Eval(container.DataItem, columnBinding).ToString

        ElseIf sender.GetType = GetType(DropDownList) Then
            Dim ddl As DropDownList = DirectCast(sender, DropDownList)
            Dim container As GridViewRow = DirectCast(ddl.NamingContainer, GridViewRow)
            If columnBinding = "criticalityRating" Then
                ddl.Items.Add("")
                For i = 1 To 4
                    ddl.Items.Add(i)
                Next
            ElseIf columnBinding = "property_id" Then
                For Each p As PropertyMP In PropertyMPDB.GetProperties
                    ddl.Items.Add(New ListItem(p.propertyMP, p.property_id))
                Next
            End If
            If templateType = DataControlRowType.DataRow Then
                ddl.SelectedValue = DataBinder.Eval(container.DataItem, columnBinding).ToString
            End If
        End If
    End Sub
End Class

The DropDownLists are bound to their own ObjectDataSources and are created in the mark-up.

As I understand, the GridView must be instantiated on every postback in the Page.Init. The Page.Load is to late for creating the gridview as it will not maintain the ViewState and will be impossible to update. However, when I create it on Init, the DropDownLists are not created or DataBound yet, so there is no selected value. I tried populating the DropDownLists on their Inits instead of bining them to the DataSource but it throws a ViewState error when I change the SelectedValue.

When I create the GridView on Load, everything works perfectly, except the most important part, updating...

Can anyone help me with figuring out where do I initialize/bind the GridView/DropDownLists? I have been struggling with this for three days now, getting desperate here :(

解决方案

Did not find a solution but found a workaround.

The GridView is created OnInit, fields are added on GridView Init. After all of the DropDownLists are DataBound, the ObjectDataSource receives its parameters from the DropDownLists.

There is one DropDownList, which is responsible for the type of Object returned. After I change the SelectedValue, the DropDownList is reinitiated and ObjectDataSource still has the old value and returns the wrong object. This is where the error was - binding GridView with an Object with wrong fields. Instead of this, I used QueryString and did a postback. On the next load, the ObjectDataSource returns the correct object that matches GridView's fields. Everything is smooth from there.

这篇关于带有TemplateField的Ddynamic GridView - LifeCycle中的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆