c# - 将 View 绑定(bind)到 View 模型并在 Xamarin.Forms 中显示为对话框页面?

标签 c# mvvm xamarin.forms binding

我正在为 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/

相关文章:

azure - 在 Xamarin 中与服务器通信的最佳方式?

ios - Xamarin Forms - 当键盘出现且内容位于 ScrollView 内时,iOS 输入字段不会自动调整位置

C# static - MSDN 上的定义是什么意思?

c# - 我的 ASP.NET DropDownList 无法正常工作

.net - 我应该如何访问 ViewModel 的底层实体/模型

android - 如何从android中的viewmodel调用baseactivity函数

c# - grpc.core 的 Xamarin iOS native 链接失败

c# - 带音乐的幻灯片放映 像 Asp.net 一样控制相册

JavaScript $.each 函数

wpf - 如何强制 ItemContainerGenerator 为项目生成容器或如何在启用 UI 虚拟化时将 TreeView 滚动到展开节点?