xamarin 如何使用查询属性将TimeSpan数据从一个XAML页传递到另一个XAML页?

zdwk9cvp  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(115)

也许对你们中的一些人来说,这可能是基本问题,但我真的不知道如何解决System.InvalidCastException:'Invalid cast from ' System.String ' to ' System.TimeSpan '。
我有两个XAML页面,我需要将TimeSpan参数从一个页面传递到另一个页面(这样我就可以在另一个页面上使用TimePicker)。
第一个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"
             x:Class="TestApp2.Views.DateTimePage"
              xmlns:viewmodels="clr-namespace:TestApp2.ViewModels" 
                    xmlns:local="clr-namespace:TestApp2.ViewModels"  
                    xmlns:model="clr-namespace:TestApp2.Models" 
             x:DataType="viewmodels:DateTimePageViewModel"
             Title="DateTimePage"
             >
        <ContentPage.Content>
        <StackLayout>
            <Label Text="Tap">
                <Label.GestureRecognizers>
                    <TapGestureRecognizer
                        NumberOfTapsRequired="2"
                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:DateTimePageViewModel}}, Path=TimePickerTapped}"        
                        CommandParameter="{Binding .}">
                    </TapGestureRecognizer>
                </Label.GestureRecognizers>
            
        </Label>

            <TimePicker x:Name="timeFromTimePicker" Time="{Binding Time, Mode=TwoWay}" />

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

namespace TestApp2.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DateTimePage : ContentPage
    {
        public DateTimePage()
        {
            InitializeComponent();
            BindingContext = new DateTimePageViewModel();
        }
    }
}

第一页后面的ViewModel:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Text;
using TestApp2.Views;
using Xamarin.Forms;

namespace TestApp2.ViewModels
{
    public class DateTimePageViewModel: BaseViewModel, INotifyPropertyChanged
    {
        public Command TimePickerTapped { get; }
        

        private TimeSpan time;
        public TimeSpan Time
        {
            get => time;
            
            set
            {
                time = value;
                OnPropertyChanged();
            }
        }

        public DateTimePageViewModel()
        {
            TimePickerTapped = new Command(OnTimePickerSelected);
            time = new TimeSpan(17, 0, 0);
        }

        async void OnTimePickerSelected()
        {
            if (time != null)
            {
                await Shell.Current.GoToAsync($"{nameof(TransferDateTimePage)}?" +
                    $"{nameof(TransferDateTimePageViewModel.Time)}={Time}");
            }
        }
    }
}

第二个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"
             x:Class="TestApp2.Views.TransferDateTimePage"
                    xmlns:viewmodels="clr-namespace:TestApp2.ViewModels" 
                    xmlns:local="clr-namespace:TestApp2.ViewModels"  
                    xmlns:model="clr-namespace:TestApp2.Models" 
             x:DataType="viewmodels:TransferDateTimePageViewModel"
             >
        <ContentPage.Content>
        <StackLayout>
            <TimePicker x:Name="timeFromTimePicker" Time="{Binding Time, Mode=TwoWay}" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

namespace TestApp2.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TransferDateTimePage : ContentPage
    {
        public TransferDateTimePage()
        {
            InitializeComponent();
            BindingContext = new TransferDateTimePageViewModel();
        }
    }
}

第二页后面的视图模型是:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Xamarin.Forms;

namespace TestApp2.ViewModels
{

        [QueryProperty(nameof(Time), nameof(Time))]
        public class TransferDateTimePageViewModel : BaseViewModel, INotifyPropertyChanged      //, IQueryAttributable
        {
            private TimeSpan time;
            public TimeSpan Time
            {
                get => time;
                set
                {
                    time = value;
                    OnPropertyChanged();
                }
            }

            public TransferDateTimePageViewModel()
            {

            }
       }
   }

我认为这个错误与

await Shell.Current.GoToAsync($"{nameof(TransferDateTimePage)}?" +
                $"{nameof(TransferDateTimePageViewModel.Time)}={Time}"); 

ViewModel behind first page code

并将参数传递给第二页:

[QueryProperty(nameof(Time), nameof(Time))]

我真的不知道如何解决这个问题。我试着在互联网上广泛搜索了几天,但到目前为止我无法解决这个问题。
我需要用户能够在第二页上编辑第一次出现的时间。
有帮助吗?谢谢。

gfttwv5a

gfttwv5a1#

从文档中

原语数据可以作为字符串查询参数传递
primitive通常表示简单的值类型,而不是像TimeSpan这样的复杂对象

要传递对象,请使用以下语法

var navigationParameter = new Dictionary<string, object>
{
    { "Time", myTimespanObject }
};
await Shell.Current.GoToAsync($"mypage", false, navigationParameter);
wnavrhmk

wnavrhmk2#

在上面Jason的建议的帮助下,我终于找到了解决方案,那就是以这种方式更改第二页的视图模型:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using Xamarin.Forms;

namespace TestApp2.ViewModels
{
    public class TransferDateTimePageViewModel : BaseViewModel, INotifyPropertyChanged, IQueryAttributable        
    {

        public void ApplyQueryAttributes(IDictionary<string, string> query)
        {
            string Time = HttpUtility.UrlDecode(query["MyTime"]);
            LoadMyTime(Time);
        }

        void LoadMyTime(string Time)
        {
            _ = TimeSpan.TryParse(Time, out myTime);
            OnPropertyChanged(nameof(MyTime));
        }

        private TimeSpan myTime;

        public TimeSpan MyTime
           {
            get => myTime;
            set
               {
                   myTime = value;
                   OnPropertyChanged();
               }
           }
     }
}

相关问题