添加到ObservableCollection的项目是成功的但仍引发异常

时间:2016-01-27 07:45:13

标签: xaml win-universal-app xamarin.forms

``我完全不知道为什么会收到这个错误:

  

发生了System.NullReferenceException     的HResult = -2147467261     Message =对象引用未设置为对象的实例。     来源= Xamarin.Forms.Platform.UAP     堆栈跟踪:          在Xamarin.Forms.Platform.UWP.WindowsBasePlatformServices.get_IsInvokeRequired()          在Xamarin.Forms.ListProxy.OnCollectionChanged(Object sender,NotifyCollectionChangedEventArgs e)          在Xamarin.Forms.ListProxy.WeakNotifyProxy.OnCollectionChanged(Object sender,NotifyCollectionChangedEventArgs e)          at System.Collections.ObjectModel.ObservableCollection 1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection 1.InsertItem(Int32 index,T item)          在System.Collections.ObjectModel.Collection`1.Add(T item)          在ViewModels.ScanBadgesViewModel.Add(BadgeScan结果)     InnerException:

错误来自以下行:

EmployeeIds.Add(badge.EmployeeId)

注意: 在Xamarin.Forms Windows 10 Universal应用程序(预览版)上观察到此错误。

如果我在XAML中注释掉ListView元素,那么我不再收到null异常。

如果我只注释掉ListView的ItemTemplate,那么我仍然会观察到null异常。

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>

ViewModel属性:

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

实体:

    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; }
    }

更新

这行代码改变了我的ObservableCollection.Add操作的行为:

var administeredScan = new BadgeScan(result, validate);

该行只是创建对象的副本。

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;

即使将一个项目添加到集合中,这仍会引发异常: Add(administeredScan);

然而,这成功了:

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

因此,创建要添加到我的observable的对象的副本失败。但是添加原始对象会成功。

3 个答案:

答案 0 :(得分:2)

这是关于Windows Universal Platform(即Windows 10)的Xamarin.Forms错误。

我不是在我的UI数据绑定的ObservableCollection上调用Add操作,而是为每个Add操作创建一个新的ObservableCollection,并在构造函数中传入一个集合。

解决方法:

_employeeIdsHack.Add(administeredScan.EmployeeId);
EmployeeIds = new ObservableCollection<EmployeeId>(_employeeIdsHack);

答案 1 :(得分:0)

您的属性是只读的。我会将属性更改为具有私有集

        public EmployeeId EmployeeId { get; private set; }

        public bool IsValid { get; private set;}

答案 2 :(得分:0)

您的第二个BadgeScan构造函数未初始化EmployeeId属性。在这一行:

EmployeeIds.Add(badge.EmployeeId);

...看起来你可能会在集合中添加一个null对象。这本身不应该是一个问题,但你在数据绑定中使用EmployeeId.Value。我的猜测是NRE与此有关。

更新:@ScottNimrod说它是一个Xamarin错误,在这种情况下,NRE可能与此无关。即便如此:EmployeeId是否有意设置?