Click here to Skip to main content
15,034,986 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've been experimenting with the DataRepeater control from the Microsoft.VisualBasic.PowerPacks package, hoping it will help me display data in my project in a more efficient manner. It works pretty well when the ItemTemplate is given from the designer, but for my project I'll need the control to take different templates depending on the situation: as such, I've tried writing some code to change the template at runtime. When doing so, however, I get a System.ArgumentException exception after trying to give a DataSource to the control, with the following message:Cannot add or insert the item 'RowStyle' in more than one place. You must first remove it from its current location or clone it.

This is the code I'm using, with DR1 being the DataRepeater and the CNT_ and TB_ arguments being constants I use to keep track of the names:
DR1.BeginResetItemTemplate()
Dim tlp As New TableLayoutPanel With {
    .Dock = DockStyle.Fill,
    .RowCount = 2,
    .ColumnCount = 2
}
tlp.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 75))
tlp.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 100))
tlp.RowStyles.Add(New RowStyle(SizeType.Absolute, 25))
tlp.RowStyles.Add(New RowStyle(SizeType.Absolute, 25))

Dim lblName As New Label With {
    .Dock = DockStyle.Fill,
    .Text = "Name:",
    .TextAlign = ContentAlignment.MiddleLeft
}
Dim tbxName As New TextBox With {
    .Dock = DockStyle.Fill,
    .Name = CNT_NAME
}
Dim lblBday As New Label With {
    .Dock = DockStyle.Fill,
    .Text = "Birth date:",
    .TextAlign = ContentAlignment.MiddleLeft
}
Dim dtpBday As New DateTimePicker With {
    .Dock = DockStyle.Fill,
    .Name = CNT_BDAY,
    .Format = DateTimePickerFormat.Short
}

tlp.Controls.Add(lblName, 0, 0)
tlp.Controls.Add(tbxName, 1, 0)
tlp.Controls.Add(lblBday, 0, 1)
tlp.Controls.Add(dtpBday, 1, 1)

DR1.ItemTemplate.Controls.Clear()
DR1.ItemTemplate.Controls.Add(tlp)
DR1.EndResetItemTemplate()

Dim dt As New DataTable
dt.Columns.Add(TB_NAME)
dt.Columns.Add(TB_BDAY)

dt.Rows.Add("Name 1", New Date(1991, 11, 8))
dt.Rows.Add("Name 2", New Date(1992, 8, 16))
dt.Rows.Add("Name 3", New Date(1993, 7, 5))

DR1.DataSource = dt


What I have tried:

I believe this issue is caused by the TableLayoutPanel I'm using to position the controls: trying to add a TableLayoutPanel to the ItemTemplate by designer caused the same exception. All the custom templates I have to use in my project, however, also use that type of Panel, and I can't just change the structure to avoid the bug. I tried looking up this bug online, but finding resources on the DataRepeater is quite difficult, especially for .NET: the only other person I found with this problem had to give up on the control in the end. Does anyone know a way to resolve this issue? Thanks in advance.
Posted
Updated 1-Feb-17 21:52pm
v2

1 solution

In the end I've managed to find a solution on my own, I'll leave it here in case anyone else needs it. I've moved the template creation to a separate function CreateTemplate() and added a new handler for the event ItemCloning: this way, when a new item would be added to the repeater, the function will create an entirely new template instead. The new code looks like this:
Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)

    DR1.BeginResetItemTemplate()
    Dim tlp = CreateTemplate()
    DR1.ItemTemplate.Controls.Clear()
    DR1.ItemTemplate.Controls.Add(tlp)
    DR1.EndResetItemTemplate()

End Sub
Private Sub ItemCloning(sender As Object, e As DataRepeaterItemCloneEventArgs) Handles DR1.ItemCloning

    Dim origin As DataRepeaterItem = e.Source

    If TypeOf origin.Controls(0) Is TableLayoutPanel Then
        e.Target = New DataRepeaterItem
        e.Target.Controls.Add(CreateTemplate)
        e.Handled = True
    End If

End Sub
This was enough to completely eliminate the problem. Hope this helps!
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900