如何将此DataTemplate移动到一个单独的XAML文件并保持命令在.NET MAUI上工作?

68bkxrlz  于 2023-05-11  发布在  .NET
关注(0)|答案(1)|浏览(138)

我目前在.NET MAUI应用程序中有一个带有Syncfusion控件的页面,这是XAML:

<ContentPage
    x:Class="MyProject.SchedulePage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:schedule="clr-namespace:Syncfusion.Maui.Scheduler;assembly=Syncfusion.Maui.Scheduler"
    x:Name="schedulePage"
    Title="Agenda"
    Shell.FlyoutBehavior="Disabled"
    Shell.NavBarIsVisible="{OnPlatform iOS='True',
                                       Default='False'}">
    <ContentPage.Resources>
        <DataTemplate x:Key="AppointmentTemplate">
            <StackLayout Background="MediumPurple">
                <Label
                    FontFamily="Bold"
                    HorizontalOptions="CenterAndExpand"
                    Text="{Binding Subject}"
                    TextColor="White"
                    VerticalOptions="CenterAndExpand" />
                <StackLayout.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding Path=BindingContext.AppointmentTappedCommand, Source={Reference professionalScheduler}}" CommandParameter="{Binding .}" />
                </StackLayout.GestureRecognizers>
            </StackLayout>
        </DataTemplate>
    </ContentPage.Resources>
    <StackLayout>
        <schedule:SfScheduler
            x:Name="professionalScheduler"
            AllowViewNavigation="True"
            AppointmentsSource="{Binding Events}"
            DisplayDate="{Binding DisplayDate}"
            ShowNavigationArrows="False"
            ShowWeekNumber="False"
            VerticalOptions="FillAndExpand"
            View="Day">
            <schedule:SfScheduler.DaysView>
                <schedule:SchedulerDaysView
                    AppointmentTemplate="{StaticResource AppointmentTemplate}"
                    EndHour="22"
                    MinimumAppointmentDuration="0:30:0"
                    StartHour="8"
                    TimeFormat="HH:mm"
                    TimeRegions="{Binding Regions}" />
            </schedule:SfScheduler.DaysView>
        </schedule:SfScheduler>
    </StackLayout>
</ContentPage>

这是我的ViewModel:

namespace MyProject.ViewModels
{
    public class ScheduleViewModel : BaseViewModel
    {
        public ObservableCollection<SchedulerAppointment> Events { get; set; } = new ObservableCollection<SchedulerAppointment>();

        public ICommand AppointmentTappedCommand { get; }

        public ScheduleViewModel(IAppointmentsService bookingsService)
        {
            AppointmentTappedCommand = new Command<SchedulerAppointment>(async (appointment) => await OnAppointmentTappedCommand(appointment));
        }

        private async Task OnAppointmentTappedCommand(SchedulerAppointment appointment)
        {
            await Shell.Current.DisplayAlert("Appointment", $"{appointment.Id} - {appointment.Subject} - {appointment.StartTime} - {appointment.EndTime}", "OK");
        }
    }
}

当我点击调度器上的一个项目时,我会触发ViewModel上的AppointmentTappedCommand,并看到DisplayAlert
但是,当我尝试将DataTemplate移动到另一个模板保持工作的文件时,Subject仍然正确地绑定到Data Context,但我的AppointmentTappedCommand停止工作。这是带有DataTemplate的XAML文件:

<ContentView
    x:Class="MyProject.Templates.Scheduler.AppointmentTemplate"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="appointmentTemplate">
    <StackLayout Background="MediumPurple">
        <Label
            FontFamily="Bold"
            HorizontalOptions="CenterAndExpand"
            Text="{Binding Subject}"
            TextColor="White"
            VerticalOptions="CenterAndExpand" />
        <StackLayout.GestureRecognizers>
            <TapGestureRecognizer Command="{Binding Path=BindingContext.AppointmentTappedCommand, Source={Reference professionalScheduler}}" CommandParameter="{Binding .}" />
        </StackLayout.GestureRecognizers>
    </StackLayout>
</ContentView>

即使模板在另一个文件中,如何保持命令工作?

bbmckpt7

bbmckpt71#

我们建议您使用Tapped事件来实现您的要求,而不是示例中的TapGestureRecognizer。请参考以下步骤“如何在SfScheduler中使用Tapped事件命令”。
第一步:安装Community.Toolkit.Maui并在MauiProgram.cs中添加UseMauiCommunityToolkit

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder.ConfigureSyncfusionCore();
    builder.UseMauiApp<App>().UseMauiCommunityToolkit();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        });

    return builder.Build();
}

步骤2:在视图模型中添加命令

public ICommand AppointmentTappedCommand { get; set; }

public SchedulerViewModel()
{
    this.GenerateAppointments();
    this.DisplayDate = DateTime.Now.Date.AddHours(8).AddMinutes(50);
    AppointmentTappedCommand = new Command<SchedulerTappedEventArgs>(async (appointment) => await OnAppointmentTappedCommand(appointment));
}

private async Task OnAppointmentTappedCommand(SchedulerTappedEventArgs obj)
{
    if (obj != null && obj.Element == SchedulerElement.Appointment && obj.Appointments[0] is SchedulerAppointment appointment)
    {
        await Shell.Current.DisplayAlert("Appointment", $"{appointment.Id} - {appointment.Subject} - {appointment.StartTime} - {appointment.EndTime}", "OK");
    }
}

步骤3:在MainPage.xaml中

<scheduler:SfScheduler x:Name="Scheduler" 
                View="Week"
                DisplayDate="{Binding DisplayDate}"
                AppointmentsSource="{Binding Events}"
                AllowedViews="Day,Week,WorkWeek,Month,TimelineDay,TimelineWeek,TimelineWorkWeek,TimelineMonth">
    <scheduler:SfScheduler.DaysView>
        <scheduler:SchedulerDaysView>
        <scheduler:SchedulerDaysView.AppointmentTemplate>
            <DataTemplate>
                    <local:AppointmentTemplate/>
            </DataTemplate>
        </scheduler:SchedulerDaysView.AppointmentTemplate>
    </scheduler:SchedulerDaysView>
</scheduler:SfScheduler.DaysView>
    <scheduler:SfScheduler.Behaviors>
        <toolkit:EventToCommandBehavior
    EventName="Tapped"
    Command="{Binding AppointmentTappedCommand}" />
    </scheduler:SfScheduler.Behaviors>
</scheduler:SfScheduler>

如果您有任何疑问,请告诉我们。

相关问题