這個解決方案可能會看起來過於複雜的情況下,但它是我用來溝通模態行動之間的隨機解決依賴關係(沒有帳戶目前,ID缺失,在此期間刪除數據等),而不會丟失類型安全。
一種思考嚮導/模態系列的方法是,下一頁取決於以前的內容,而且大多數情況下你會想要使用你的模態結果。
我希望這有助於:
public static class ModalManager
{
public static bool TryRespondModal<TData>(this IModalResponse<TData> source, TData data, bool autoPop = true, bool animate = false)
{
if (Application.Current.MainPage.Navigation.ModalStack.Count <= 0)
return false;
source.ModalRequestComplete.SetResult(data);
if (autoPop)
Application.Current.MainPage.Navigation.PopModalAsync(animate);
return true;
}
public static Task<TData> GetResponseAsync<TData>(this IModalResponse<TData> source)
{
source.ModalRequestComplete = new TaskCompletionSource<TData>();
return source.ModalRequestComplete.Task;
}
}
public enum WizardState
{
Indeterminate = 0,
Complete = 1,
Canceled = 2
}
public class WizardModel
{
public WizardState State { get; set; }
public List<string> Page1Values { get; set; } = new List<string>();
public List<string> Page2Values { get; set; } = new List<string>();
public List<string> Page3Values { get; set; } = new List<string>();
}
public abstract class WizardPage : IModalResponse<WizardModel>
{
public WizardModel Model { get; set; }
public ICommand NextCommand { get; set; }
public ICommand PreviousCommand { get; set; }
public ICommand CancelCommand { get; set; }
protected WizardPage(WizardModel model)
{
Model = model;
NextCommand = new Command(NextButtonPressed);
PreviousCommand = new Command(PreviousButtonPressed);
CancelCommand = new Command(PreviousButtonPressed);
}
protected abstract IModalResponse<WizardModel> GetNextPage();
protected virtual void CancelButtonPressed()
{
Model.State = WizardState.Canceled;
this.TryRespondModal(Model);
}
protected virtual void PreviousButtonPressed()
{
// you're dropping down on the level of dependent windows here so you can tell your previous modal window the result of the current response
this.TryRespondModal(Model);
}
protected virtual async void NextButtonPressed()
{
var np = GetNextPage();
if (Model.State == WizardState.Complete || np == null || (await np?.GetResponseAsync()).State == WizardState.Complete)
PersistWizardPage();
// all following modal windows must have run through - so you persist whatever your page has done, unless you do that on the last page anyway. and then tell the previous
// modal window that you're done
this.TryRespondModal(Model);
}
protected virtual void PersistWizardPage()
{
// virtual because i'm lazy
throw new NotImplementedException();
}
public TaskCompletionSource<WizardModel> ModalRequestComplete { get; set; }
}
public class Page1 : WizardPage
{
public Page1(WizardModel model) : base(model)
{
}
protected override IModalResponse<WizardModel> GetNextPage()
{
return new Page2(Model);
}
}
public class Page2 : WizardPage
{
public Page2(WizardModel model) : base(model)
{
}
protected override IModalResponse<WizardModel> GetNextPage()
{
return new Page3(Model);
}
}
public class Page3 : WizardPage
{
public Page3(WizardModel model) : base(model)
{
}
protected override IModalResponse<WizardModel> GetNextPage()
{
return null;
}
protected override void NextButtonPressed()
{
this.Model.State = WizardState.Complete;
base.NextButtonPressed();
}
}
public interface IModalResponse<TResponseType>
{
TaskCompletionSource<TResponseType> ModalRequestComplete { get; set; }
}
來源
2016-04-28 13:18:45
Dbl
我今天已經有同樣的問題。工作在我想出的答案 – Dbl