`` Estoy completamente confundido sobre por qué recibo este error:

System.NullReferenceException ocurrió HResult = -2147467261 Mensaje = Referencia de objeto no establecida en una instancia de un objeto. Fuente = Xamarin.Forms.Platform.UAP StackTrace: en Xamarin.Forms.Platform.UWP.WindowsBasePlatformServices.get_IsInvokeRequired () en Xamarin.Forms.ListProxy.OnCollectionChanged (remitente del objeto, NotifyCollectionChangedEventArgs e) en Xamarin.Forms.ListProxy.WeakNotifyProxy.OnCollectionChanged (remitente del objeto, NotifyCollectionChangedEventArgs e) en System.Collections.ObjectModel.ObservableCollection 1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection 1.InsertItem (índice Int32, elemento T) en System.Collections.ObjectModel.Collection`1.Add (elemento T) en ViewModels.ScanBadgesViewModel.Add (resultado de BadgeScan) InnerException:

El error resulta de la siguiente línea:

EmployeeIds.Add(badge.EmployeeId)

NOTA: Este error se observa en una aplicación universal de Windows 10 de Xamarin.Forms (versión preliminar).

Si comento el elemento ListView dentro del XAML, ya no recibo la excepción nula.

Si solo comento la ItemTemplate de ListView, sigo observando la excepción nula.

XAML:

    <Grid Grid.Row="4" Grid.RowSpacing="3" Grid.ColumnSpacing="3" BackgroundColor="Silver">
        <ListView ItemsSource="{Binding EmployeeIds}" SelectedItem="{Binding SelectedEmployeeId}"
                  BackgroundColor="Black">
          <ListView.ItemTemplate>
            <DataTemplate>
              <ViewCell>
                <ViewCell.View>
                    <Label Text="{Binding Value}" TextColor="Yellow" XAlign="Start" />
                </ViewCell.View>
              </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
      </Grid>

Propiedad ViewModel:

        ObservableCollection<EmployeeId> _employeeIds = new ObservableCollection<EmployeeId>();
        public ObservableCollection<EmployeeId> EmployeeIds
        {
            get { return _employeeIds; }
            set
            {
                if (_employeeIds != value)
                {
                    _employeeIds = value;
                    OnNotifyPropertyChanged();
                }
            }
        }

Entidades:

    public class EmployeeId
    {
        public EmployeeId(string employeeId) { Value = employeeId; }

        public string Value { get; }
    }

    public class BadgeScan
    {
        public BadgeScan(string employeeId) { EmployeeId = new EmployeeId(employeeId); }

        public BadgeScan(BadgeScan source, Predicate<string> validate) : this(source.EmployeeId.Value)
        {
            IsValid = validate.Invoke(source.EmployeeId.Value);
        }

        public EmployeeId EmployeeId { get; }

        public bool IsValid { get; }
    }

ACTUALIZACIÓN

Esta línea de código altera el comportamiento de mi operación ObservableCollection.Add:

var administeredScan = new BadgeScan(result, validate);

La línea simplemente crea una copia del objeto.

var validate = DependencyManager.Resolve(typeof(Predicate<string>)) as Predicate<string>;

var administeredScan = new BadgeScan(result, validate);
var canAdd = CanAdd(administeredScan) && 
             ScanMode == Entities.ScanMode.Add;

if (canAdd) Add(administeredScan);
break;

Esto aún genera una excepción aunque se agrega un elemento a la colección: Add(administeredScan);

Sin embargo, esto tiene éxito:

var result = obj as BadgeScan;
Add(result);

Entonces, crear una copia de un objeto para agregar a mi observable falla. Pero agregar el objeto original tiene éxito.

2
Scott Nimrod 27 ene. 2016 a las 10:45

3 respuestas

La mejor respuesta

Este es un error de Xamarin.Forms con respecto a la Plataforma universal de Windows (es decir, Windows 10).

En lugar de invocar la operación Add en ObservableCollection a la que mi UI está vinculada a los datos, simplemente creo una nueva ObservableCollection para cada operación Add y paso una colección dentro del constructor.

Solución alternativa:

_employeeIdsHack.Add(administeredScan.EmployeeId);
EmployeeIds = new ObservableCollection<EmployeeId>(_employeeIdsHack);
3
Scott Nimrod 27 ene. 2016 a las 17:04

Su segundo constructor BadgeScan no inicializa la propiedad EmployeeId. En esta línea:

EmployeeIds.Add(badge.EmployeeId);

... parece que está agregando un objeto null a la colección. Eso en sí mismo no debería ser un problema, pero estás usando EmployeeId.Value en un enlace de datos. Supongo que la NRE está relacionada con esto.


Actualización : @ScottNimrod dice que es un error de Xamarin, en cuyo caso es posible que la NRE no esté conectada con esto después de todo. Aun así: ¿Es intencional la falta de fraguado de EmployeeId?

0
Petter Hesselberg 27 ene. 2016 a las 16:54

Sus propiedades son de solo lectura. Cambiaría las propiedades para tener un conjunto privado.

        public EmployeeId EmployeeId { get; private set; }

        public bool IsValid { get; private set;}
0
Ken Tucker 27 ene. 2016 a las 08:31