经过大量研究,我对如何实现简单 CollectionChanged事件感到难过。我当前的设置使用INotifyPropertyChanged实现如下:
public class Invasion : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
每个Property都像这样调用NotifyPropertyChanged:
public int myProperty
{
get { return _backingMember; }
set { _backingMember = value; NotifyPropertyChanged(); }
}
一切都很好。除了: 我需要在ObservableCollection更改时引发事件,而不仅仅是属性。诀窍是,我需要这个超级简单;我不在乎所得到的东西。添加或删除。我不在乎修改了哪个元素,或者如何,如果不是一个,我就不在乎在给定的集合中发生了变化。我需要知道的是如果集合已更改。那就是它。
所以我正在寻找一种超级简单的方法来实现某种类型的CollectionChanged事件。正如我所提到的,我一直在研究" INotifyCollectionChanged",但我在网上发现的一切都非常复杂,有很多自定义处理和诸如此类的东西。我并不需要所有这些,并且如果可能的话,我不希望不必要地混乱我的代码。
截至目前,我有以下(非工作)代码:
public class Invasion : INotifyPropertyChanged, INotifyCollectionChanged
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void NotifyCollectionChanged(/*Need this code*/)
{
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(/* And this Code */));
}
}
集合及其属性设置如下:
private ObservableCollection<FearCard> _fearDeck = new ObservableCollection<FearCard>();
private ObservableCollection<EventCard> _eventDeck = new ObservableCollection<EventCard>();
etc...
...
public ObservableCollection<FearCard> FearDeck
{
get { return _fearDeck; }
set {
_fearDeck = value;
NotifyPropertyChanged();
NotifyPropertyChanged("TopFearCard");
NotifyCollectionChanged();
}
}
etc...
同样,如果可能的话,我希望尽可能简单。我需要做的就是在我的集合发生变化时通知,这样xaml数据绑定就会在图像发生变化时更新。
答案 0 :(得分:0)
您可能只是将CollectionChanged事件订阅传递给myApp.SendMessage('Controller','enableCamera', 'true');
成员(如果它是唯一应该触发&#34;外部&#34; CollectionChanged事件的成员集合。)
_fearDeck
否则,请查看NotifyCollectionChangedEventArgs
构造函数的重载列表,以了解如何实现它。
答案 1 :(得分:0)
通常,最简单的方法是创建一次observable然后使用它(.Clear()/ .Add(...)/ Remove(...))。 然后,您可以直接使用observable的CollectionChanged事件。
class SomeViewModel : ViewModelBase
{
void SomeMethod ( )
{
Obs.Add ( "item" );
Obs.Clear ( );
}
public ObservableCollection<string> Obs { get; }
= new ObservableCollection<string> ( );
public ObservableCollection<string> Obs2 { get; }
= new ObservableCollection<string> ( );
}
class SomeParentViewModel : ViewModelBase
{
public SomeParentViewModel ( )
{
Child.Obs.CollectionChanged += ( sender, e ) => { /* Handles collection changed logic */ };
Child.Obs2.CollectionChanged += ( sender, e ) => { /* Handles collection changed logic */ };
}
public SomeViewModel Child { get; }
= new SomeViewModel ( );
}
然后,您可以直接在viewmodel上实现INotifyCollectionChanged并冒泡可观察集合已更改事件:
class SomeViewModel : ViewModelBase, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
public SomeViewModel ( )
{
Obs.CollectionChanged += (sender, e) => CollectionChanged?.Invoke ( this, e ); // *edit*
}
public ObservableCollection<string> Obs { get; }
= new ObservableCollection<string> ( );
}
编辑:
由于您只需要在集合更改时显示图片,还有另一种可行的方法,即DependencyObject:
class DisplayOnNotify : DependencyObject
{
public static INotifyCollectionChanged GetObservable ( DependencyObject obj )
{
return (INotifyCollectionChanged)obj.GetValue ( ObservableProperty );
}
public static void SetObservable ( DependencyObject obj, INotifyCollectionChanged value )
{
obj.SetValue ( ObservableProperty, value );
}
// Using a DependencyProperty as the backing store for Observable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ObservableProperty =
DependencyProperty.RegisterAttached ( "Observable",
typeof ( INotifyCollectionChanged ),
typeof ( DisplayOnNotify ),
new FrameworkPropertyMetadata ( propertyChangedCallback ) );
private static void propertyChangedCallback ( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
if ( d is UIElement uiElement && e.NewValue is INotifyCollectionChanged notify )
{
notify.CollectionChanged += ( sender, e_ ) => uiElement.Visibility = Visibility.Visible;
}
}
}
然后你可以直接在xaml中使用它:
<Image Visibility="Collapsed" local:DisplayOnNotify.Observable="{Binding FearDeck}" />
这将有效地在第一个集合更改事件
上显示您的图像答案 2 :(得分:0)
collectionchanged事件并不仅仅是为了改变图片。 我能想到的最简单的方法是将图像绑定到从同一视图模型中公开的imagesource属性。 然后,您只需在setter中设置该属性并更改该raise属性。
set {
_fearDeck = value;
NotifyPropertyChanged();
NotifyPropertyChanged("TopFearCard");
NotifyPropertyChanged("NameofProperyExposingImageSource");
}
看看你似乎在做什么。 我想也许这张图片是从&#34; top&#34;恐惧卡。 您似乎不太可能尝试更改套牌中的所有照片。
说出你的&#34; top&#34;汽车在集合中的索引为0。您可以将图像控件的ImageSource绑定到FearCard中索引的图片属性。 ICollectionChanged(observablecollection implements)可以通知其中一个对象已更改。强制执行此操作的方法是将observablecollection中的对象设置为自身。 因此,如果TopFearCard是指向其中一个FearCards的属性,您可以执行以下操作:
FearCard[0] = FearCard[0];