从ObservableCollection

时间:2016-06-07 07:56:39

标签: c# xaml xamarin xamarin.forms zxing

我使用ObservableCollection<BarcodeInfo>作为ItemsSource的{​​{1}}来生成ListView。一个单元格包含2个ViewCells和一个Labels,其绑定到我的ZXingBarcodeImageView - 类,一切都按预期工作。

现在我要从BarcodeInfo删除几个单元格,但是一旦我尝试这样做,我就会从ListView

中获得以下异常
  

System.ArgumentException:找到空内容

这是我的XAML

ZXingBarcodeImageView

ListView中<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;

一旦我尝试

,就会发生异常
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); 并尝试将所有属性设置为null,无异常,但是ZXingBarcodeImageView没有清除条形码图像,如果我尝试从中移除Item,则仍会抛出异常收藏。我正处于一个我没有更多想法的地方。

我希望有人可以帮助我。

更新 因为INotifyPropertyChanged似乎令人困惑,所以我正在使用它的循环

i

2 个答案:

答案 0 :(得分:0)

我已设法确定问题的原因,这是在删除元素并将ListViewCachingStrategy设置为RetainElement(默认值)时刷新ListView的方式的副作用。 从集合中删除项目时,将调用自定义渲染器OnElementPropertyChanged,并且ZXing自定义渲染器中的regenerate()方法崩溃。 这可以通过将ListViewCachingStrategy设置为RecycleElement来解决,这将适用于Android,但iOS 10仍然存在问题,它不能正确支持将ListViewCachingStrategy设置为RecycleElement的listview,iOS 10 currentlly仅适用于设置为RetainElement的ListViewCachingStrategy如果您在便携式代码中创建自定义控件,则可以适应这种情况,例如:

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

然后根据ZXing源创建自己的自定义渲染器,但将void regenerate()方法替换为以下内容:

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

如果您将ListViewCachingStrategy设置为RecycleElement,则不必为Android创建自定义渲染器,ZXingBarcodeImageView的基本渲染器将毫无错误地使用。

答案 1 :(得分:0)

不是一个简单的解决方案,但我发现的最简单的解决方法是在绑定 FallbackValue 时提供 BarcodeValue

<forms:ZXingBarcodeImageView BarcodeFormat="{Binding Format}" 
                             BarcodeValue="{Binding Content, FallbackValue='1'}" />