【发布时间】:2020-12-29 10:10:32
【问题描述】:
按照this 示例为 CollectionView 创建分组,我注意到没有一个属性是 INotifyPropertyChanged,基类也不是 ObservableCollection。
虽然后者很容易通过将 List 更改为 ObservableCollection 来解决:
public class AnimalGroup : ObservableCollection<Animal>
{
public string Name { get; private set; }
public AnimalGroup(string name, ObservableCollection<Animal> animals) : base(animals)
{
Name = name;
}
private string _someOtherPropertyIWantToChangeAtRuntime = "hey";
public string SomeOtherPropertyIWantToChangeAtRuntime { get => _someOtherPropertyIWantToChangeAtRuntime, set => SetProperty(ref _someOtherPropertyIWantToChangeAtRuntime, value); }
}
不清楚如何创建 Name 或任何其他属性(例如 SomeOtherPropertyIWantToChangeAtRuntime),我想将组关联为 INotifyPropertyChanged。通过将接口添加到 base 将其视为普通类会导致此警告:
基本接口 'INotifyPropertyChanged' 是多余的,因为 AnimalGroup 继承了 'ObservableCollection'
然而,setter 没有什么可以调用的,例如 SetProperty(ref _name, Value) 并且现有的 PropertyChanged 对象只是用于监视组的集合更改。它不是可调用的,只是可处理的。
如果我忽略警告并无论如何实施 INotifyPropertyChanged(并将我的事件命名为 PropChanged 以避免与 ObservableCollection.PropertyChanged 冲突),
protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName]string propertyName = "", Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
PropChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
public event PropertyChangedEventHandler PropChanged;
让我的 ViewModel 管理 SomeOtherPropertyIWantToChangeAtRuntime 的值,绑定的 <Label> 永远不会看到任何变化。
<CollectionView ItemsSource="{Binding AnimalGroups}" HorizontalOptions="FillAndExpand">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label
Text="{Binding Name}"
HorizontalOptions="Start"
FontSize="24.44"
TextColor="Black"
FontAttributes="Bold"
Margin="0,0,0,10"/>
<Label
Text="{Binding SomeOtherPropertyIWantToChangeAtRuntime}" FontSize="15"
TextColor="Black"
Margin="0,0,0,0">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.FindGroupAndChangeTextCommand, Source{x:Reference thisPageName}" CommandParameter="{Binding Name}"/>
</Label.GestureRecognizers>
</Label>
...
视图模型:
public ObservableCollection<AnimalGroup> AnimalGroups {get; private set;}
public ICommand FindGroupAndChangeTextCommand {get; private set;}
public void FindGroupAndChangeText(string name)
{
var group = AnimalGroups.FirstOrDefault(t => t.Name == name);
if (group != null)
group.SomeOtherPropertyIWantToChangeAtRuntime = DateTime.Now.ToString();
}
ViewModel()
{
AnimalGroups = LoadData(); // not shown
FindGroupAndChangeTextCommand = new Command(FindGroupAndChangeText);
}
结果是标签保持“嘿”(这是默认值)并且永远不会改变,即使我可以看到上面的命令触发并且代码找到了组并设置了文本。
【问题讨论】:
-
ObservableCollection 有一个 OnPropertyChanged 方法
-
我不认为你理解我的问题。 ObservableCollection 确实具有 PropertyChanged,但它仅在添加和删除项目时触发。这与我需要什么无关。
-
我明白,你应该可以在你的属性设置器中调用 OnPropertyChanged
-
现在我明白了。设置器的工作方式如下: set {_propname= value; OnPropertyChanged(newPropertyChangedEventArgs(nameof(Propname)));}
标签: xamarin.forms grouping observablecollection inotifypropertychanged collectionview