PropertyOverridesDialog.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 / fx / src / MIT / System / Web / UI / MobileControls / Design / PropertyOverridesDialog.cs / 1305376 / PropertyOverridesDialog.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.Design.MobileControls 
{ 
    using System;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Globalization; 
    using System.Diagnostics;
    using System.Drawing; 
    using System.Drawing.Design; 
    using System.Reflection;
    using System.Windows.Forms; 
    using System.Windows.Forms.Design;

    using Control = System.Web.UI.Control;
 
    using System.Web.UI.MobileControls;
    using System.Web.UI.Design.MobileControls.Converters; 
    using System.Web.UI.Design.MobileControls.Util; 

    [ 
        System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
        Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
    ]
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 
    internal sealed class PropertyOverridesDialog :
        DesignerForm, IRefreshableDeviceSpecificEditor, IDeviceSpecificDesigner 
    { 
        private bool _isDirty = true;
        private IDeviceSpecificDesigner _designer; 
        private int _mergingContext;
        private System.Windows.Forms.Control _header;
        private String _currentDeviceSpecificID;
        private IDictionary _cachedDeviceSpecifics = 
            new HybridDictionary(true /* make case-insensitive */);
        private bool _ignoreSelectionChanged = true; 
 
        private System.Windows.Forms.Label _lblProperties;
        private System.Windows.Forms.PropertyGrid _pgProperties; 
        private System.Windows.Forms.Button _btnEditFilters;
        private System.Windows.Forms.ComboBox _cbChoices;
        private System.Windows.Forms.Label _lblAppliedFilters;
        private System.Windows.Forms.Button _cmdOK; 
        private System.Windows.Forms.Button _cmdCancel;
        private System.Windows.Forms.Panel _pnlMain; 
 
        internal PropertyOverridesDialog(
            IDeviceSpecificDesigner designer, 
            int mergingContext
        ) : base(designer.UnderlyingControl.Site) {
            _designer = designer;
            _mergingContext = mergingContext; 

            // Required for Win Form Designer support 
            InitializeComponent(); 

            this._lblAppliedFilters.Text = 
                SR.GetString(SR.PropertyOverridesDialog_AppliedDeviceFilters);
            this._btnEditFilters.Text = SR.GetString(SR.GenericDialog_Edit);
            this._lblProperties.Text =
                SR.GetString(SR.PropertyOverridesDialog_DeviceSpecificProperties); 
            this._cmdOK.Text = SR.GetString(SR.GenericDialog_OKBtnCaption);
            this._cmdCancel.Text = SR.GetString(SR.GenericDialog_CancelBtnCaption); 
 
            int tabOffset = GenericUI.InitDialog(
                this, 
                _designer,
                _mergingContext
            );
 
            this.Text = _designer.UnderlyingControl.ID
                + " - " + SR.GetString(SR.PropertyOverridesDialog_Title); 
            SetTabIndexes(tabOffset); 
            _designer.SetDeviceSpecificEditor(this);
 
            // Note that the following can cause an
            // IDeviceSpecificDesigner.Refresh() to occur as a side-effect.
            _designer.RefreshHeader(_mergingContext);
            _ignoreSelectionChanged = false; 

            // NOTE: Calling CurrentDeviceSpecificID will cause a refresh to 
            //       happen as a side effect. 
            _currentDeviceSpecificID = _designer.CurrentDeviceSpecificID;
            if(_currentDeviceSpecificID != null) 
            {
                _cbChoices.Items.Clear();
                LoadChoices(_currentDeviceSpecificID);
                if(!ValidateLoadedChoices()) 
                {
                    // Throw to prevent dialog from opening.  Caught and hidden 
                    // by PropertyOverridesTypeEditor.cs 
                    throw new InvalidChoiceException(
                        "Property overrides dialog can not open because there " + 
                        "are invalid choices defined in the page."
                    );
                }
            } 

            // Register Event Handlers 
            _cbChoices.SelectedIndexChanged += new EventHandler( 
                OnFilterSelected
            ); 
            _btnEditFilters.Click += new EventHandler(OnEditFilters);
            _cmdOK.Click += new EventHandler(OnOK);
            _cmdCancel.Click += new EventHandler(OnCancel);
            UpdateUI(); 
        }
 
        protected override string HelpTopic { 
            get {
                return "net.Mobile.PropertyOverridesDialog"; 
            }
        }

        internal void SetTabIndexes(int tabOffset) 
        {
            this._pnlMain.TabIndex = ++tabOffset; 
            this._lblAppliedFilters.TabIndex = ++tabOffset; 
            this._cbChoices.TabIndex = ++tabOffset;
            this._btnEditFilters.TabIndex = ++tabOffset; 
            this._lblProperties.TabIndex = ++tabOffset;
            this._pgProperties.TabIndex = ++tabOffset;
            this._cmdOK.TabIndex = ++tabOffset;
            this._cmdCancel.TabIndex = ++tabOffset; 
        }
 
        private void InitializeComponent() 
        {
            this._cbChoices = new System.Windows.Forms.ComboBox(); 
            this._cmdOK = new System.Windows.Forms.Button();
            this._btnEditFilters = new System.Windows.Forms.Button();
            this._pnlMain = new System.Windows.Forms.Panel();
            this._pgProperties = new System.Windows.Forms.PropertyGrid(); 
            this._lblProperties = new System.Windows.Forms.Label();
            this._lblAppliedFilters = new System.Windows.Forms.Label(); 
            this._cmdCancel = new System.Windows.Forms.Button(); 
            this._cbChoices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
            this._cbChoices.DropDownWidth = 195; 
            this._cbChoices.Location = new System.Drawing.Point(0, 16);
            this._cbChoices.Size = new System.Drawing.Size(195, 21);
            this._cmdOK.Location = new System.Drawing.Point(120, 290);
            this._cmdCancel.Location = new System.Drawing.Point(201, 290); 
            this._btnEditFilters.Location = new System.Drawing.Point(201, 15);
            this._btnEditFilters.Size = new System.Drawing.Size(75, 23); 
            this._pnlMain.Anchor = (System.Windows.Forms.AnchorStyles.Bottom 
                | System.Windows.Forms.AnchorStyles.Left);
            this._pnlMain.Controls.AddRange(new System.Windows.Forms.Control[] { 
                this._cmdCancel,
                this._cmdOK,
                this._lblProperties,
                this._pgProperties, 
                this._btnEditFilters,
                this._cbChoices, 
                this._lblAppliedFilters}); 
            this._pnlMain.Location = new System.Drawing.Point(6, 5);
            this._pnlMain.Size = new System.Drawing.Size(276, 313); 
            this._pgProperties.CommandsVisibleIfAvailable = false;
            this._pgProperties.HelpVisible = false;
            this._pgProperties.LargeButtons = false;
            this._pgProperties.LineColor = System.Drawing.SystemColors.ScrollBar; 
            this._pgProperties.Location = new System.Drawing.Point(0, 64);
            this._pgProperties.PropertySort = System.Windows.Forms.PropertySort.Alphabetical; 
            this._pgProperties.Size = new System.Drawing.Size(275, 220); 
            this._pgProperties.Text = "PropertyGrid";
            this._pgProperties.ToolbarVisible = false; 
            this._pgProperties.ViewBackColor = System.Drawing.SystemColors.Window;
            this._pgProperties.ViewForeColor = System.Drawing.SystemColors.WindowText;
            this._pgProperties.PropertyValueChanged += new PropertyValueChangedEventHandler(this.OnPropertyValueChanged);
            this._lblProperties.Location = new System.Drawing.Point(0, 48); 
            this._lblProperties.Size = new System.Drawing.Size(275, 16);
            this._lblAppliedFilters.Size = new System.Drawing.Size(275, 16); 
            this.AcceptButton = _cmdOK; 
            this.CancelButton = _cmdCancel;
            this.ClientSize = new System.Drawing.Size(285, 325); 
            this.Controls.AddRange(new System.Windows.Forms.Control[] {this._pnlMain});
        }

        private void CacheState(String deviceSpecificID) 
        {
            _cachedDeviceSpecifics[deviceSpecificID] = 
                new PropertyOverridesCachedState(_cbChoices); 
        }
 
        private void CacheCurrentState()
        {
            CacheState(_currentDeviceSpecificID);
        } 

        private bool RestoreState(String deviceSpecificID) 
        { 
            if (null != deviceSpecificID)
            { 
                _currentDeviceSpecificID = deviceSpecificID.ToLower(CultureInfo.InvariantCulture);
                PropertyOverridesCachedState state =
                    (PropertyOverridesCachedState) _cachedDeviceSpecifics[
                        _currentDeviceSpecificID 
                    ];
                if(state != null) 
                { 
                    state.Restore(_cbChoices);
                    foreach(ChoiceTreeNode node in state.Choices) 
                    {
                        node.Choice.Refresh();
                    }
                    return true; 
                }
            } 
            else 
            {
                _currentDeviceSpecificID = null; 
            }
            return false;
        }
 
        [Conditional("DEBUG")]
        private void debug_CheckChoicesForDuplicate(DeviceSpecificChoice runtimeChoice) 
        { 
            foreach(ChoiceTreeNode choiceNode in _cbChoices.Items)
            { 
                if(choiceNode.Name == runtimeChoice.Filter
                    && choiceNode.RuntimeChoice.Argument == runtimeChoice.Argument)
                {
                    Debug.Fail("Loaded duplicate choice: " + 
                        DesignerUtility.ChoiceToUniqueIdentifier(runtimeChoice));
                } 
            } 
        }
 
        private void LoadChoices(String deviceSpecificID)
        {
            DeviceSpecific ds;
            _designer.GetDeviceSpecific(deviceSpecificID, out ds); 
            LoadChoices(ds);
        } 
 
        private void LoadChoices(DeviceSpecific deviceSpecific)
        { 
            if(deviceSpecific != null)
            {
                foreach(DeviceSpecificChoice runtimeChoice in deviceSpecific.Choices)
                { 
                    debug_CheckChoicesForDuplicate(runtimeChoice);
                    ChoiceTreeNode newChoiceNode = new ChoiceTreeNode( 
                        null, 
                        runtimeChoice,
                        _designer 
                    );
                    newChoiceNode.IncludeArgument = true;
                    _cbChoices.Items.Add(newChoiceNode);
                } 
            }
            UpdateUI(); 
        } 

        private bool ValidateLoadedChoices() 
        {
            StringCollection duplicateChoices =
                DesignerUtility.GetDuplicateChoiceTreeNodes(
                    _cbChoices.Items 
                );
 
            if(duplicateChoices.Count > 0) 
            {
                if (!_ignoreSelectionChanged) 
                {
                    GenericUI.ShowWarningMessage(
                        SR.GetString(SR.PropertyOverridesDialog_Title),
                        SR.GetString(SR.PropertyOverridesDialog_DuplicateChoices, 
                        GenericUI.BuildCommaDelimitedList(duplicateChoices))
                        ); 
                } 
                return false;
            } 
            return true;
        }

        private void SaveChoices() 
        {
            if(_currentDeviceSpecificID != null) 
            { 
                CacheCurrentState();
            } 
            foreach (DictionaryEntry entry in _cachedDeviceSpecifics)
            {
                PropertyOverridesCachedState state =
                    (PropertyOverridesCachedState) entry.Value; 
                state.SaveChoicesFromComboBox(
                    _designer, 
                    (String) entry.Key 
                );
            } 
        }

        private void UpdateUI()
        { 
            if(_cbChoices.SelectedItem == null && _cbChoices.Items.Count > 0)
            { 
                _cbChoices.SelectedItem = _cbChoices.Items[0]; 
            }
 
            ChoiceTreeNode choice = (ChoiceTreeNode) _cbChoices.SelectedItem;
            bool isChoiceSelected = (choice != null);
            if (isChoiceSelected)
            { 
                _cbChoices.Text = choice.ToString();
                _pgProperties.SelectedObject = 
                    choice.Choice; 
            }
            else 
            {
                _cbChoices.Text = String.Empty;
                _pgProperties.SelectedObject = null;
            } 
            _cbChoices.Enabled = isChoiceSelected;
            _pgProperties.Enabled = isChoiceSelected; 
            _btnEditFilters.Enabled = (_currentDeviceSpecificID != null); 
        }
 
        private void SetDirty(bool dirty)
        {
            if (dirty)
            { 
                if (false == _isDirty)
                { 
                    _isDirty = true; 
                    _cmdCancel.Text = SR.GetString(SR.GenericDialog_CancelBtnCaption);
                } 
            }
            else
            {
                if (true == _isDirty) 
                {
                    _isDirty = false; 
                    _cmdCancel.Text = SR.GetString(SR.GenericDialog_CloseBtnCaption); 
                }
            } 
        }

        ////////////////////////////////////////////////////////////////////////
        //  Begin Event Handling 
        ////////////////////////////////////////////////////////////////////////
 
        private void OnEditFilters(Object sender, EventArgs e) 
        {
            ISite componentSite = ((IComponent)(_designer.UnderlyingControl)).Site; 
            Debug.Assert(componentSite != null, "Expected the runtime control to be sited.");

            IComponentChangeService changeService =
                (IComponentChangeService)componentSite.GetService(typeof(IComponentChangeService)); 

            IMobileWebFormServices wfServices = 
                (IMobileWebFormServices)componentSite.GetService(typeof(IMobileWebFormServices)); 

            DialogResult result = DialogResult.Cancel; 
            try
            {
                AppliedDeviceFiltersDialog dialog = new
                    AppliedDeviceFiltersDialog( 
                    this,
                    _mergingContext 
                    ); 

                result = dialog.ShowDialog(); 
            }
            finally
            {
                if (result != DialogResult.Cancel) 
                {
                    SaveChoices(); 
                    SetDirty(false); 

                    if (changeService != null) 
                    {
                        changeService.OnComponentChanged(_designer.UnderlyingControl, null, null, null);
                    }
                } 
            }
        } 
 
        private void OnFilterSelected(Object sender, EventArgs e)
        { 
            UpdateUI();
        }

        private void OnOK(Object sender, EventArgs e) 
        {
            SaveChoices(); 
            Close(); 
            DialogResult = DialogResult.OK;
        } 

        private void OnCancel(Object sender, EventArgs e)
        {
            Close(); 
            DialogResult = DialogResult.Cancel;
        } 
 
        private void OnPropertyValueChanged(Object sender,
                                            PropertyValueChangedEventArgs e) 
        {
            SetDirty(true);
        }
 
        ////////////////////////////////////////////////////////////////////////
        //  End Event Handling 
        //////////////////////////////////////////////////////////////////////// 

        //////////////////////////////////////////////////////////////////////// 
        //  Begin IRefreshableComponentEditor Implementation
        ////////////////////////////////////////////////////////////////////////

        bool IRefreshableDeviceSpecificEditor.RequestRefresh() 
        {
            return true; 
        } 

        void IRefreshableDeviceSpecificEditor.Refresh( 
            String deviceSpecificID,
            DeviceSpecific deviceSpecific
        ) {
            if (_currentDeviceSpecificID != null) 
            {
                CacheCurrentState(); 
            } 
            _cbChoices.Items.Clear();
 
            if (!RestoreState(deviceSpecificID))
            {
                LoadChoices(deviceSpecific);
                if(!ValidateLoadedChoices()) 
                {
                    _designer.RefreshHeader( 
                        MobileControlDesigner.MergingContextProperties 
                    );
                } 
            }
            UpdateUI();
        }
 
        void IRefreshableDeviceSpecificEditor.UnderlyingObjectsChanged()
        { 
            SaveChoices(); 
            SetDirty(false);
        } 

        private bool InExternalCacheEditMode
        {
            get 
            {
                return _cacheBuffer != null; 
            } 
        }
 
        private IDictionary _cacheBuffer = null;

        void IRefreshableDeviceSpecificEditor.BeginExternalDeviceSpecificEdit()
        { 
            Debug.Assert(!InExternalCacheEditMode,
                "Call to BeginExternalDeviceSpecificEdit() while already in external " 
                + "cache edit mode."); 
            if(_currentDeviceSpecificID != null)
            { 
                CacheCurrentState();
                _currentDeviceSpecificID = null;
            }
            _cacheBuffer = new HybridDictionary( 
                true /* make case-insensitive*/ );
            foreach(DictionaryEntry entry in _cachedDeviceSpecifics) 
            { 
                _cacheBuffer.Add(entry.Key, entry.Value);
            } 
        }

        void IRefreshableDeviceSpecificEditor.EndExternalDeviceSpecificEdit(
            bool commitChanges) 
        {
            Debug.Assert(InExternalCacheEditMode, 
                "Call to EndExternalDeviceSpecificEdit() while not in external " 
                + "cache edit mode.");
            if(commitChanges) 
            {
                _cachedDeviceSpecifics = _cacheBuffer;
            }
            _cacheBuffer = null; 
        }
 
        void IRefreshableDeviceSpecificEditor.DeviceSpecificRenamed( 
            String oldDeviceSpecificID, String newDeviceSpecificID)
        { 
            Debug.Assert(InExternalCacheEditMode,
                "Call to DeviceSpecificRenamed() while not in external "
                + "cache edit mode.");
            Object value = _cacheBuffer[oldDeviceSpecificID]; 
            if(value != null)
            { 
                _cacheBuffer.Remove(oldDeviceSpecificID); 
                _cacheBuffer.Add(newDeviceSpecificID, value);
            } 
        }

        void IRefreshableDeviceSpecificEditor.DeviceSpecificDeleted(
            String deviceSpecificID) 
        {
            Debug.Assert(InExternalCacheEditMode, 
                "Call to DeviceSpecificDeleted() while not in external " 
                + "cache edit mode.");
            _cacheBuffer.Remove(deviceSpecificID); 
        }

        ////////////////////////////////////////////////////////////////////////
        //  End IRefreshableComponentEditor Implementation 
        ////////////////////////////////////////////////////////////////////////
 
        //////////////////////////////////////////////////////////////////////// 
        //  Begin IDeviceSpecificDesigner Implementation
        //////////////////////////////////////////////////////////////////////// 

        void IDeviceSpecificDesigner.SetDeviceSpecificEditor
            (IRefreshableDeviceSpecificEditor editor)
        { 
        }
 
        String IDeviceSpecificDesigner.CurrentDeviceSpecificID 
        {
            get 
            {
                return _currentDeviceSpecificID;
            }
        } 

        System.Windows.Forms.Control IDeviceSpecificDesigner.Header 
        { 
            get
            { 
                return _header;
            }
        }
 
        System.Web.UI.Control IDeviceSpecificDesigner.UnderlyingControl
        { 
            get 
            {
                return _designer.UnderlyingControl; 
            }
        }

        Object IDeviceSpecificDesigner.UnderlyingObject 
        {
            get 
            { 
                return _designer.UnderlyingObject;
            } 
        }

        bool IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds)
        { 
            Debug.Assert(deviceSpecificParentID == _currentDeviceSpecificID);
 
            ds = null; 
            if (_cbChoices.Items.Count > 0)
            { 
                ds = new DeviceSpecific();
                foreach (ChoiceTreeNode choiceNode in _cbChoices.Items)
                {
                    DeviceSpecificChoice choice = choiceNode.Choice.RuntimeChoice; 
                    ds.Choices.Add(choice);
                } 
            } 

            return true; 
        }

        void IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds)
        { 
            Debug.Assert(_currentDeviceSpecificID != null);
            _cbChoices.Items.Clear(); 
            LoadChoices(ds); 
            UpdateUI();
        } 

        void IDeviceSpecificDesigner.InitHeader(int mergingContext)
        {
            HeaderPanel panel = new HeaderPanel(); 
            HeaderLabel lblDescription = new HeaderLabel();
 
            lblDescription.TabIndex = 0; 
            lblDescription.Text = SR.GetString(SR.MobileControl_SettingGenericChoiceDescription);
 
            panel.Height = lblDescription.Height;
            panel.Width = lblDescription.Width;
            panel.Controls.Add(lblDescription);
            _header = panel; 
        }
 
        void IDeviceSpecificDesigner.RefreshHeader(int mergingContext) 
        {
        } 

        void IDeviceSpecificDesigner.UseCurrentDeviceSpecificID()
        {
        } 

        ///////////////////////////////////////////////////////////////////////// 
        //  End IDeviceSpecificDesigner Implementation 
        /////////////////////////////////////////////////////////////////////////
    } 

    ////////////////////////////////////////////////////////////////////////////
    //  Begin Internal Class
    //////////////////////////////////////////////////////////////////////////// 

    [ 
        System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, 
        Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
    ] 
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
    internal class ChoicePropertyFilter :
        ICustomTypeDescriptor, IDeviceSpecificChoiceDesigner, IComponent
    { 
        private DeviceSpecificChoice _choice;
        private Object _copyOfOriginalObject; 
        private Object _underlyingObject; 
        private IDeviceSpecificDesigner _designer;
        private Hashtable _specialProp_buffer = new Hashtable(); 
        private EventHandler _specialProp_delegate = null;
        private ISite _site = null;
        private EventHandlerList _events;
        private static readonly Object _eventDisposed = new Object(); 
        private static readonly String _alternateUrl = "AlternateUrl";
        private static readonly String _navigateUrl = "NavigateUrl"; 
 
        internal ChoicePropertyFilter(
            DeviceSpecificChoice choice, 
            IDeviceSpecificDesigner designer,
            ISite site
        ) {
            _events = new EventHandlerList(); 
            _choice = choice;
            _site = site; 
            _designer = designer; 

            CreateLocalCopiesOfObjects(); 
        }

        private void CreateLocalCopiesOfObjects()
        { 
            // We make this copy of the original to remove the object from
            // the inheritance chain. 
            _copyOfOriginalObject = CloneTarget(_designer.UnderlyingObject); 
            _underlyingObject = CloneTarget(_designer.UnderlyingObject);
 
            // We need to pop up editors when certain property values change
            RegisterForPropertyChangeEvents();

            // Copy properties set on DeviceSpecificChoice 
            ApplyChoiceToRuntimeControl();
        } 
 
        internal void Refresh()
        { 
            ApplyChangesToRuntimeChoice();
            CreateLocalCopiesOfObjects();
        }
 
        private void RegisterForPropertyChangeEvents()
        { 
            foreach(PropertyDescriptor property in TypeDescriptor.GetProperties( 
                _underlyingObject.GetType()
            )) { 
                if(property.Converter is NavigateUrlConverter &&
                   (property.Name == _navigateUrl ||
                    property.Name == _alternateUrl))
                { 
                    //
 
                    if (property.Name == _navigateUrl) 
                    {
                        _specialProp_delegate = new EventHandler(OnNavigateUrlChanged); 
                    }
                    else
                    {
                        _specialProp_delegate = new EventHandler(OnAlternateUrlChanged); 
                    }
                    _specialProp_buffer[property.Name] = property.GetValue(_underlyingObject); 
                    property.AddValueChanged( 
                        _underlyingObject,
                        _specialProp_delegate 
                    );
                }
            }
        } 

        private Object CloneTarget(Object target) 
        { 
            Object clone = Activator.CreateInstance(
                target.GetType() 
            );
            // We need to copy the Site over to the new object incase setting
            // properties has a side effect that requires the component model
            // to be intact.  (e.g., Launching UrlPicker for NavigateUrl). 
            if(clone is IComponent)
            { 
                ((IComponent)clone).Site = ((IComponent)target).Site; 
            }
            // We also need to copy the Page over in case runtime properties 
            // try to access the page.
            if(clone is System.Web.UI.Control)
            {
                ((Control)clone).Page = ((Control)target).Page; 
            }
            CopyOverridableProperties(target, clone); 
            return clone; 
        }
 
        private void CopyStyleProperties(Style source, Style dest)
        {
            // We copy the StateBag to duplicate the style properties without
            // walking the inheritance. 
            dest.State.Clear();
            foreach(String key in source.State.Keys) 
            { 
                dest.State[key] = source.State[key];
            } 
        }

        private void CopyOverridableProperties(Object source, Object dest)
        { 
            MobileControl destControl = null;
 
            // HACK: To avoid copying expandable property FontInfo.  We will 
            //       need to required that expandable properties implement
            //       ICloneable for our designer extensibility story. 
            if(source is Style)
            {
                CopyStyleProperties((Style)source, (Style)dest);
                return; 
            }
 
            if(source is MobileControl) 
            {
                // If the control is a MobileControl, we copy the style's 
                // StateBag to get the non-inherited proprety values.
                destControl = (MobileControl) dest;
                MobileControl sourceControl = (MobileControl) source;
                CopyStyleProperties(sourceControl.Style, destControl.Style); 
            }
 
            // Copy remaining properties not contained in the style (or 
            // all properties if not a mobile control.)
            PropertyDescriptorCollection properties = 
                TypeDescriptor.GetProperties(dest.GetType());
            foreach(PropertyDescriptor property in properties)
            {
                if(IsDeviceOverridable(property) 
                    && (destControl == null
                    || !PropertyExistsInStyle(property, destControl.Style))) 
                { 
                    CopyProperty(property, source, dest);
                } 
            }
        }

        private void CopyProperty(PropertyDescriptor property, 
            Object source,
            Object dest) 
        { 
            Object value = property.GetValue(source);
 
            if(property.Converter is ExpandableObjectConverter)
            {
                if(value is ICloneable)
                { 
                    value = ((ICloneable)value).Clone();
                } 
                else 
                {
                    throw new Exception( 
                        SR.GetString(
                            SR.PropertyOverridesDialog_NotICloneable,
                            property.Name,
                            property.PropertyType.FullName 
                        )
                    ); 
                } 
            }
            property.SetValue(dest, value); 
        }

        private bool PropertyExistsInStyle(
            PropertyDescriptor property, Style style) 
        {
            return style.GetType().GetProperty(property.Name) != null; 
        } 

        public event EventHandler Disposed 
        {
            add
            {
                _events.AddHandler(_eventDisposed, value); 
            }
            remove 
            { 
                _events.RemoveHandler(_eventDisposed, value);
            } 
        }

        public ISite Site
        { 
            get
            { 
                Debug.Assert(_site != null); 
                return _site;
            } 

            set
            {
                _site = value; 
            }
        } 
 
        public void Dispose()
        { 
            if (_events != null)
            {
                EventHandler handler = (EventHandler)_events[_eventDisposed];
                if (handler != null) handler(this, EventArgs.Empty); 
            }
        } 
 
        private void OnNavigateUrlChanged(Object sender, EventArgs e)
        { 
            OnSpecialPropertyChanged(sender, true);
        }

        private void OnAlternateUrlChanged(Object sender, EventArgs e) 
        {
            OnSpecialPropertyChanged(sender, false); 
        } 

        // 


        private void OnSpecialPropertyChanged(Object sender, bool navigateUrl)
        { 
            IComponent component = (IComponent) sender;
            PropertyDescriptor property 
                = TypeDescriptor.GetProperties(component)[navigateUrl ? _navigateUrl : _alternateUrl]; 
            String newValue = (String) property.GetValue(component);
            String oldValue = (String) _specialProp_buffer[navigateUrl ? _navigateUrl : _alternateUrl]; 
            newValue = NavigateUrlConverter.GetUrl(
                component,
                newValue,
                oldValue 
            );
            property.RemoveValueChanged( 
                _underlyingObject, 
                _specialProp_delegate
            ); 
            property.SetValue(component, newValue);
            property.AddValueChanged(
                _underlyingObject,
                _specialProp_delegate 
            );
        } 
 
        private static bool IsDeviceOverridable(PropertyDescriptor property)
        { 
            //
            return (
                property.IsBrowsable
                && ((!property.IsReadOnly) 
                    || (property.Converter is ExpandableObjectConverter))
                && !property.SerializationVisibility.Equals( 
                     DesignerSerializationVisibility.Hidden) 
                && property.Name != "ID"
            ); 
        }

        private void ApplyChoiceToRuntimeControl()
        { 
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties( 
                    _underlyingObject.GetType()); 

            foreach(PropertyDescriptor property in properties) 
            {
                if(IsDeviceOverridable(property))
                {
                    ApplyChoiceToRuntimeControl_helper( 
                        property,
                        _underlyingObject, 
                        "" 
                    );
                } 
            }
        }

        private void ApplyChoiceToRuntimeControl_helper( 
            PropertyDescriptor property,
            Object target, 
            String prefix 
        ) {
            String propertyName = prefix + property.Name; 
            String value = ((IAttributeAccessor)_choice).GetAttribute(propertyName) as String;

            if(property.Converter is ExpandableObjectConverter)
            { 
                PropertyDescriptorCollection properties =
                    TypeDescriptor.GetProperties( 
                        property.PropertyType 
                    );
                foreach(PropertyDescriptor embeddedProperty in properties) 
                {
                    if(IsDeviceOverridable(embeddedProperty))
                    {
                        ApplyChoiceToRuntimeControl_helper( 
                            embeddedProperty,
                            property.GetValue(target), 
                            propertyName + "-" 
                        );
                    } 
                }
                return;
            }
 
            if(value != null)
            { 
                try 
                {
                    property.SetValue( 
                        target,
                        property.Converter.ConvertFromString(value)
                    );
                } 
                catch
                { 
                    GenericUI.ShowWarningMessage( 
                        SR.GetString(SR.PropertyOverridesDialog_Title),
                        SR.GetString( 
                            SR.PropertyOverridesDialog_InvalidPropertyValue,
                            value,
                            propertyName
                        ) 
                    );
                } 
            } 
        }
 
        private void ApplyChangesToRuntimeChoice()
        {
            PropertyDescriptorCollection properties =
                TypeDescriptor.GetProperties( 
                    _underlyingObject.GetType()
                ); 
 
            foreach(PropertyDescriptor property in properties)
            { 
                if (IsDeviceOverridable(property))
                {
                    ApplyChangesToRuntimeChoice_helper(
                        property, 
                        _copyOfOriginalObject,
                        _underlyingObject, 
                        ""); 
                }
            } 
        }

        private void ApplyChangesToRuntimeChoice_helper(
            PropertyDescriptor property, 
            Object sourceTarget,
            Object destTarget, 
            String prefix 
        ) {
            Object oldValue = property.GetValue(sourceTarget); 
            Object newValue = property.GetValue(destTarget);

            String propertyName = prefix + property.Name;
 
            if(property.Converter is ExpandableObjectConverter)
            { 
                PropertyDescriptorCollection properties = 
                    TypeDescriptor.GetProperties(
                        newValue.GetType() 
                    );
                foreach(PropertyDescriptor embeddedProperty in properties)
                {
                    if(IsDeviceOverridable(embeddedProperty)) 
                    {
                        ApplyChangesToRuntimeChoice_helper( 
                            embeddedProperty, 
                            oldValue,
                            newValue, 
                            propertyName + "-"
                        );
                    }
                } 
            }
            else if(IsDeviceOverridable(property)) 
            { 
                IAttributeAccessor overrides = (IAttributeAccessor)_choice;
                String oldValueString = 
                    property.Converter.ConvertToInvariantString(
                        oldValue
                    );
                String newValueString = 
                    property.Converter.ConvertToInvariantString(
                        newValue 
                    ); 
                if(newValueString != oldValueString)
                { 
                    overrides.SetAttribute(propertyName, newValueString);
                }
                else
                { 
                    // Clear any previous values we might have loaded
                    overrides.SetAttribute(propertyName, null); 
                } 
            }
        } 

        internal DeviceSpecificChoice RuntimeChoice
        {
            get 
            {
                ApplyChangesToRuntimeChoice(); 
                return _choice; 
            }
        } 

        internal IDeviceSpecificDesigner Designer
        {
            get 
            {
                return _designer; 
            } 
        }
 
        internal Object Owner
        {
            get
            { 
                return _underlyingObject;
            } 
        } 

        private PropertyDescriptorCollection PreFilterProperties( 
            PropertyDescriptorCollection originalProperties
        ) {
            PropertyDescriptorCollection newProperties =
                new PropertyDescriptorCollection( 
                    new PropertyDescriptor[] {}
                ); 
 
            foreach(PropertyDescriptor property in originalProperties)
            { 
                if (IsDeviceOverridable(property))
                {
                    newProperties.Add(property);
                } 
            }
 
            PropertyDescriptor[] arpd = new PropertyDescriptor[newProperties.Count]; 
            for(int i = 0; i < newProperties.Count; i++)
            { 
                arpd[i] = newProperties[i];
            }
            newProperties = new PropertyDescriptorCollection(arpd);
 
            return newProperties;
        } 
 
        ////////////////////////////////////////////////////////////////////
        //  Begin ICustomTypeDescriptor Implementation 
        ////////////////////////////////////////////////////////////////////

        System.ComponentModel.AttributeCollection ICustomTypeDescriptor.GetAttributes()
        { 
            return TypeDescriptor.GetAttributes(this.GetType());
        } 
 
        String ICustomTypeDescriptor.GetClassName()
        { 
            return TypeDescriptor.GetClassName(this.GetType());
        }

        String ICustomTypeDescriptor.GetComponentName() 
        {
            return TypeDescriptor.GetComponentName(this.GetType()); 
        } 

        TypeConverter ICustomTypeDescriptor.GetConverter() 
        {
            return TypeDescriptor.GetConverter(this.GetType());
        }
 
        EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
        { 
            return TypeDescriptor.GetDefaultEvent(this.GetType()); 
        }
 
        PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this.GetType());
        } 

        Object ICustomTypeDescriptor.GetEditor(Type editorBaseType) 
        { 
            return TypeDescriptor.GetEditor(this.GetType(), editorBaseType);
        } 

        EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
        {
            return TypeDescriptor.GetEvents(this.GetType()); 
        }
 
        EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) 
        {
            return TypeDescriptor.GetEvents(this.GetType(), attributes); 
        }

        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
        { 
            PropertyDescriptorCollection collection =
                TypeDescriptor.GetProperties( 
                    _underlyingObject.GetType() 
                );
            collection = PreFilterProperties(collection); 
            return collection;
        }

        PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) 
        {
            PropertyDescriptorCollection collection = 
                TypeDescriptor.GetProperties( 
                    _underlyingObject.GetType(),
                    attributes 
                );
            collection = PreFilterProperties(collection);
            return collection;
        } 

        Object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor property) 
        { 
            return _underlyingObject;
        } 

        ////////////////////////////////////////////////////////////////////////
        //  End ICustomTypeDescriptor Implementation
        //////////////////////////////////////////////////////////////////////// 

        /////////////////////////////////////////////////////////////////////// 
        //  Begin IDeviceSpecificChoiceDesigner Implementation 
        ///////////////////////////////////////////////////////////////////////
 
        Object IDeviceSpecificChoiceDesigner.UnderlyingObject
        {
            get
            { 
                return _designer.UnderlyingObject;
            } 
        } 

        Control IDeviceSpecificChoiceDesigner.UnderlyingControl 
        {
            get
            {
                return _designer.UnderlyingControl; 
            }
        } 
 
        ///////////////////////////////////////////////////////////////////////
        //  End IDeviceSpecificChoiceDesigner Implementation 
        ///////////////////////////////////////////////////////////////////////
    }

    //////////////////////////////////////////////////////////////////////////// 
    //  End Internal Class
    //////////////////////////////////////////////////////////////////////////// 
    ///////////////////////////////////////////////////////////////////////// 
    //  Begin Internal Class
    ///////////////////////////////////////////////////////////////////////// 

    [
        System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
        Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 
    ]
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 
    internal class PropertyOverridesCachedState : DeviceSpecificDialogCachedState 
    {
        private ArrayList _cachedComboBox = null; 

        internal PropertyOverridesCachedState(
            ComboBox comboBox
        ) { 
            _cachedComboBox = new ArrayList();
            foreach(Object o in comboBox.Items) 
            { 
                _cachedComboBox.Add(o);
            } 
        }

        internal void Restore(
            ComboBox comboBox 
        ) {
            Object selectedItem = comboBox.SelectedItem; 
            comboBox.Items.Clear(); 
            comboBox.Items.AddRange(_cachedComboBox.ToArray());
            if(selectedItem != null) 
            {
                int index = comboBox.Items.IndexOf(selectedItem);
                if(index >= 0)
                { 
                    comboBox.SelectedItem = comboBox.Items[index];
                } 
            } 
        }
 
        internal bool FilterExistsInComboBox(DeviceFilterNode filter)
        {
            foreach(DeviceFilterNode availableFilter in _cachedComboBox)
            { 
                if(availableFilter.Name == filter.Name)
                { 
                    return true; 
                }
            } 
            return false;
        }

        internal void SaveChoicesFromComboBox( 
            IDeviceSpecificDesigner designer,
            String deviceSpecificID 
        ) { 
            SaveChoices(designer, deviceSpecificID, _cachedComboBox);
        } 

        internal ArrayList Choices
        {
            get 
            {
                return _cachedComboBox; 
            } 
        }
    } 

    /////////////////////////////////////////////////////////////////////////
    //  End Internal Class
    ///////////////////////////////////////////////////////////////////////// 

    ///////////////////////////////////////////////////////////////////////// 
    //  Begin Internal Class 
    /////////////////////////////////////////////////////////////////////////
 
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
    internal class InvalidChoiceException : ApplicationException
    {
        internal InvalidChoiceException(String message) : base(message) 
        {
        } 
    } 

    ///////////////////////////////////////////////////////////////////////// 
    //  End Internal Class
    /////////////////////////////////////////////////////////////////////////
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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