在 .NET MAUI (MVVM) 中从另一个 ViewModel 添加项目时如何确保 CollectionView 更新

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

我正在开发一个带有两个 CollectionView 的 .NET MAUI 应用程序:

public ObservableCollection<CourseGroup> CourseGroups { get; } = new ObservableCollection<CourseGroup>();
public ObservableCollection<Course> Courses { get; } = new ObservableCollection<Course>();

CourseGroup 旨在对课程进行分组概述。

在我的 CoursePage.xaml.cs 中,我有以下代码来获取一次数据:

if (!_isDataLoaded)
{
    _coursesViewModel?.GetCoursesAsync();
    _isDataLoaded = true;
}

在 CoursePage.xaml 中,我有:

<RefreshView Grid.ColumnSpan="2"
             Command="{Binding GetCoursesCommand}"
             IsRefreshing="{Binding IsRefreshing}">
    <ContentView>
        <CollectionView ItemsSource="{Binding CourseGroups}"

在我的 CoursesViewModel 中,我有逻辑:

[RelayCommand]
public async Task GetCoursesAsync()

在此方法中,我从 API 获取课程并使用 foreach 循环将它们添加到课程和课程组中。

现在,我有另一个名为 CourseRegistrationViewModel 的 ViewModel 负责添加新课程。它调用我的 API 的 POST 请求。但是,如何确保 CollectionView 已更新?我无权访问 CoursesViewModel 的 CollectionView。我尝试在每次打开 CoursesPage 时重新获取数据,但这会导致闪烁,而这并不总是必要的。

任何有关如何处理这种情况的建议将不胜感激!谢谢!

mvvm maui maui-community-toolkit community-toolkit-mvvm
1个回答
0
投票

有多种方法可以实现这一目标。

方法1:常见的方法是使用

EventHandler

您可以在此视图中定义

EventHandler
(假设名称为
AddItemPage
),如下:

 public static EventHandler<Item> mEventHandler; // define a static  EventHandler

选择一个项目后,您可以使用以下代码传递添加的项目:

private void Button_Clicked(object sender, EventArgs e)
    {
        EventHandler<Item> handler = mEventHandler;
        if (handler != null)
        {
            Item item = new Item { Name= "Hello." };

            mEventHandler(this, item);
        }

        Navigation.PopAsync();
    }

在上一页中,您可以在 YourPreviousPage 的

constructor
中添加以下代码:

        AddItemPage.mEventHandler += delegate (object s, Item a)
        {
            BackCall(s, a);
        };

函数

BackCall
的代码是:

 private void BackCall(object send, Item a)
    {
        if (a == null)
        {
            throw new ArgumentNullException(nameof(a));
        }
        else {

             DisplayAlert("Alert", "call back value is : " + a.Name, "OK");
        }
    }

方法2

您也可以使用Messenger来实现此功能。

请参考以下代码:

// Create a message
public class LoggedInUserChangedMessage : ValueChangedMessage<User>
{
    public LoggedInUserChangedMessage(User user) : base(user)
    {        
    }
}

// Register a message in some module
WeakReferenceMessenger.Default.Register<LoggedInUserChangedMessage>(this, (r, m) =>
{
    // Handle the message here, with r being the recipient and m being the
    // input message. Using the recipient passed as input makes it so that
    // the lambda expression doesn't capture "this", improving performance.
});

// Send a message from some other module
WeakReferenceMessenger.Default.Send(new LoggedInUserChangedMessage(user));
© www.soinside.com 2019 - 2024. All rights reserved.