在弹出窗口的视图模型中更新 属性 不会更新 UI
Updating a property in a viewmodel of popup doesn't update the UI
如标题所示,我遇到一个问题,即在弹出窗口的视图模型中更新 属性 不会更新 UI。我使用来自 xamarin 社区工具包的弹出窗口。我正在使用执行此任务的命令:
async Task ShowPopup()
{
MessagingCenter.Send(AnimeGroupObservable, "AnimeGroups");
Shell.Current.ShowPopup(new MediaListGroupsPopup());
}
它发送一条带有负载的消息并显示弹出窗口。这是弹出视图模型:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Input;
using OtakuApp.Models;
using Xamarin.Forms;
namespace OtakuApp.ViewModels
{
class MediaListGroupsPopupViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public ObservableCollection<Group> _AnimeGroups = new ObservableCollection<Group>();
public ObservableCollection<Group> AnimeGroups
{
get => _AnimeGroups;
set
{
if (_AnimeGroups == value)
return;
_AnimeGroups = value;
OnPropertyChanged();
}
}
public String _label;
public String label
{
get => _label;
set
{
if (value == _label)
return;
_label = value;
OnPropertyChanged();
}
}
public MediaListGroupsPopupViewModel()
{
MessagingCenter.Subscribe<ObservableCollection<Group>>(this, "AnimeGroups", (AnimeGroupObservable) =>
{
Console.WriteLine(AnimeGroupObservable[0].Name);
label = AnimeGroupObservable[1].Name;
MessagingCenter.Unsubscribe<ObservableCollection<Group>>(this, "AnimeGroups");
});
}
}
}
我正计划从 select 获得一个小型 collection 标签视图。但现在我正在努力更新一个标签只是为了测试目的,所以你可以想象我已经尝试了 collection 视图但它没有用。在代码中手动将 _label 设置为某些内容表明绑定有效。只是因为某些原因没有更新。
弹出xaml文件:
<?xml version="1.0" encoding="utf-8" ?>
<xct:Popup
x:Class="OtakuApp.Popups.MediaListGroupsPopup"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
Size="300,300">
<StackLayout>
<Label Text="{Binding label}" />
</StackLayout>
</xct:Popup>
所以现在我有两个问题:
- 标签没有更新。它绑定到具有 INotifyPropertyChanged
的 属性
- 奇怪的是,这个订阅只发生了第二次(之后也是,而不是第一次)我打开了一个弹出窗口。这是因为它在构造函数中吗?如果是,正确的处理方式是什么?
还有一个小问题 - 我在订阅结束时退订了。当我没有它并打印出 AnimeGroupObservable[0].Name 时,第一次打印一次,第二次我打开弹出窗口两次等等。最后取消订阅是正确的修复方法吗这个?
由于您将单个参数传递给单个页面,因此使用构造函数 比 MessagingCenter
简单得多(这很好,但对于这种情况来说太过分了)
创建页面时,在构造函数中传递参数
Shell.Current.ShowPopup(new MediaListGroupsPopup(AnimeGroupObservable));
然后修改页面构造函数接受参数
public MediaListGroupsPopup(ObservableCollection<Group> groups)
{
// you did't show how you create your VM, but I assume it's something like this
this.BindingContext = new MediaListGroupsPopupViewModel(groups);
}
然后修改您的 VM 构造函数
public MediaListGroupsPopupViewModel(ObservableCollection<Group> groups)
{
label = groups[1].Name;
}
如果您真的只使用一个 string
值,您可以只传递它而不是整个 ObservableCollection
如标题所示,我遇到一个问题,即在弹出窗口的视图模型中更新 属性 不会更新 UI。我使用来自 xamarin 社区工具包的弹出窗口。我正在使用执行此任务的命令:
async Task ShowPopup()
{
MessagingCenter.Send(AnimeGroupObservable, "AnimeGroups");
Shell.Current.ShowPopup(new MediaListGroupsPopup());
}
它发送一条带有负载的消息并显示弹出窗口。这是弹出视图模型:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Input;
using OtakuApp.Models;
using Xamarin.Forms;
namespace OtakuApp.ViewModels
{
class MediaListGroupsPopupViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public ObservableCollection<Group> _AnimeGroups = new ObservableCollection<Group>();
public ObservableCollection<Group> AnimeGroups
{
get => _AnimeGroups;
set
{
if (_AnimeGroups == value)
return;
_AnimeGroups = value;
OnPropertyChanged();
}
}
public String _label;
public String label
{
get => _label;
set
{
if (value == _label)
return;
_label = value;
OnPropertyChanged();
}
}
public MediaListGroupsPopupViewModel()
{
MessagingCenter.Subscribe<ObservableCollection<Group>>(this, "AnimeGroups", (AnimeGroupObservable) =>
{
Console.WriteLine(AnimeGroupObservable[0].Name);
label = AnimeGroupObservable[1].Name;
MessagingCenter.Unsubscribe<ObservableCollection<Group>>(this, "AnimeGroups");
});
}
}
}
我正计划从 select 获得一个小型 collection 标签视图。但现在我正在努力更新一个标签只是为了测试目的,所以你可以想象我已经尝试了 collection 视图但它没有用。在代码中手动将 _label 设置为某些内容表明绑定有效。只是因为某些原因没有更新。
弹出xaml文件:
<?xml version="1.0" encoding="utf-8" ?>
<xct:Popup
x:Class="OtakuApp.Popups.MediaListGroupsPopup"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
Size="300,300">
<StackLayout>
<Label Text="{Binding label}" />
</StackLayout>
</xct:Popup>
所以现在我有两个问题:
- 标签没有更新。它绑定到具有 INotifyPropertyChanged 的 属性
- 奇怪的是,这个订阅只发生了第二次(之后也是,而不是第一次)我打开了一个弹出窗口。这是因为它在构造函数中吗?如果是,正确的处理方式是什么?
还有一个小问题 - 我在订阅结束时退订了。当我没有它并打印出 AnimeGroupObservable[0].Name 时,第一次打印一次,第二次我打开弹出窗口两次等等。最后取消订阅是正确的修复方法吗这个?
由于您将单个参数传递给单个页面,因此使用构造函数 比 MessagingCenter
简单得多(这很好,但对于这种情况来说太过分了)
创建页面时,在构造函数中传递参数
Shell.Current.ShowPopup(new MediaListGroupsPopup(AnimeGroupObservable));
然后修改页面构造函数接受参数
public MediaListGroupsPopup(ObservableCollection<Group> groups)
{
// you did't show how you create your VM, but I assume it's something like this
this.BindingContext = new MediaListGroupsPopupViewModel(groups);
}
然后修改您的 VM 构造函数
public MediaListGroupsPopupViewModel(ObservableCollection<Group> groups)
{
label = groups[1].Name;
}
如果您真的只使用一个 string
值,您可以只传递它而不是整个 ObservableCollection