2016-11-08 5 views
2

им пытаются загрузить данные с веба-сервиса в sfDataGrid с использованием параметров я получаю от OnNavigatedToнеобработанного исключения произошло при обновлении списка ObservableCollection

первого он загружает фиктивную строку в сетку, потому что я не могу получить данные OnNavigatedTo еще тогда он запускает OnNavigatedTo и получает данные из веб-сервиса и Gose в добавление данных в ObservableCollection, что сетка ItemsSource установлено в

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

<?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> 

, когда он попадает в Ws_GetToemmeDatasCompleted после получения данных из web-сервиса, он останавливается в ToemmeListe.Add (_ToemningData); в

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

и говорит необработанное исключение произошло.

Любая помощь глубоко признателен

им с помощью Visual Studio 2015 сообщества, Xamarin, призмы v6.2.0 Xam.Plugin.Geolocator v3.0.4 и Syncfusion в основном работает его на XPERIA z3 сони с Android версии 6.0. 1 и используя API-23

Dropbox link to the full project

решение я пошел с

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




    } 
} 
+0

Что такое необработанное исключение? Проверьте свойство 'InnerException' вашего исключения. – Kilazur

+1

Было бы разумно добавить тип исключения. Можно предположить, что 'Ws_GetToemmeDatasCompleted' вызвал поток gui? Вам может понадобиться 'Dispatcher.Invoke()' –

+0

Я не могу найти больше об исключении, я просто получаю это http://tinypic.com/r/2v3n8g1/9 , а затем у меня есть все остальное, на что я смотрел был пуст после просмотра на выходе я увидел 11-08 12: 51: 18.830 I/Хореограф (14918): Пропустил 78 кадров! Приложение может делать слишком много работы над своей основной нитью. 11-08 12: 51: 24.904 I/Хореограф (14918): пропустил 344 кадра! Приложение может делать слишком много работы над своей основной нитью. Возникло необработанное исключение. я не использовал Dispatcher.Invoke() раньше, но я буду делать сом исследования – Zarp

ответ

0

Вам не разрешено изменять ObservableCollection из любой темы, кроме той, которая его создала (обычно это поток пользовательского интерфейса). Вы должны маршаллизации 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); 
} 
+0

Спасибо Haukinger вы меня в правильном направлении – Zarp

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