我正在开发一个带有两个 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 时重新获取数据,但这会导致闪烁,而这并不总是必要的。
任何有关如何处理这种情况的建议将不胜感激!谢谢!
有多种方法可以实现这一目标。
方法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));