我正在使用 Shell 構建一個 Xamarin Forms 應用程式,我沒有在其中構建典型的彈出視窗。我為頁眉、頁腳和內容分別創建了一個模板。內容包含從資料庫中獲取的資料。
我在我的 app.xaml 檔案中定義這些。
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="FlyoutFooterTemplate" Value="{DataTemplate common:FlyoutFooterTemplate}"/>
<Setter Property="FlyoutHeaderTemplate" Value="{DataTemplate common:FlyoutHeaderTemplate}"/>
<Setter Property="FlyoutContentTemplate" Value="{DataTemplate common:FlyoutContentTemplate}"/>
</Style>
我已將 FlyoutContentTemplate 創建為 RefreshView。
<?xml version="1.0" encoding="utf-8" ?>
<RefreshView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:InFlight.ViewModels.Common"
xmlns:model="clr-namespace:InFlight.Core.Models;assembly=InFlight.Core"
x:Class="InFlight.Views.Common.FlyoutContentTemplate"
x:DataType="local:FlyoutContentTemplateViewModel"
Command="{Binding LoadFlightsCommand}"
IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<CollectionView
ItemsSource="{Binding Flights}"
SelectionMode="None">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10" x:DataType="model:Flight">
<Label Text="{Binding CallSign}"
LineBreakMode="NoWrap"
Style="{StaticResource LabelMedium}" />
<Label Text="{Binding FlightNotes}"
LineBreakMode="NoWrap"
Style="{StaticResource LabelSmall}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.Footer>
<Button Command="{Binding AddFlightCommand}" Text="Add Flight" />
</CollectionView.Footer>
</CollectionView>
</RefreshView>
后面的代碼只是設定了 BindingContext。
using InFlight.ViewModels.Common;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace InFlight.Views.Common
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FlyoutContentTemplate : RefreshView
{
readonly FlyoutContentTemplateViewModel viewModel;
public FlyoutContentTemplate()
{
InitializeComponent();
this.BindingContext = viewModel = new FlyoutContentTemplateViewModel();
}
}
}
視圖模型相當簡單,它處理由 RefreshView 觸發的 LoadFlightsCommand 和到 AddEditFlightPage 的導航。
using InFlight.Core.Models;
using InFlight.Core.Respositories;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace InFlight.ViewModels.Common
{
public class FlyoutContentTemplateViewModel : BaseViewModel
{
public ObservableCollection<Flight> Flights { get; set; }
public Command LoadFlightsCommand { get; }
public Command AddFlightCommand { get; }
readonly IFlightRepository flightRepository;
public FlyoutContentTemplateViewModel()
{
flightRepository = DependencyService.Get<IFlightRepository>();
Flights = new ObservableCollection<Flight>();
LoadFlightsCommand = new Command(ExecuteLoadFlightsCommand);
AddFlightCommand = new Command(async () => await OnAddFlightCommand());
ExecuteLoadFlightsCommand();
}
private async Task OnAddFlightCommand()
{
await Shell.Current.GoToAsync("AddEditFlightPage");
Shell.Current.FlyoutIsPresented = false;
}
private void ExecuteLoadFlightsCommand()
{
IsBusy = true;
try
{
Flights.Clear();
var flts = flightRepository.GetFlights();
foreach (var flight in flts)
{
Flights.Add(flight);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
}
這一切似乎運作良好,但目前我需要拉動重繪 以觸發LoadFlightsCommand.
The issue is that I want to trigger the data refresh when navigating back from my add page. I've seen posts where people tap into the OnAppearing event in order to trigger the refresh, but as I am using a template and refresh view, I don't see how I can do that.
Have I maybe taken the wrong approach and using Shell for a purpose it shouldn't be used for?
I'm thinking that the solution probably involves the events of the shell itself?
Any advice would be much appreciated.
uj5u.com熱心網友回復:
第一種方法
我不知道你如何定義你的路線/導航的全貌Shell,但我相信你想要實作的目標可以使用 Shell 事件OnNavigated或OnNavigating.
- 首先,Shell (AppShell.xaml.cs) 需要訪問您的
FlyoutContentTemplateViewModelin roder 的實體才能從那里呼叫該方法ExecuteLoadFlightsCommand()。 - 將可訪問性
ExecuteLoadFlightsCommand()公開。
AppShell.xaml.cs
public FlyoutContentTemplateViewModel flyoutContentTemplateViewModel;
public AppShell()
{
flyoutContentTemplateViewModel = new();
InitializeComponent();
}
protected override void OnNavigated(ShellNavigatedEventArgs args)
{
var previousRouteString = args?.Previous?.Location?.OriginalString;
var currentRouteString = args?.Current?.Location?.OriginalString;
if (previousRouteString != null && previousRouteString.Contains("[DEPENDS ON YOUR ROUTES NAME]") &&
currentRouteString.Contains("[DEPENDS ON YOUR ROUTES NAME]"))
{
flyoutContentTemplate.ExecuteLoadFlightsCommand();
}
base.OnNavigated(args);
}
在您的FlyoutContentTemplate()中,使用我們在 AppShell 中添加的欄位中的相同 ViewModel 實體。
public FlyoutContentTemplate()
{
InitializeComponent();
BindingContext = viewModel = (Shell.Current as AppShell).flyoutContentTemplateViewModel;
}
第二種方法
如果您不想將 VM 存盤在 AppShell 中,則可以使用DependencyService。
- 從你的界面中提取一個介面
FlyoutContentTemplateViewModel:在visual studio上選擇類名,右鍵單擊,在選單中單擊“快速操作和重構”,然后單擊“提取介面”,VS將生成一個名為IFlyoutContentTemplateViewModel:
public interface IFlyoutContentTemplateViewModel
{
Command AddFlightCommand { get; }
ObservableCollection<Flight> Flights { get; set; }
bool IsBusy { get; }
Command LoadFlightsCommand { get; }
Task OnAddFlightCommand()
void ExecuteLoadFlightsCommand();
}
- FlyoutContentTemplate.xaml.cs
public FlyoutContentTemplate()
{
InitializeComponent();
BindingContext = viewModel = new FlyoutContentTemplateViewModel();
DependencyService.RegisterSingleton<IFlyoutContentTemplateViewModel>(viewModel);
}
- AppShell.xaml.cs
...
if (previousRouteString != null && previousRouteString.Contains("[DEPENDS ON YOUR ROUTES NAME]") &&
currentRouteString.Contains("[DEPENDS ON YOUR ROUTES NAME]"))
{
DependencyService.Resolve<IFlyoutContentTemplateViewModel>()?.ExecuteLoadFlightsCommand();
}
第三種方法
Calling ExecuteLoadFlightsCommand() from OnDisappearing() of AddEditFlightPage, instead of AppShell.OnNavigated().
AddEditFlightPage.xaml.cs
protected override void OnDisappearing()
{
(DependencyService.Resolve<IFlyoutContentTemplateViewModel>())?.ExecuteLoadFlightsCommand();
base.OnDisappearing();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/436753.html
