PropertyValue.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / Base / Core / PropertyEditing / PropertyValue.cs / 1305376 / PropertyValue.cs

                            namespace System.Activities.Presentation.PropertyEditing { 
    using System.Globalization;
    using System;
    using System.Collections;
    using System.ComponentModel; 
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis; 
    using System.Activities.Presentation.Internal.Properties; 
    using System.Activities.Presentation;
 
    /// 
    /// This class provides a data model for the underlying property value.
    /// 
    public abstract class PropertyValue : INotifyPropertyChanged { 

        private PropertyEntry _parentProperty; 
 
        /// 
        /// Creates a PropertyValue.  For host infrastructure. 
        /// 
        /// The PropertyEntry that corresponds to this PropertyValue
        /// When parentProperty is null
        protected PropertyValue(PropertyEntry parentProperty) { 
            if (parentProperty == null)
                throw FxTrace.Exception.ArgumentNull("parentProperty"); 
 
            _parentProperty = parentProperty;
        } 

        /// 
        /// Event that gets fired when any properties of the PropertyValue class change.
        /// Note that a "Value" and "StringValue" property changed notification gets fired 
        /// either when the Value or StringValue get set to a new instance OR when any
        /// sub-properties of this PropertyValue change. 
        ///  
        public event PropertyChangedEventHandler PropertyChanged;
 
        /// 
        /// Event fired when the Value or StringValue properties of this class
        /// get updated with new instances.
        ///  
        public event EventHandler RootValueChanged;
 
        ///  
        /// Event fired when the any of the sub-properties of this PropertyValue
        /// or its sub-properties get updated with new value instances. 
        /// 
        public event EventHandler SubPropertyChanged;

        ///  
        /// Gets the parent PropertyEntry.
        ///  
        public PropertyEntry ParentProperty { get { return _parentProperty; } } 

        ///  
        /// Gets a PropertyValueSource that contains information
        /// about where this value is coming from.
        /// 
        public abstract PropertyValueSource Source { get; } 

        ///  
        /// Returns true if Value is the default value for the property 
        /// 
        public abstract bool IsDefaultValue { get; } 

        /// 
        /// Returns true if this value represents a property for multiple objects with
        /// more than one value - for example 2 Buttons with different values for Background 
        /// If this property is true then Value will return null and and StringValue will return
        /// String.Empty. 
        ///  
        public abstract bool IsMixedValue { get; }
 
        /// 
        /// Throws if the value is invalid
        /// 
        /// value to validate 
        protected abstract void ValidateValue(object valueToValidate);
 
        ///  
        /// Gets a flag indicating whether the underlying value can be converted from a string
        ///  
        public abstract bool CanConvertFromString { get; }

        /// 
        /// Returns the given string as a value - used to convert StringValue to Value 
        /// Typical implementations would use the TypeConverter for the underlying property
        /// This method should not catch exceptions, it should propagate them. 
        ///  
        protected abstract object ConvertStringToValue(string value);
 
        /// 
        /// Returns the value as a String - used to convert Value to StringValue
        /// Typical implementations would use the TypeConverter for the underlying property
        ///  
        protected abstract string ConvertValueToString(object value);
 
        ///  
        /// Gets the underlying property value.
        ///  
        protected abstract object GetValueCore();

        /// 
        /// Sets the underlying property value.  This method should not catch 
        /// exceptions, but allow them to propagate.
        ///  
        protected abstract void SetValueCore(object value); 

        ///  
        /// Clears this value such that it is unset.
        /// 
        public abstract void ClearValue();
 
        // Value Property
 
        ///  
        /// Gets or sets the underlying property value.  Both Value and StringValue
        /// will raise the appropriate change notifications. 
        /// 
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Propagating the error might cause VS to crash")]
        [SuppressMessage("Reliability", "Reliability108", Justification = "Propagating the error might cause VS to crash")]
        public object Value 
        {
            get { 
                object returnValue = null; 

                if (this.CatchExceptions) { 
                    try {
                        returnValue = GetValueCore();
                    }
                    catch (Exception ex) { 
                        OnPropertyValueException(new PropertyValueExceptionEventArgs(
                            string.Format( 
                                CultureInfo.CurrentCulture, 
                                Resources.Error_ValueGetFailed),
                            this, 
                            PropertyValueExceptionSource.Get,
                            ex));
                    }
                } 
                else {
                    returnValue = GetValueCore(); 
                } 

                return returnValue; 
            }
            set
            {
                try 
                {
                    SetValueImpl(value); 
                } 
                catch (Exception ex)
                { 
                    bool isValidationException = ex is ValidationException;

                    //show error message if we do catch exception or exception is ValidationException
                    if (this.CatchExceptions || isValidationException) 
                    {
                        OnPropertyValueException(new PropertyValueExceptionEventArgs( 
                            string.Format(CultureInfo.CurrentCulture, Resources.Error_ValueSetFailed), 
                            this,
                            PropertyValueExceptionSource.Set, 
                            ex));
                    }

                    //rethrow if we do not catch exception or exception is ValidationException (it should be handled by the control) 
                    if (!this.CatchExceptions || isValidationException)
                    { 
                        throw; 
                    }
                } 
            }
        }

        private void SetValueImpl(object value) { 
            ValidateValue(value);
            SetValueCore(value); 
            NotifyValueChanged(); 
            OnRootValueChanged();
        } 


        // StringValue Property
 
        /// 
        /// Gets or sets the underlying property value as a string.  Both Value and StringValue 
        /// will raise the appropriate change notifications. 
        /// 
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Propagating the error might cause VS to crash")] 
        [SuppressMessage("Reliability", "Reliability108", Justification = "Propagating the error might cause VS to crash")]
        public string StringValue
        {
            get { 
                string returnValue = string.Empty;
 
                //If there is an error event handler then use it otherwise let the exception 
                //propogate
                if (this.CatchExceptions) { 
                    try {
                        //Caching opportunity here
                        returnValue = this.ConvertValueToString(this.Value);
                    } 
                    catch (Exception ex) {
                        OnPropertyValueException(new PropertyValueExceptionEventArgs( 
                            string.Format( 
                                CultureInfo.CurrentCulture,
                                Resources.Error_CannotConvertValueToString), 
                            this,
                            PropertyValueExceptionSource.Get,
                            ex));
                    } 
                }
                else { 
                    //Caching opportunity here 
                    returnValue = this.ConvertValueToString(this.Value);
                } 

                return returnValue;
            }
            set { 
                //If there is an error event handler then use it otherwise let the exception
                //propogate 
                if (CatchExceptions) { 
                    try {
                        this.Value = this.ConvertStringToValue(value); 
                    }
                    catch (Exception ex) {
                        OnPropertyValueException(
                            new PropertyValueExceptionEventArgs( 
                                string.Format(
                                    CultureInfo.CurrentCulture, 
                                    Resources.Error_CannotUpdateValueFromStringValue), 
                                this,
                                PropertyValueExceptionSource.Set, 
                                ex));
                    }
                }
                else { 
                    this.Value = this.ConvertStringToValue(value);
                } 
            } 
        }
 

        // SubProperties

        ///  
        /// Gets a flag indicating whether the type of this property
        /// supports sub-properties.  Typical implementations will use a TypeConverter 
        /// to verify whether sub-properties exist. 
        /// 
        public abstract bool HasSubProperties { get; } 

        /// 
        /// Gets a collection of sub-properties as PropertyEntry instances
        ///  
        public abstract PropertyEntryCollection SubProperties { get; }
 
 
        // Collections
 
        /// 
        /// Gets a flag indicating whether this PropertyValue models a property
        /// whose value is a collection.
        ///  
        public abstract bool IsCollection { get; }
 
        ///  
        /// Gets a collection of PropertyValue instances that correspond to the items
        /// in the collection when IsCollection is true. 
        /// 
        public abstract PropertyValueCollection Collection { get; }

 
        // Error Handling
 
        ///  
        /// Event for host implementations to use for error handling.  Raised when StringValue or Value throws
        /// and CatchExceptions is true.  If CatchExceptions is false, the exception will be thrown up the stack. 
        /// 
        public event EventHandler PropertyValueException;

        ///  
        /// Gets a boolean indicating whether exceptions thrown during value gets and sets
        /// should be caught or propagated directly to the caller.  By default, exceptions 
        /// are caught if there is at least one subscriber to the PropertyValueException event. 
        /// 
        protected virtual bool CatchExceptions { 
            get {
                return PropertyValueException != null;
            }
        } 

        ///  
        /// Called when PropertyValue get or set fails.  Default implementation raises the 
        /// PropertyValueException event.
        ///  
        /// PropertyValueExceptionEventArgs
        /// When e is null
        protected virtual void OnPropertyValueException(PropertyValueExceptionEventArgs e) {
            if (e == null) 
                throw FxTrace.Exception.ArgumentNull("e");
 
            if (PropertyValueException != null) 
                PropertyValueException(this, e);
        } 


        // Notification Helpers
 
        /// 
        /// Raises change notification for all properties.  This should be called when 
        /// the underlying object is changed externally (for example Button.Width is 
        /// changed on the design surface)
        ///  
        protected virtual void NotifyRootValueChanged() {
            //When Value is updated or the model is reset we
            //need to fire an "everything has changed" notification
 
            //This doesn't appear to work at all...
            //PropertyChanged(this, new PropertyChangedEventArgs("")); 
 
            //So notify these key changes individually
            OnPropertyChanged("IsDefaultValue"); 
            OnPropertyChanged("IsMixedValue");
            OnPropertyChanged("IsCollection");
            OnPropertyChanged("Collection");
            OnPropertyChanged("HasSubProperties"); 
            OnPropertyChanged("SubProperties");
            OnPropertyChanged("Source"); 
            OnPropertyChanged("CanConvertFromString"); 

            NotifyValueChanged(); 
            OnRootValueChanged();
        }

        ///  
        /// Called to raise the SubPropertyChanged event.  This method should be called
        /// when one of the sub-properties of this property changes.  It raises changed 
        /// events for Value, StringValue, and SubProperty 
        /// 
        protected void NotifySubPropertyChanged() { 
            NotifyValueChanged();
            OnSubPropertyChanged();
        }
 
        /// 
        /// Called to raise the changed events for Value and StringValue.  This method 
        /// should only be called to trigger the refresh of the visual representation 
        /// of this value.  If the value content actually changes, call NotifyRootValueChanged
        /// instead. 
        /// 
        private void NotifyValueChanged() {
            OnPropertyChanged("Value");
            NotifyStringValueChanged(); 
        }
 
        ///  
        /// Raise change notification for StringValue
        ///  
        private void NotifyStringValueChanged() {
            OnPropertyChanged("StringValue");
        }
 
        /// 
        /// Called to raise the RootValueChanged event 
        ///  
        private void OnRootValueChanged() {
            if (RootValueChanged != null) 
                RootValueChanged(this, EventArgs.Empty);
        }

        ///  
        /// Called to raise the SubPropertyChanged event
        ///  
        private void OnSubPropertyChanged() { 
            if (SubPropertyChanged != null)
                SubPropertyChanged(this, EventArgs.Empty); 
        }


        // INotifyPropertyChanged 

        ///  
        /// Raises the PropertyChanged event.  Subclasses that override this method 
        /// should call the base class implementation.
        ///  
        /// 
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
            if (PropertyChanged != null)
                PropertyChanged(this, e); 
        }
 
        ///  
        /// Raises the PropertyChanged event.
        ///  
        /// 
        protected virtual void OnPropertyChanged(string propertyName) {
            if (PropertyChanged != null)
                OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
        }
 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK