在毛伊岛内容视图中绑定数据

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

在我的毛伊岛应用程序中,我有一个用作自定义控件的内容视图。在其中我有一个集合视图,我想将其绑定到数据列表。

我的服务使用 DI,并且有一个包含所有 httpclient 请求的 BaseService,然后根据模型继承该 BaseService。

然后我有一个视图模型,我可以在其中注入服务并从 api 检索数据。


private readonly LightCastArchiveService _lightCastArchiveService;
private readonly LightCastChannelService _lightCastChannelService;
#endregion

public LatestViewModel(LightCastArchiveService lightCastArchiveService,
    LightCastChannelService lightCastChannelService)
{
    _lightCastArchiveService = lightCastArchiveService;
    _lightCastChannelService = lightCastChannelService;

}

在视图模型中我有一个获取数据的方法:

public async Task LoadVideos()
    {
        if (IsLoading) return;
        try
        {
            string url = EndPoints.ArchiveEndpoint + $"&count=50";
            IsLoading = true;
            if (Videos.Any()) Videos.Clear();
            var videos = new List<LCVideo>();
            videos = await _lightCastArchiveService.Get(url);
            foreach (var video in videos)
            {
                Videos.Add(video);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"Unable to get the videos: {ex.Message}");
            await Shell.Current.DisplayAlert("Error", "Failed to retrieve list of videos.", "Ok");
        }
        finally
        {
            IsLoading = false;
            IsRefreshing = false;
        }
    }

在内容页面中,我可以使用 OnAppearing 方法来检索视频:

 protected override async void OnAppearing()
    {
        base.OnAppearing();
        await _homeViewModel.GetCarouselItems(1025, 10);
        await _homeViewModel.LoadLiveChannels();
        await _homeViewModel.GetItems(1009, 20);
        await _homeViewModel.LoadVideosForAllChannels();
        
    }

但是我怎样才能在内容视图中做到这一点(我尝试了下面的方法,但它不起作用)?

public partial class Latest : ContentView
{
    private readonly LatestViewModel _latestViewModel;
    private readonly LightCastArchiveService _lightCastArchiveService;
    private readonly LightCastChannelService _lightCastChannelService;
    private readonly HttpClient _client;
    public Latest()
    {
        InitializeComponent();
        .BindingContextChanged += OnBindingContextChanged;

        _lightCastArchiveService = new LightCastArchiveService(_client);
        _lightCastChannelService = new LightCastChannelService(_client);

        this.BindingContextChanged += OnBindingContextChanged;

        _latestViewModel = new LatestViewModel(_lightCastArchiveService, _lightCastChannelService);
        BindingContext = _latestViewModel;
    }

    private async void OnBindingContextChanged(object sender, EventArgs e)
    {
        if (BindingContext is LatestViewModel viewModel)
        {
            await viewModel.LoadVideos();
        }
    }

    // private async void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    // {
    //     if (e.PropertyName == nameof(_latestViewModel.Videos))
    //     {
    //         latestVideos.BindingContext = await _latestViewModel.LoadVideos();
    //     }
    // }
}
```
asp.net-core maui
1个回答
0
投票

除非它是一个非常复杂的自定义控件,否则您可能希望避免使用
ContentView
的视图模型。

让我证明这一点。我并不是说这是完全错误的,也不是不可能的,但正如您所看到的,

Page
s 视图模型中的许多功能并不适用于
ContentView
s 视图模型(注入服务、出现事件...)。 有人实际上可能会说你不应该使用
OnAppearing()
来调用 viewmodel 方法,但我不是一个纯粹主义者。

如果您考虑一下 MAUI 控件,它们没有自己的视图模型,但它们继承了祖先的

BindingContext
(可能属于使用它们的
Page
)并提供可绑定属性,您可以绑定到视图模型财产。你也应该这么做。

如果您不知道我在说什么,请看看如何

BindableProperties
工作


如果您确实想保留视图模型,您可以在

ContentPage
代码隐藏中实例化它,并在那里执行所有绑定操作。这样,您就可以在
LatestViewModel
中调用
OnAppearing
方法。

© www.soinside.com 2019 - 2024. All rights reserved.