Carlo Piras Ответов: 1

Datarepeater и tablelayoutpanel: исключение с повторяющимся стилем строки


Я экспериментировал с элементом управления DataRepeater из Microsoft. VisualBasic.Пакет PowerPacks, надеясь, что он поможет мне более эффективно отображать данные в моем проекте. Он работает довольно хорошо, когда ItemTemplate дается от дизайнера, но для моего проекта мне понадобится элемент управления, чтобы принимать различные шаблоны в зависимости от ситуации: как таковой, я попытался написать некоторый код, чтобы изменить шаблон во время выполнения. Однако при этом я получаю систему.Исключение ArgumentException после попытки передать источник данных элементу управления со следующим сообщением:Невозможно добавить или вставить элемент "стиль строки" более чем в одном месте. Сначала вы должны удалить его из текущего местоположения или клонировать.

Это код, который я использую, причем DR1 - это DataRepeater, а аргументы CNT_ и TB_-константы, которые я использую для отслеживания имен:
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


Что я уже пробовал:

Я считаю, что эта проблема вызвана TableLayoutPanel, которую я использую для позиционирования элементов управления: попытка добавить TableLayoutPanel в ItemTemplate конструктором вызвала то же исключение. Однако все пользовательские шаблоны, которые я должен использовать в своем проекте, также используют этот тип панели, и я не могу просто изменить структуру, чтобы избежать ошибки. Я попытался найти эту ошибку в интернете, но найти ресурсы на DataRepeater довольно сложно, особенно для .NET: единственный другой человек, которого я нашел с этой проблемой в конце концов пришлось отказаться от контроля. Кто-нибудь знает способ решить эту проблему? Заранее спасибо.

1 Ответов

Рейтинг:
12

Carlo Piras

В конце концов, мне удалось найти решение самостоятельно, я оставлю его здесь на случай, если он кому-то еще понадобится. Я переместил создание шаблона в отдельную функцию CreateTemplate () и добавил новый обработчик для события ItemCloning: таким образом, когда новый элемент будет добавлен в ретранслятор, функция создаст вместо него совершенно новый шаблон. Новый код выглядит так:

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
Этого было достаточно, чтобы полностью устранить проблему. Надеюсь, это поможет!