我正在为 Windows、Android 和 iOS 开发跨平台库。
而且我有一个界面方法,用于显示基于一些 ViewModel(带有用于绑定(bind)的数据和命令)和相应 View 的复杂对话框消息。
有一个 Windows 实现:
// view and viewModel is valid at this point
public void Show<TViewModel>(TView view, TViewModel viewModel) where TViewModel : class
{
var window = (Window)view;
window.DataContext = viewModel;
window.ShowDialog();
}
我可以在 Xamarin.Forms 中做同样的事情吗?
我发现了类似的东西:
var activity = Intent(this, typeof(DataPage));
activity.BindingContext = viewModel
this.StartActivity(m_activity);
但这适用于 Xamarin.Android,这不是我需要的。
最佳答案
您需要使用的是 INavigation
来自Xamarin.Forms
的接口(interface)组件。所有 View /页面通过 Navigation
提供属性,并且您希望使用当前显示的属性。
一旦你有了它,你就可以调用PushModalAsync
这需要 Page
的类型但如果你想展示它,我希望你能创造一个。
绑定(bind)
至于Bindings
最终你需要将你的 View 模型分配给你的 View BindingContext
我的 View 有一个基类,类似于以下内容:
public abstract class ViewBase : ContentPage
{
protected ViewModelBase viewModel;
internal ViewModelBase ViewModel
{
get
{
return this.viewModel;
}
set
{
if (this.viewModel != value)
{
this.viewModel = value;
// Make sure we bind the view model to the UI.
this.BindingContext = value;
}
}
}
}
更多想法
这可能超出了这个问题的要求,但是我已经完成了
Page
的显示。就像您要求的以下实现:internal async Task<U> ShowAsync<T, U>(IDictionary<string, object> arguments = null, bool animated = true) where T : IDialogView where U : IDialogResult
{
var completionSource = new TaskCompletionSource<U>();
try
{
var page = (IDialogView)Activator.CreateInstance<T>();
// Hook up event handlers so when either the Complete/Error is fired then we dismiss and pass the result back to the caller.
page.ResultChanged += (sender, e) =>
{
// Hide the modal view.
this.DismissAsync();
// Do we need to perform a safety check when converting?
completionSource.SetResult((U)e.Value);
};
// Pass in any arguments to the view.
page.SetArguments(arguments);
// Display the view and wait.
await this.navigation.PushModalAsync((Page)page, animated);
// Return the result of the view.
return await completionSource.Task;
}
catch (Exception ex)
{
LogService.Error($"Unable to ShowAsync for view: {typeof(T).Name}", ex);
completionSource.SetException(ex);
}
return default(U);
}
internal interface IDialogView
{
event EventHandler<EventArgs<IDialogResult>> ResultChanged;
void SetArguments(IDictionary<string, object> arguments);
}
internal interface IDialogResult
{
}
虽然这看起来确实使初始设置复杂化,但这意味着您可以简单地调用:
var result = await ShowAsync<MyView, MyViewResult>();
最大的好处是它允许您显示新页面并等待它需要执行的任何操作并利用该操作的结果。请注意,您不需要处理对话框显示的结果,然后可以用简单的 bool 值替换 U 逻辑。
关于c# - 将 View 绑定(bind)到 View 模型并在 Xamarin.Forms 中显示为对话框页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51594884/