I went ahead and applied Andrew's approach to my solution's persistent
observable bag, list, and set classes (the IUserCollectionType
implementations stayed the same). This is a much more elegant method
than the override hacking I was doing previously. Wish I got his
suggestion earlier! In any case, looks like additional (GUI
technology neutral) support for observability in NH-Core might not be
necessary after all, although I enjoyed our discussion. Check out my
blog entry (mentioned in the original post) to download the updated
solution.
On Dec 8, 12:24 pm, HappyNomad <[EMAIL PROTECTED]> wrote:
> Thanks for your help, Andrew. Subscribing to the inner collection's
> change events is a great idea -- far better than the override hacking
> approach I've been taking. I'm building against NH 2.0 for the time
> being. Depending on further related changes made to the trunk, I'll
> eventually update the solution on my blog to use the latest NH
> version, including lists and sets as well.
>
> On Dec 7, 8:22 pm, Andrew C <[EMAIL PROTECTED]> wrote:
>
> > HappyNomad:
>
> > I got ObservableBag working with the new trunk by extending
> > PersistantGenericBag and replacing the InnerBag with an
> > ObservableCollection. See below:
>
> > [Serializable, DebuggerTypeProxy(typeof
> > (NHibernate.DebugHelpers.CollectionProxy<>))]
> > public class PersistentObservableBag<T> : PersistentGenericBag<T>,
> > INotifyCollectionChanged
> > {
>
> > public PersistentObservableBag(ISessionImplementor session)
> > : base(session)
> > {
> > }
>
> > public PersistentObservableBag(ISessionImplementor session,
> > ICollection<T> coll)
> > : base(session, coll)
> > {
> > INotifyCollectionChanged collection = coll as
> > INotifyCollectionChanged;
> > if (collection != null)
> > {
> > collection.CollectionChanged += new
> > NotifyCollectionChangedEventHandler(OnCollectionChanged);
> > }
> > }
>
> > public override void BeforeInitialize(ICollectionPersister
> > persister, int anticipatedSize)
> > {
> > this.InternalBag = (IList<T>)
> > persister.CollectionType.Instantiate(anticipatedSize);
> > INotifyCollectionChanged collection = base.InternalBag as
> > INotifyCollectionChanged;
> > if (collection != null)
> > {
> > collection.CollectionChanged += new
> > NotifyCollectionChangedEventHandler(OnCollectionChanged);
> > }
> > }
>
> > protected void OnCollectionChanged(object sender,
> > NotifyCollectionChangedEventArgs e)
> > {
> > if (CollectionChanged != null)
> > CollectionChanged(this, e);
> > }
>
> > public event NotifyCollectionChangedEventHandler
> > CollectionChanged;
>
> > }
>
> > public class ObservableBagType<T> : IUserCollectionType
> > {
> > #region IUserCollectionType Members
>
> > public bool Contains(object collection, object entity)
> > {
> > return ((IList<T>)collection).Contains((T)entity);
> > }
>
> > public IEnumerable GetElements(object collection)
> > {
> > return (IEnumerable)collection;
> > }
>
> > public object IndexOf(object collection, object entity)
> > {
> > return ((IList<T>)collection).IndexOf((T)entity);
> > }
>
> > public object ReplaceElements(object original, object target,
> > ICollectionPersister persister, object owner, IDictionary copyCache,
> > ISessionImplementor session)
> > {
> > IList<T> result = (IList<T>)target;
> > result.Clear();
> > foreach (object item in ((IEnumerable)original))
> > result.Add((T)item);
> > return result;
> > }
>
> > // return an instance of the inner collection type
> > public object Instantiate(int anticipatedSize)
> > {
> > return new ObservableCollection<T>();
> > }
>
> > public IPersistentCollection Instantiate(ISessionImplementor
> > session, ICollectionPersister persister)
> > {
> > return new PersistentObservableBag<T>(session);
> > }
>
> > public IPersistentCollection Wrap(ISessionImplementor session,
> > object collection)
> > {
> > return new PersistentObservableBag<T>(session,
> > (ICollection<T>)collection);
> > }
>
> > #endregion
> > }