【问题标题】:Passing data between view in xamarin forms using mvvm使用 mvvm 在 xamarin 表单中的视图之间传递数据
【发布时间】:2018-06-01 01:55:15
【问题描述】:

我正在尝试在页面之间导航并同时绑定数据。

这是我尝试过的:

public ICommand GetIdeasCommand
{
    get
    {
        return new Command(async () =>
        {
            Ideas = await _apiServices.GetIdeasAsync();
            await Application.Current.MainPage.Navigation.PushAsync(new IdeasSinglePage(Ideas));
        });
    }
}

Ideas 应该是我从 json 获得的数组列表。但是这种方法对我没有帮助,因为我得到了一个空白页。此外,如果我在页面内调用此函数,一切都很好。 这篇文章给了我一个想法:How to pass a parameter from one Page to another Page in Xamarin.Forms?

我的看法:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Ideas.Pages.IdeasSinglePage"
         xmlns:vm="clr-namespace:Ideas.ViewModel;assembly=Ideas"
          Title="My Page">

<ContentPage.BindingContext>
    <vm:IdeasViewModel/>
</ContentPage.BindingContext>

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="20, 10">
                        <Label Text="{Binding Ideas}"
                               FontSize="12"
                               TextColor="RoyalBlue"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

后面的代码:

public partial class IdeasSinglePage : ContentPage
{
    public IdeasSinglePage(List<Models.Ideas> ideas)
    {

      InitializeComponent();
      this.BindingContext = new IdeasSinglePage(ideas); //the app breaks here
    }
}

谢谢。

【问题讨论】:

  • 预期输出是什么? 'IdeasSinglePage' 上有控件吗?
  • 我希望视图中填充我从 ` Ideas = await _apiServices.GetIdeasAsync();` @EvZ 获得的信息
  • 请分享您的 IdeasSinglePage 代码隐藏和 XAML(如果存在)。 @阿尔多
  • 你可以看看我的编辑@EvZ
  • 很遗憾,这还不够,您的 IdeasSinglePage 背后的代码在哪里?你如何处理通过的列表?

标签: c# xamarin mvvm binding xamarin.forms


【解决方案1】:

您的问题很明显,您正在将数据传递给 ContentPage 但您对它什么也不做。一般来说,将参数从一个ViewModel 传递到另一个ViewModel 是一个非常简单的问题。

这是一个没有XAML的插图:

public class MyFirstPage : ContentPage
{
  public MyFirstPage()
  {
    this.BindingContext = new MyFirstPageViewModel();
  }
}

public class MyFirstPageViewModel : INotifyPorpertyChanged
{
  public ICommand<List<string>> DownloadDataCmd { get; }

  public MyFirstPageViewModel()
  {
    DownloadDataCmd = new Command<List<string>>(async () => {
        var data = await dataService.DownloadData();
        await navService.PushAsync(new MySecondPage(data));
    });
  }
}

public class MySecondPage : ContentPage
{
  public MySecondPage(List<string> downloadedData)
  {
    this.BindingContext = new MySecondPageViewModel(downloadedData);
  }
}

public class MySecondPageViewModel : INotifyPropertyChanged
{
  public List<string> Data { get; }
  public MySecondPageViewModel(List<string> downloadedData)
  {
     // Do whatever is needed with the data
     Data = downloadedData;
  }
}

现在,看看这个解决方案有几个问题:
1. 为什么不直接在第二页下载数据呢?
2. 如果您在整个应用程序中需要数据,为什么不将数据存储在缓存或数据库中?

【讨论】:

    【解决方案2】:

    您对 BindingContext 的理解不足。通常你将一个 ViewModel 绑定到一个 BindingContext。你在这里做什么

    this.BindingContext = new IdeasSinglePage(ideas); //the app breaks here

    没有意义。

    您将要加载的页面作为上下文传递?完全删除这一行。由于在您最近的 cmets 中您说您不想以 ViewModel 开头,因此您将在 CodeBehind 中执行以下操作:

    public partial class IdeasSinglePage : ContentPage
    {
      public IdeasSinglePage(List<Models.Ideas> ideas)
      {
        InitializeComponent();
        listViewName.ItemsSource = ideas;
      }
    }
    

    在你的 xml 中你给你的 listView 一个名字。您需要此名称来引用后面的代码列表。

    希望对你有帮助

    【讨论】:

    • 你是完全正确的@greggz。谢谢你的解释,真的很感激:)。
    • @Aldo Np 和快乐编码 ;)
    猜你喜欢
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多