如何修复“只有创建视图层次结构的原始线程可以触摸其视图” Xamarin形式在Android上
我正在建立一个带有Xamarin表格的应用程序,但仅在Android上。 当我运行应用程序时,我会收到此错误:“只有创建视图层次结构的原始线程可以触摸其视图”。我的应用程序中有类似的页面,但这是我第一次收到此错误。我知道这是关于UI线程的东西,但我无法弄清楚在哪里使用错误的线程。
这是错误来自的代码:
-ViewModel
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinApp.Services;
using XamarinApp.Views.Month;
namespace XamarinApp.ViewModels.Month
{
public class HistoryViewModel : BaseViewModel
{
private readonly IMonthService _monthService;
private ObservableCollection<int> years;
private ObservableCollection<int> months;
public int year;
public int month;
public HistoryViewModel(IMonthService monthService)
{
_monthService = monthService;
Years = new ObservableCollection<int>();
Months = new ObservableCollection<int>();
Title= "History";
FindCommand = new Command(async () => await GoToYearHistory());
}
private async Task GoToYearHistory()
{
if (year == 0)
return;
await Shell.Current.GoToAsync($"{nameof(YearHistoryPage)}?{nameof(YearHistoryViewModel.Year)}={year}");
}
public async void GetYearsAndMonths()
{
Years.Clear();
Months.Clear();
var years = await _monthService.GetYears().ConfigureAwait(false);
foreach (var year in years)
{
Years.Add(year);
}
for (int i = 0; i < 12; i++)
{
Months.Add(i+1);
}
}
public ObservableCollection<int> Years
{
get => years;
set
{
years = value;
OnPropertyChanged(nameof(Years));
}
}
public ObservableCollection<int> Months
{
get => months;
set
{
months = value;
OnPropertyChanged(nameof(Months));
}
}
public int Year
{
get => year;
set
{
year = value;
OnPropertyChanged(nameof(Year));
}
}
public int Month
{
get => month;
set
{
month = value;
OnPropertyChanged(nameof(Month));
}
}
public ICommand FindCommand { get; }
}
}
------ 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:month="clr-namespace:XamarinApp.ViewModels.Month" x:DataType="month:HistoryViewModel"
x:Class="XamarinApp.Views.Month.HistoryPage"
BackgroundColor="{StaticResource BackgroundColor}">
<ContentPage.Content>
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="History"
FontSize="Title"
TextColor="{StaticResource Primary}"
FontAttributes="Bold"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
<StackLayout Orientation="Horizontal">
<Picker Title="Select Year" ItemsSource="{Binding Years}"
SelectedItem="{Binding Year}" HorizontalOptions="FillAndExpand"/>
<Picker Title="Select Month" ItemsSource="{Binding Months}"
SelectedItem="{Binding Month}" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<Button Text="Find" Command="{Binding FindCommand}" Margin="20,40,20,0" CornerRadius="10" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
---------------------------------------------------------------------------
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XamarinApp.ViewModels.Month;
namespace XamarinApp.Views.Month
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HistoryPage : ContentPage
{
private readonly HistoryViewModel _historyViewModel;
public HistoryPage()
{
InitializeComponent();
_historyViewModel = Startup.Resolve<HistoryViewModel>();
BindingContext = _historyViewModel;
}
protected override void OnAppearing()
{
Device.BeginInvokeOnMainThread(() =>
{
_historyViewModel?.GetYearsAndMonths();
});
}
}
}
I'm building an app with Xamarin Forms, but only on android.
When I run the app I get this error "Only the original thread that created a view hierarchy can touch its views". I have similar pages in my app, but this is the first time I've received this error. I know that is something about the UI thread but I can't figure out where exacly I'm using the wrong thread.
This is the code where the error comes from:
--ViewModel--
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using XamarinApp.Services;
using XamarinApp.Views.Month;
namespace XamarinApp.ViewModels.Month
{
public class HistoryViewModel : BaseViewModel
{
private readonly IMonthService _monthService;
private ObservableCollection<int> years;
private ObservableCollection<int> months;
public int year;
public int month;
public HistoryViewModel(IMonthService monthService)
{
_monthService = monthService;
Years = new ObservableCollection<int>();
Months = new ObservableCollection<int>();
Title= "History";
FindCommand = new Command(async () => await GoToYearHistory());
}
private async Task GoToYearHistory()
{
if (year == 0)
return;
await Shell.Current.GoToAsync(quot;{nameof(YearHistoryPage)}?{nameof(YearHistoryViewModel.Year)}={year}");
}
public async void GetYearsAndMonths()
{
Years.Clear();
Months.Clear();
var years = await _monthService.GetYears().ConfigureAwait(false);
foreach (var year in years)
{
Years.Add(year);
}
for (int i = 0; i < 12; i++)
{
Months.Add(i+1);
}
}
public ObservableCollection<int> Years
{
get => years;
set
{
years = value;
OnPropertyChanged(nameof(Years));
}
}
public ObservableCollection<int> Months
{
get => months;
set
{
months = value;
OnPropertyChanged(nameof(Months));
}
}
public int Year
{
get => year;
set
{
year = value;
OnPropertyChanged(nameof(Year));
}
}
public int Month
{
get => month;
set
{
month = value;
OnPropertyChanged(nameof(Month));
}
}
public ICommand FindCommand { get; }
}
}
---Xaml file---
<?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:month="clr-namespace:XamarinApp.ViewModels.Month" x:DataType="month:HistoryViewModel"
x:Class="XamarinApp.Views.Month.HistoryPage"
BackgroundColor="{StaticResource BackgroundColor}">
<ContentPage.Content>
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="History"
FontSize="Title"
TextColor="{StaticResource Primary}"
FontAttributes="Bold"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
<StackLayout Orientation="Horizontal">
<Picker Title="Select Year" ItemsSource="{Binding Years}"
SelectedItem="{Binding Year}" HorizontalOptions="FillAndExpand"/>
<Picker Title="Select Month" ItemsSource="{Binding Months}"
SelectedItem="{Binding Month}" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<Button Text="Find" Command="{Binding FindCommand}" Margin="20,40,20,0" CornerRadius="10" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
---Xaml.cs file---
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using XamarinApp.ViewModels.Month;
namespace XamarinApp.Views.Month
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HistoryPage : ContentPage
{
private readonly HistoryViewModel _historyViewModel;
public HistoryPage()
{
InitializeComponent();
_historyViewModel = Startup.Resolve<HistoryViewModel>();
BindingContext = _historyViewModel;
}
protected override void OnAppearing()
{
Device.BeginInvokeOnMainThread(() =>
{
_historyViewModel?.GetYearsAndMonths();
});
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,我通过从此行中删除 configureawait(false)来解决问题。 false)使我无法保持UI线程。
So I fixed the problem by removing ConfigureAwait(false) from this line "var years = await _monthService.GetYears().ConfigureAwait(false)" because ConfigureAwait(false) kept me from staying on the UI thread.