Я столкнулся с аналогичной проблемой со следующей настройкой:
- Флажок на строку
- Текстовое поле поиска (перед управлением повторителем, для фильтрации элементов)
- Много элементов в повторителе (по крайней мере, число достаточно большое, чтобы его можно было прокручивать)
Я бы фильтровал (или нет) свой список и выбирал элементы из повторителя. Но когда я прокручивал, мои выбранные строки не отслеживались. Вместо этого при прокрутке были выбраны случайные строки.
Я думаю, что вы можете столкнуться с той же проблемой. У меня нет доказательств того, что я говорю, и я не мог в то время найти ответ на SO, но я думаю, что это связано с тем, как работает повторитель.
Он указывает индекс вашего элемента (строки) на основе отображаемых элементов (элементов, которые видны в определенное время). Таким образом, можно быстро прокручивать компонент, повторяя элементы управления.
Представьте, что было бы, если бы у вас было 10 элементов управления в строке и отображалось бы 30 000 строк. Как вы думаете, что произойдет, если повторителю придется создать 300 000 элементов управления?
По этой причине (и еще раз я предполагаю, что это мои предположения, поскольку документации очень мало - как вы, возможно, уже знаете) повторитель создает только элементы управления для элементов, которые соответствуют вашей области повторителя, и перерабатывает их.
Это означает, что если вы выполняете какую-то операцию над элементом по индексу XX и прокручиваете, поскольку элементы не находятся в одном индексе, повторитель будет переворачиваться, поскольку индексы пересчитываются при прокрутке.
Хорошо, теперь, когда я ответил на ваш вопрос о том, что происходит, давайте посмотрим, как это исправить:
Сначала добавьте Label
к ItemTemplate
ретранслятора. Эта метка будет использоваться для привязки свойства вашего элемента Id
(или чего-то в этом роде). Кроме того, установите для свойства label Visible значение false, чтобы скрыть это.
В моей форме я добавляю эти поля:
// I use an observable collection to be notified when it changes
private ObservableCollection<YourItem> _allItems =
new ObservableCollection<YourItem>();
private BindingSource _bindingSource;
Затем привяжите свою коллекцию к повтору (я делаю это в OnLoad)
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
...
_bindingSource = new BindingSource();
_bindingSource.DataSource = _allItems;
// my hidden label // All my items have an Id property
_labelHiddenId.DataBindings.Add("Text", BindingSource, "Id");
_dataRepeaterList.DataSource = _bindingSource;
_allItems.CollectionChanged += AllItems_CollectionChanged;
}
мой слушатель:
protected override void AllItems_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
RefreshRepeater();
}
мой метод обновления:
protected void RefreshRepeater(bool search = false)
{
if (_dataRepeaterList.InvokeRequired)
{
_dataRepeaterList.Invoke((Action)(() => { RefreshRepeater(search); }));
return;
}
_bindingSource.DataSource = null; // Clear binding source first
_bindingSource.DataSource = _allItems.ToList();
_dataRepeaterList.DataSource = null; // Clear datasource first
_dataRepeaterList.DataSource = _bindingSource;
_dataRepeaterList.Refresh();
}
мой метод рисования элемента, в котором я заполняю большую часть информации о строке:
protected override void DataRepeater_DrawItem(object sender,
DataRepeaterItemEventArgs e)
{
var dataSourceEntity = GetObjectFromDataSource(e.DataRepeaterItem);
var checkedComponent = _checkedItems.SingleOrDefault(
x => x.Equals(dataSourceEntity));
// Get current item control to fill. Something like
var grid = e.DataRepeaterItem.Controls["yourgridiew"] as DataGridView;
// Do stuff, you are messing with the right object :)
}
И моя последняя часть:
protected override T GetObjectFromDataSource(DataRepeaterItem dataRepeaterItem)
{
if (dataRepeaterItem == null)
return null;
var hiddenIdLabel = (Label)dataRepeaterItem.Controls[_labelHiddenId.Name];
return _allItems.FirstOrDefault((entity) => entity.Id.ToString().Equals(hiddenIdLabel.Text));
}
Этот код не видел компилятора, но он должен направить вас на правильный путь.
Подвести итог:
- Создайте скрытую метку в шаблоне элемента
- Создайте наблюдаемую коллекцию и при изменении события обновите повторитель
- Создайте источник привязки, установите его источник данных в свою коллекцию.
- Сделайте так, чтобы ваши элементы имели общий идентификатор и привязали этот идентификатор к повторителю.
- При обновлении ретранслятора новыми данными сбросьте источник данных (на всякий случай)
- Создайте метод для поиска исходного объекта (объекта источника данных) на основе текущей строки повторителя.
- Получите контроль над текущим объектом (объектом источника данных) и примените к нему операции.
Это заняло много времени, чтобы найти и реализовать, но, надеюсь, вам будет легче :)
person
Joel
schedule
11.09.2013