如何修复“只有创建视图层次结构的原始线程可以触摸其视图” Xamarin形式在Android上

发布于 2025-01-23 10:44:11 字数 5026 浏览 0 评论 0原文

我正在建立一个带有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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

超可爱的懒熊 2025-01-30 10:44:11

因此,我通过从此行中删除 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文