2016-06-07 3 views
0

Я использую ObservableCollection<BarcodeInfo> как ItemsSource из ListView для генерации ViewCells. A Cell содержит 2 Labels и ZXingBarcodeImageView с привязками к моему классу BarcodeInfo, все работает так, как ожидалось.Исключение из ZXingBarcodeImageView при удалении из ObservableCollection

Теперь я удалить несколько клеток из ListView, но как только я пытаюсь сделать так, я получаю следующее исключение из ZXingBarcodeImageView

System.ArgumentException: Найдено порожнее содержание

Вот мой XAML

<ListView RowHeight="50"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <ViewCell> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="1*" /> 
         <ColumnDefinition Width="3*" /> 
        </Grid.ColumnDefinitions> 

        <zxing:ZXingBarcodeImageView 
         BarcodeFormat="{Binding Format}" 
         BarcodeOptions="{Binding Options}" 
         BarcodeValue="{Binding Text}" 
         HorizontalOptions="FillAndExpand" 
         VerticalOptions="FillAndExpand" 
         Margin="5" 
         Grid.Column="0"/> 

        <StackLayout Grid.Row="0" Grid.Column="1" 
           Spacing="0" VerticalOptions="CenterAndExpand"> 
         <Label Text="{Binding Text}" 
          LineBreakMode="TailTruncation" 
          VerticalOptions="End"/> 
         <Label Text="{Binding Format}" 
          VerticalOptions="End" 
          LineBreakMode="TailTruncation"/> 
        </StackLayout> 
       </Grid> 
      </ViewCell> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

А Класс для ObservableCollection<BarcodeInfo> _barcodeCollection; в в ListVi РЭБ

public class BarcodeInfo 
{ 
    public string Text 
    { get; set; } 

    public string Detail 
    { get; set; } 

    public BarcodeFormat Format 
    { get; set; } 

    public EncodingOptions Options 
    { get; set; } 
} 

Исключение происходит, как только я пытаюсь

_barcodeCollection.RemoveAt(i); 

Я реализовал INotifyPropertyChanged и попытался установить все свойства обнулить, который работает без исключения, но ZXingBarcodeImageView не очищает штрих-кода -image и Exception все равно бросается, если я пытаюсь удалить Item из коллекции. Я в такой ситуации, когда у меня больше нет идей.

Надеюсь, кто-нибудь может мне помочь.

Update Поскольку i кажется, путает здесь это цикл я использую это

for (int i = 0; i < _barcodeCollection.Count; i++) 
{ 
    var response = 
     await _serverUrl.PostUrlEncodedAsync(
      new { barcode = _barcodeCollection[i].Text }) 
      .ReceiveString(); 

    if (string.Equals(response, "ok", StringComparison.OrdinalIgnoreCase)) 
    { 
     percentage += progressSteps; 

     _barcodeCollection.RemoveAt(i); //EXCEPTION!!! 

     i--; // index must be checked twice else one element will be skipped 

     await UploadProgress.ProgressTo(percentage, 250, Easing.Linear); 
    } 
} 
+0

Что вы 'i'?Это не тот случай, когда вы удалили все элементы, и вы пытаетесь удалить что-то из коллекции. –

+0

'i' является частью цикла for' for (int i = 0; i <_barcodeCollection.Count; i ++) 'внутри - это вещи, которые я проверяю, и если true, я пытаюсь удалить элемент –

+0

Не увеличивайте' i' после ' RemoveAt (я) '. – Clemens

ответ

0

мне удалось определить причину проблемы, это побочный эффект так, ListView обновляется, когда элементы удаляются, а ListViewCachingStrategy - RetainElement (по умолчанию). Пользовательский рендерер OnElementPropertyChanged вызывается, когда элементы удаляются из коллекции, а также метод регенерации() в пользовательском рендерере ZXing. Это можно решить, установив ListViewCachingStrategy в RecycleElement, это будет работать с Android, однако по-прежнему существует проблема с iOS 10, которая неправильно поддерживает список со списком ListViewCachingStrategy, установленным в RecycleElement, iOS 10 currentlly работает только с ListViewCachingStrategy, установленным для RetainElement, это может быть размещено, если вы создаете пользовательский элемент управления в портативной коде, например:

public class MyZXingBarcodeImageView : ZXingBarcodeImageView 
    { 
    //THERE IS NO CODE REQUIRED HERE 
    } 

а затем создать свой собственный пользовательский визуализатор на основе источника ZXing, но заменить метод недействительные регенерировать() со следующим:

void regenerate() 
    { 
     if(formsView != null && !string.IsNullOrWhiteSpace(formsView.BarcodeValue)) 
     { 
      var writer = new ZXing.Mobile.BarcodeWriter(); 

      if(formsView != null && formsView.BarcodeOptions != null) 
       writer.Options = formsView.BarcodeOptions; 
      if(formsView != null && formsView.BarcodeFormat != null) 
       writer.Format = formsView.BarcodeFormat; 

      var value = formsView != null ? formsView.BarcodeValue : string.Empty; 

      Device.BeginInvokeOnMainThread(() => 
      { 

       var image = writer.Write(value); 

       imageView.Image = image; 

       }); 

     } 
    } 

Изменение находится в самом первом выражении If, изменяющемся от тестирования для нулевой строки в string.IsNullOrWhiteSpace

Вам не нужно создавать собственный рендер для Android, если вы используете ListViewCachingStrategy, установленный в RecycleElement, базовый рендеринг для ZXingBarcodeImageView будет использовать без ошибок.

 Смежные вопросы

  • Нет связанных вопросов^_^