Below is my base entity class.  I have a class (GuidPOCO) that
inherits from BindableObject and just implements an Id property as a
guid along with some vaidation logic.


    /// <summary>
    /// Implements the INotifyPropertyChanged interface and
    /// exposes a NotifyPropertyChanged method for derived
    /// classes to raise the PropertyChange event.  The event
    /// arguments created by this class are cached to prevent
    /// managed heap fragmentation.
    /// </summary>
    [Serializable]
    public abstract class BindableObject : INotifyPropertyChanged,
IEditableObject, IDataErrorInfo
    {
        #region Data

        private static readonly Dictionary<string,
PropertyChangedEventArgs> eventArgCache;
        private const string ERROR_MSG = "{0} is not a public property
of {1}";
        private static readonly object syncLock = new object();
        private HybridDictionary oldState;

        #endregion // Data

        #region Constructors

        static BindableObject()
        {
            eventArgCache = new Dictionary<string,
PropertyChangedEventArgs>();
        }

        protected BindableObject()
        {

        }

        #endregion // Constructors

        #region Public Members

        /// <summary>
        /// Raised when a public property of this object is set.
        /// </summary>
        [field: NonSerialized]
        public virtual event PropertyChangedEventHandler
PropertyChanged;

        /// <summary>
        /// Returns an instance of PropertyChangedEventArgs for
        /// the specified property name.
        /// </summary>
        /// <param name="propertyName">
        /// The name of the property to create event args for.
        /// </param>
        public static PropertyChangedEventArgs
GetPropertyChangedEventArgs(string propertyName)
        {
            if (String.IsNullOrEmpty(propertyName))
                throw new ArgumentException("propertyName cannot be
null or empty.");

            PropertyChangedEventArgs args;
            lock (BindableObject.syncLock)
            {
                if (!eventArgCache.TryGetValue(propertyName, out
args))
                {
                    eventArgCache.Add(propertyName, args = new
PropertyChangedEventArgs(propertyName));
                }
            }
            return args;
        }

        public abstract bool IsPropertyValid { get; }

        public abstract bool IsValid { get; }

        public abstract string ValidationErrors { get; }

        #endregion // Public Members

        #region Protected Members

        /// <summary>
        /// Derived classes can override this method to
        /// execute logic after a property is set. The
        /// base implementation does nothing.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected virtual void AfterPropertyChanged(string
propertyName)
        {
        }

        /// <summary>
        /// Attempts to raise the PropertyChanged event, and
        /// invokes the virtual AfterPropertyChanged method,
        /// regardless of whether the event was raised or not.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected virtual void NotifyPropertyChanged(string
propertyName)
        {
            this.VerifyProperty(propertyName);

            PropertyChangedEventHandler handler =
this.PropertyChanged;
            if (handler != null)
            {
                // Get the cached event args.
                PropertyChangedEventArgs args =
                    GetPropertyChangedEventArgs(propertyName);

                // Raise the PropertyChanged event.
                handler(this, args);
            }

            this.AfterPropertyChanged(propertyName);
        }

        #endregion // Protected Members

        #region Private Helpers

        [Conditional("DEBUG")]
        private void VerifyProperty(string propertyName)
        {
            // Thanks to Rama Krishna Vavilala for the tip to use
TypeDescriptor here, instead of manual
            // reflection, so that custom properties are honored too.
            // 
http://www.codeproject.com/KB/WPF/podder1.aspx?msg=2381272#xx2381272xx

            bool propertyExists = TypeDescriptor.GetProperties
(this).Find(propertyName, false) != null;
            if (!propertyExists)
            {
                // The property could not be found,
                // so alert the developer of the problem.

                string msg = string.Format(
                    ERROR_MSG,
                    propertyName,
                    this.GetType().FullName);

                Debug.Fail(msg);
            }
        }

        #endregion // Private Helpers

        #region Implementation of IEditableObject

        public virtual void BeginEdit()
        {
            oldState = new HybridDictionary();
            foreach (PropertyInfo property in this.GetType
().GetProperties())
            {
                if (property.CanWrite)
                {
                    oldState[property.Name] = property.GetValue(this,
null);
                }
            }
        }

        public virtual void EndEdit()
        {
            oldState = null;
        }

        public virtual void CancelEdit()
        {
            foreach (PropertyInfo property in this.GetType
().GetProperties())
            {
                if (property.CanWrite)
                {
                    property.SetValue(this, oldState[property.Name],
null);
                }
            }
            oldState = null;
        }

        #endregion

        #region Implementation of IDataErrorInfo

        public abstract string this[string columnName] { get; }
        public abstract string Error { get; }

        #endregion
    }

On Aug 24, 6:28 pm, José Romaniello <[email protected]> wrote:
> could your post the entity class?
>
> 2009/8/24 Chris Willard <[email protected]>
>
>
>
> > Hi José,
>
> > I am attempting to try out your ObservableSet implementation but am
> > having a couple of issues.  First off I can't seem to get the global
> > registration working using the code you supplied below.  I seems to be
> > ignoring the configuration property change and using the default
> > implementation.  Below is how I am currently handling the
> > configuration.
>
> >        private ISessionFactory BuildSessionFactory()
> >        {
> >            ISessionFactory result =
> >                   Fluently.Configure()
> >                       .Database(MsSqlConfiguration.MsSql2005
> >                           .ConnectionString(c => c
> >                               .FromConnectionStringWithKey
> > (ConnectionStringName))
> >                           .Cache(c => c
> >                               .UseQueryCache()
> >                               .ProviderClass<HashtableCacheProvider>
> > ())
> >                           .ShowSql())
> >                       .ExposeConfiguration(ConfigureLazyLoad)
> >                       .ExposeConfiguration(ConfigureCollectionType)
> >                       .Mappings(m => m
> >                           .FluentMappings.AddFromAssembly
> > (_MapAssembly)
>
> > .ConventionDiscovery.AddFromAssemblyOf<ClassConvention>
> > ())
> >                       .ExposeConfiguration(ConfigureValidator)
> >                       .BuildSessionFactory();
>
> >            return result;
> >        }
>
> >        private void ConfigureCollectionType(Configuration
> > configuration)
> >        {
> >            configuration.SetProperty
> > (Cfg.Environment.CollectionTypeFactoryClass, typeof
>
> > (Collection.Observable.ObservableCollectionTypeFactory).AssemblyQualifiedName);
> >        }
>
> > If I manually set the CollectionType within one of my mapping classes
> > (.CollectionType<ObservableSetType<SectionNumber>>();) it seems to
> > work, although I am getting an error (Collection Remove event must
> > specify item position) when I try to remove an item from the
> > collection.
>
> > Thanks again,
> > Chris
>
> > On Aug 24, 4:57 pm, José Romaniello <[email protected]> wrote:
> > > There is also an ObservableSet. I use this class as a "transient
> > observable
> > > set" since .net framework only have an observable list.
> > > In order to configure the collection type factory I use:
>
> > > configuration.Properties[Environment.CollectionTypeFactoryClass]
> > > = typeof (WpfCollectionTypeFactory).AssemblyQualifiedName;
>
> > > Stay in sync with the WPF sample (athttp://nhforge.org/blogs/nhibernate/
> > ).
>
> > > 2009/8/24 Chris Willard <[email protected]>
>
> > > > That is exactly what I needed!  I really appreciate all your great
> > > > work...
>
> > > > Chris
>
> > > > On Aug 24, 3:02 pm, Fabio Maulo <[email protected]> wrote:
> > > > > The proposal of CollectionTypeFactoryClass is allow the substitutions
> > of
> > > > all
> > > > > persistent collections by default.If you want see an implementation
> > using
> > > > > observable collections it is available here:
> > > >http://code.google.com/p/unhaddins/source/browse/#svn/trunk/uNhAddIns.
> > ..
>
> > > > > <
> >http://code.google.com/p/unhaddins/source/browse/#svn/trunk/uNhAddIns..
> > > > .>You
> > > > > can change it according to the implementations you are using.
>
> > > > > 2009/8/24 Chris Willard <[email protected]>
>
> > > > > > Hello,
>
> > > > > > I am using the observable collections implementation from the
> > > > > > following post to handle collections within a WPF application.
>
> >http://happynomad121.blogspot.com/2007/12/collections-for-wpf-and-nhi.
> > > > ..
>
> > > > > > I am currently adding ".CollectionType<ObservableSetType<T>>()" to
> > > > > > each property within the fluent map classes but was wondering if
> > there
> > > > > > is a way to handle this type of thing globally.  I have seen some
> > > > > > mention of setting the CollectionTypeFactoryClass but was not sure
> > how
> > > > > > (or if) that related to the actually collection implementation.  I
> > am
> > > > > > sure I am just missing something simple.  Any help would be greatly
> > > > > > appreciated!
>
> > > > > > Thanks in advance,
> > > > > > Chris
>
> > > > > --
> > > > > Fabio Maulo
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to