使用 CommunityToolkit.Mvvm 绑定 XamarinForms ContentView

问题描述 投票:0回答:1

我有包含 ContentView 推荐的 MainPage。 MainPage 有自己的 ViewModel,与推荐视图相同。在 MainPage 的 OnAppearing 事件中,我需要从RecommendationViewModel 调用InitializeAsync() 方法,以便填充Recommendations ObservableCollection 数据。到目前为止一切都很好,除了我的数据没有显示在 ListView 中。

我正在使用 CommunityToolkit.Mvvm。

这是我的代码:

-- MainPage.xaml.cs

<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:ApeOdds.ViewModels"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:Page.UseSafeArea="True"
    x:Name="Main"
    x:Class="ApeOdds.Views.MainPage">

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

    <ContentPage.Content>
        <controls:RecommendationsView />
    </ContentPage.Content>
</ContentPage>

-- MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    public MainViewModel ViewModel => (MainViewModel)BindingContext;

    public MainPage()
    {
        InitializeComponent();
        BindingContext = Ioc.Default.GetRequiredService<MainViewModel>();
    }

    protected override async void OnAppearing()
    {
        var recomendationVm = Ioc.Default.GetRequiredService<RecommendationViewModel>();
        await recomendationVm.InitializeAsync(); 
        //var recomendations = recomendationVm.Recommendations; -- I have recommendations data here, but they are not displayed
        base.OnAppearing();
    }
}

--MainViewModel.cs

public partial class MainViewModel : ObservableObject
{
    public MainViewModel()
    {
    }
}

——推荐.xaml

<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:ApeOdds.ViewModels"
             x:Class="ApeOdds.Controls.RecommendationsView"
             x:Name="rootView">

    <ContentView.BindingContext>
        <vm:RecommendationViewModel />
    </ContentView.BindingContext>
    <ListView ItemsSource="{Binding Recommendations}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Label Text="{Binding Id}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentView>

——推荐.xaml.cs

public partial class RecommendationsView : ContentView
{
    public RecommendationViewModel ViewModel => (RecommendationViewModel)BindingContext;

     public RecommendationsView()
     {
         InitializeComponent();
         BindingContext = Ioc.Default.GetRequiredService<RecommendationViewModel>();
     }
}

--RecommendationViewModel.cs

public partial class RecommendationViewModel : ObservableObject
{
    public ObservableCollection<Recommendation> Recommendations { get; set; }

    public RecommendationViewModel()
    {
    }

    public async Task InitializeAsync()
    {
        var recommendations = DummyData.CreateDummyRecommendations();
        Recommendations = new ObservableCollection<Recommendation>(recommendations);
        OnPropertyChanged(nameof(Recommendations));
    }
}

-- App.xaml.cs

public partial class App : Application
{

    public App ()
    {
        InitializeComponent();

        Ioc.Default.ConfigureServices(
            new ServiceCollection()
            .AddTransient<BaseViewModel>()
            .AddTransient<MainViewModel>()
            .AddTransient<RecommendationViewModel>()
            .RegisterRefitService()
            .BuildServiceProvider());


        MainPage = new AppShell();
    }

     protected override void OnStart ()
     {
     }

     protected override void OnSleep ()
     {
     }

     protected override void OnResume ()
     {
     }
}
xamarin.forms binding community-toolkit-mvvm xamarin.communitytoolkit
1个回答
0
投票

您可以使用 BindableProperty 来实现此目的。

根据您的代码,我创建了一个演示来实现此功能。我们需要向 ContentView 添加一个 Bindable 属性(

RecommendationsView.xaml.cs
)。

您可以参考以下代码:

RecommendationsView.xaml.cs

 public partial class RecommendationsView : ContentView 
  {
    public RecommendationsView()
    {
        InitializeComponent();
    }

    public static readonly BindableProperty myViewModelProperty =
BindableProperty.Create(
    nameof(myViewModel),
    typeof(MainViewModel),
    typeof(RecommendationsView),
    null);

    public MainViewModel myViewModel
    {
        set { SetValue(myViewModelProperty, value); }
        get { return (MainViewModel)GetValue(myViewModelProperty); }
    }
}

RecommendationsView.xaml

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormContentViewApp.RecommendationsView"
             x:Name="myControlView"
             >
  <ContentView.Content>
        <ListView ItemsSource="{Binding Source={x:Reference myControlView}, Path=myViewModel.Items }">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                      <Label Text="{Binding Id}"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentView.Content>
</ContentView>

MainViewModel.cs

public class MainViewModel 
{
    public ObservableCollection<Item> Items { get; set; }

    public MainViewModel() {
        Items= new ObservableCollection<Item>();

        Items.Add(new Item { Id = 1});
        Items.Add(new Item { Id = 2});
        Items.Add(new Item { Id = 3});
    }
}

public class Item 
{
    public int Id { get; set; }
}

使用示例:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:local="clr-namespace:FormContentViewApp"
             x:Class="FormContentViewApp.MainPage"
             x:Name="mainpage"
             >

    <ContentPage.BindingContext>
        <local:MainViewModel></local:MainViewModel>
    </ContentPage.BindingContext>

    <StackLayout Orientation="Vertical">
        <local:RecommendationsView  myViewModel="{Binding Path=BindingContext, Source={x:Reference mainpage}}">
        </local:RecommendationsView>
    </StackLayout>
</ContentPage>
© www.soinside.com 2019 - 2024. All rights reserved.