我尝试使用从OnNavigatedTo获取的参数将数据从Web服务加载到sfDataGrid
首先它将一个虚拟行加载到网格中,因为我无法获取数据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
<?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>
从Web服务获取数据后进入Ws_GetToemmeDatasCompleted时,它停在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,prism v6.2.0 Xam.Plugin.Geolocator v3.0.4和Syncfusion 主要在Android版6.0.1和使用的sony xperia z3上运行它 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 :(得分:0)
您不允许从任何线程更改ObservableCollection
,而是创建它的线程(通常是UI线程)。您必须将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 );
}