简体   繁体   English

更新ObservableCollection列表时发生未处理的异常

[英]An unhandled exception occured when updating ObservableCollection list

im trying to load data from a webservice into a sfDataGrid using parameters i get from OnNavigatedTo 我试图使用我从OnNavigatedTo获取的参数将数据从Web服务加载到sfDataGrid

first it loads a dummy row into the grid because i can´t get the data OnNavigatedTo yet then it runs the OnNavigatedTo and gets the data from the webservice and gose into adding the data to the ObservableCollection that the grid has ItemsSource set to 首先,它将空行加载到网格中,因为我无法获取数据OnNavigatedTo,然后它运行OnNavigatedTo并从Web服务获取数据,然后将数据添加到网格中将ItemsSource设置为的ObservableCollection中。

using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace PrismUnityApp2.ViewModels
{

public class HovedsideViewModel : BindableBase, INotifyPropertyChanged , INavigationAware
{
    MobileService.VaksServiceClient ws = new MobileService.VaksServiceClient();
    INavigationService _navigationService;
    public event PropertyChangedEventHandler PropertyChanged;


    private DateTime selectedDate;
    public DateTime SelectedDate
    {
        get { return selectedDate; }
        set
        {
            if (selectedDate != value)
            {
                selectedDate = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this,
                        new PropertyChangedEventArgs("SelectedDate"));
                }
            }
        }
    }

    private DateTime minimumSelectedDate;
    public DateTime MinimumSelectedDate
    {
        get { return minimumSelectedDate; }
        set
        {
            if (minimumSelectedDate != value)
            {
                minimumSelectedDate = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this,
                        new PropertyChangedEventArgs("MinimumSelectedDate"));
                }
            }
        }
    }

    public DelegateCommand Navigatetest { get; private set; }
    public DelegateCommand NavigateToBestilling { get; private set; }

    public string latitude { get; set; }
    private string _longitude;

    public string longitude
    {
        get { return _longitude; }
        set
        {
            _longitude = value;
            ws.GetToemmeDatasAsync(latitude, longitude, DateTime.Today.AddDays(-7)); // needs to be set to the 1 of november as its the only day with data
        }
    }




    public HovedsideViewModel(INavigationService navigationService)
    {
        try
        {
            toemmeListe = new ObservableCollection<ToemningData>();
        }
        catch (Exception ex)
        {

            throw;
        }
          SetRowData();

        MinimumSelectedDate = DateTime.Now;
        SelectedDate = DateTime.Now.AddDays(1);

        _navigationService = navigationService;
        Navigatetest = new DelegateCommand(Navigate);
        NavigateToBestilling = new DelegateCommand(_NavigateToBestilling);
    }



    private void _NavigateToBestilling()
    {
        _navigationService.NavigateAsync("Bestilling");
    }

    private void Navigate()
    {
        _navigationService.NavigateAsync("Scanner");
    }

    public void OnNavigatedFrom(NavigationParameters parameters)
    {

    }

    public void OnNavigatedTo(NavigationParameters parameters)
    {
        latitude = parameters["lat"].ToString();  // if the phone inst near latitude "55,7070631" and longitude "12,4235393" then remove the part where it gets data from parameters
        longitude = parameters["lon"].ToString();  // and use the two lines under this
        //latitude = "55,7070631";
        //longitude = "12,4235393";
    }

    public void SetRowData()
    {
        ws.GetToemmeDatasCompleted += Ws_GetToemmeDatasCompleted;
        ws.GetToemmeDatasAsync(latitude, longitude, DateTime.Today.AddDays(-7));   // needs to be set to the 1 of november as its the only day with data 
    }


    private void Ws_GetToemmeDatasCompleted(object sender, MobileService.GetToemmeDatasCompletedEventArgs e)
    {

        int numOfRows = 0;
        try
        {
            numOfRows = e.Result.Count();   // awdawd
        }
        catch (Exception)
        {
            numOfRows = 0;
        }
        //ToemmeListe.Clear();
        if (numOfRows > 0)
        {
            foreach (var toemming in e.Result)
            {
                ToemningData _ToemningData = new ToemningData();
                _ToemningData.Fraktion = toemming.Fraktion;
                _ToemningData.ToemmeID = toemming.ToemmeId;
                _ToemningData.Type = toemming.type;
                _ToemningData.Vaegt = toemming.weight;
                ToemmeListe.Add(_ToemningData);  // failes when it trys to add a new row   // An unhandled exception occured.
            }
        }
        else  // if there isnt any data then set one row saying that there isnt any data
        {
            ToemningData _ToemningData = new ToemningData();  
            _ToemningData.Fraktion = "Igen Data";
            _ToemningData.ToemmeID = -1;
            _ToemningData.Type = "Igen Data";
            _ToemningData.Vaegt = "Igen Data";
            ToemmeListe.Add(_ToemningData);
        }
    }

    private ObservableCollection<ToemningData> toemmeListe;

    public ObservableCollection<ToemningData> ToemmeListe
    {
        get { return toemmeListe; }
        set { this.toemmeListe = value; }
    }

    }
}

xaml XAML

    <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             xmlns:sfgrid="clr-namespace:Syncfusion.SfDataGrid.XForms;assembly=Syncfusion.SfDataGrid.XForms"
             x:Class="PrismUnityApp2.Views.Hovedside"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             Title="test">

  <ContentPage.Content>

    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="20" />
        <RowDefinition Height="50"/>
        <RowDefinition  Height="*" />
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
      </Grid.RowDefinitions>

      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>

      <DatePicker Date="{Binding SelectedDate,Mode=TwoWay}" MinimumDate="{Binding MinimumSelectedDate,Mode=TwoWay}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" HorizontalOptions="Center">
        <DatePicker.Format>yyyy-MM-dd</DatePicker.Format>
      </DatePicker>



      <sfgrid:SfDataGrid x:Name="dataGrid"
                  AutoGenerateColumns="False"
                  ColumnSizer="Star"
                  SelectedIndex="1"
                  SelectionMode="Single"
                 ItemsSource="{Binding ToemmeListe}"
                   AllowSorting="True"
                          Grid.Row="2" 
                          Grid.Column="0" Grid.ColumnSpan="3"
                         >

        <sfgrid:SfDataGrid.Columns x:TypeArguments="syncfusion:Columns">
          <sfgrid:GridTextColumn HeaderText="Fraktion"
                                     MappingName="Fraktion" />     <!--Fraktion-->                                               
          <sfgrid:GridTextColumn HeaderText="Type"
                                     MappingName="Type" />          <!--Type--> 
          <sfgrid:GridTextColumn HeaderText="Vaegt"
                                   MappingName="Vaegt" />     <!--vægt-->
        </sfgrid:SfDataGrid.Columns>

      </sfgrid:SfDataGrid>

      <Button Text="Scan" FontSize="24" Grid.Row="3" Grid.Column="0" Command="{Binding Navigatetest}"/>
      <Button Text="Mail" FontSize="24" Grid.Row="3" Grid.Column="2"/>
      <Button Text="Manuel" FontSize="24" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" HorizontalOptions="Center" Command="{Binding NavigateToBestilling}"/>

    </Grid>


  </ContentPage.Content>

</ContentPage>

when it gets in the Ws_GetToemmeDatasCompleted after getting the data from the webservice it stops at ToemmeListe.Add(_ToemningData); 从Web服务获取数据后,当它进入Ws_GetToemmeDatasCompleted时,它停在ToemmeListe.Add(_ToemningData); in

foreach (var toemming in e.Result)
            {
                ToemningData _ToemningData = new ToemningData();
                _ToemningData.Fraktion = toemming.Fraktion;
                _ToemningData.ToemmeID = toemming.ToemmeId;
                _ToemningData.Type = toemming.type;
                _ToemningData.Vaegt = toemming.weight;
                ToemmeListe.Add(_ToemningData);  // failes when it trys to add a new row   // An unhandled exception occured.
            }

and says An unhandled exception occured. 并说发生了未处理的异常。

Any help is deeply appreciated 任何帮助深表感谢

im using visual studio 2015 community, xamarin, prism v6.2.0 Xam.Plugin.Geolocator v3.0.4 and Syncfusion mainly running it on a sony xperia z3 with Android version 6.0.1 and using API 23 我使用Visual Studio 2015社区,xamarin,prism v6.2.0 Xam.Plugin.Geolocator v3.0.4和Syncfusion主要在具有Android 6.0.1版本并使用API​​ 23的索尼xperia z3上运行它

Dropbox link to the full project Dropbox链接到完整项目

The solution to i went with 我的解决方案去了

    using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using PrismUnityApp2.ProxyClient;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;

namespace PrismUnityApp2.ViewModels
{


    public class HovedsideViewModel : BindableBase, INotifyPropertyChanged, INavigationAware
    {
        MobileService.VaksServiceClient ws = new MobileService.VaksServiceClient();
        INavigationService _navigationService;
        public event PropertyChangedEventHandler PropertyChanged;


        private DateTime selectedDate;
        public DateTime SelectedDate
        {
            get { return selectedDate; }
            set
            {
                if (selectedDate != value)
                {
                    selectedDate = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this,
                            new PropertyChangedEventArgs("SelectedDate"));
                    }
                }
            }
        }

        private DateTime minimumSelectedDate;
        public DateTime MinimumSelectedDate
        {
            get { return minimumSelectedDate; }
            set
            {
                if (minimumSelectedDate != value)
                {
                    minimumSelectedDate = value;

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this,
                            new PropertyChangedEventArgs("MinimumSelectedDate"));
                    }
                }
            }
        }

        public DelegateCommand Navigatetest { get; private set; }
        public DelegateCommand NavigateToBestilling { get; private set; }

        public string latitude { get; set; }
        private string _longitude;

        public string longitude
        {
            get { return _longitude; }
            set { _longitude = value; }
        }




        public HovedsideViewModel(INavigationService navigationService)
        {

            SetRowData(); // initialize the grid

            MinimumSelectedDate = DateTime.Now;  // this one will be revmoved later. its fine that they can go back and watch but not edite it
            SelectedDate = DateTime.Now.AddDays(1);

            _navigationService = navigationService;
            Navigatetest = new DelegateCommand(Navigate);
            NavigateToBestilling = new DelegateCommand(_NavigateToBestilling);
        }



        private void _NavigateToBestilling()
        {
            _navigationService.NavigateAsync("Bestilling");
        }

        private void Navigate()
        {
            _navigationService.NavigateAsync("Scanner");
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public async void OnNavigatedTo(NavigationParameters parameters)
        {
            Xamarin.Forms.Device.BeginInvokeOnMainThread(async () =>
            {
                latitude = parameters["lat"].ToString();  // if the phone inst near latitude "55,7070631" and longitude "12,4235393" then remove the part where it gets data from parameters
                longitude = parameters["lon"].ToString();  // and use the two lines under this
                                                           //latitude = "55,7070631";
                                                           //longitude = "12,4235393";
                var ggg = await CallService(new MobileService.Toemning { Latitude = latitude, Longitude = longitude, date = new DateTime(2016, 11, 1) });  // the date is set to a day where there is data
                var justatest = 0;
                ToemmeListe.Clear();
                foreach (var toemming in ggg)
                {

                    ToemningData _ToemningData = new ToemningData();
                    _ToemningData.Fraktion = toemming.Fraktion;
                    _ToemningData.ToemmeID = toemming.ToemmeId;
                    _ToemningData.Type = toemming.Type;
                    _ToemningData.Vaegt = toemming.Weight;
                    ToemmeListe.Add(_ToemningData);
                }

            });

        }

        MobileService.Toemning ToWCFServiceTodoItem(MobileService.Toemning item)
        {
            return new MobileService.Toemning
            {
                Fraktion = item.Fraktion,
                ToemmeId = item.ToemmeId,
                Type = item.Type,
                date = item.date,
                Latitude = item.Latitude,
                Longitude = item.Longitude,
                Weight = item.Weight
            };
        }


        public async Task<ObservableCollection<MobileService.Toemning>> CallService(MobileService.Toemning item)
        {
            var todoItem = ToWCFServiceTodoItem(item);
            MobileService.VaksServiceClient client = new MobileService.VaksServiceClient(new BasicHttpBinding(), new EndpointAddress("http://vf-kssweb2/Vaks2Svc/VaksService.svc?singleWsdl"));
            var t = Task<ObservableCollection<MobileService.Toemning>>.Factory.FromAsync(
                    ((MobileService.IVaksService)client.InnerChannel).BeginGetToemmeDatas,
                    ((MobileService.IVaksService)client.InnerChannel).EndGetToemmeDatas,
                     todoItem, TaskCreationOptions.None);
            return await t;
        }

        public void SetRowData()
        {

            try
            {
                toemmeListe = new ObservableCollection<ToemningData>();
            }
            catch (Exception ex)
            {

                throw;
            }

            ToemningData _ToemningData = new ToemningData();
            _ToemningData.Fraktion = "Igen Data";
            _ToemningData.ToemmeID = -1;
            _ToemningData.Type = "Igen Data";
            _ToemningData.Vaegt = "Igen Data";
            ToemmeListe.Add(_ToemningData);
        }

        private ObservableCollection<ToemningData> toemmeListe;

        public ObservableCollection<ToemningData> ToemmeListe
        {
            get { return toemmeListe; }
            set { this.toemmeListe = value; }
        }




    }
}

You're not allowed to change an ObservableCollection from any thread but the one that created it (normally the UI thread). 不允许从任何线程更改ObservableCollection ,但只能从创建线程的线程中更改(通常是UI线程)。 You have to marshall the Add operations back to that thread, preferably using async / await : 您必须将Add操作编组回该线程,最好使用async / await

private async Task FillList()
{
    // on the ui thread here...

    // leaving it to wait for i/o operations or cpu-bound work on a threadpool thread
    var data = await _server.FetchData();

    // here we are back on the ui thread and update the list
    foreach (var item in data)
        TransformItemAndAddItToTheList( item );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM