StyleSheetDesigner.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / MIT / System / Web / UI / MobileControls / Design / StyleSheetDesigner.cs / 1305376 / StyleSheetDesigner.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.Diagnostics; 
    using System.Drawing.Design;
    using System.Globalization; 
    using System.Text; 
    using System.Web.UI;
    using System.Web.UI.Design; 
    using System.Web.UI.Design.MobileControls.Adapters;
    using System.Web.UI.Design.MobileControls.Converters;
    using System.Web.UI.Design.MobileControls.Util;
    using System.Web.UI.MobileControls; 
    using System.Windows.Forms;
 
    using Control = System.Web.UI.Control; 
    using DataBindingCollectionEditor = System.Web.UI.Design.DataBindingCollectionEditor;
 
    [
        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 StyleSheetDesigner : MobileTemplatedControlDesigner, IDeviceSpecificDesigner 
    { 
        internal static BooleanSwitch StyleSheetDesignerSwitch =
            new BooleanSwitch("StyleSheetDesigner", "Enable StyleSheet designer general purpose traces."); 

        private IWebFormsDocumentService _iWebFormsDocumentService;
        private IRefreshableDeviceSpecificEditor _deviceSpecificEditor;
        private DesignerVerbCollection _designerVerbs; 
        private System.Web.UI.MobileControls.StyleSheet _styleSheet;
        private Style _currentStyle, _tmpCurrentStyle; 
        private bool _isDuplicate; 
        private MergedUI _mergedUI = null;
        private ArrayList _cycledStyles = null; 
        private const int _templateWidth = 300;
        private static bool _requiresDesignTimeChanges = false;
        private bool _shouldRepersistStyles = false;
        private EventHandler _loadComplete = null; 

        private const String _templatesStylePropName = "TemplateStyle"; 
        private const String _persistedStylesPropName = "PersistedStyles"; 

        private const String _designTimeHTML = 
            @"
                
StyleSheet - {0}
Template Style:{1}
Template Device Filter:{2}
{3}
"; private const String _specialCaseDesignTimeHTML = @"
StyleSheet - {0}
Template Style:{1}
Template Device Filter:{2}
{3}
{5}
"; private const int _headerFooterTemplates = 0; private const int _itemTemplates = 1; private const int _separatorTemplate = 2; private const int _contentTemplate = 3; private const int _numberOfTemplateFrames = 4; private static readonly String[][] _templateFrameNames = new String[][] { new String [] { Constants.HeaderTemplateTag, Constants.FooterTemplateTag }, new String [] { Constants.ItemTemplateTag, Constants.AlternatingItemTemplateTag, Constants.ItemDetailsTemplateTag }, new String [] { Constants.SeparatorTemplateTag }, new String [] { Constants.ContentTemplateTag } }; private const String _templateStyle = "__TemplateStyle__"; // used by DesignerAdapterUtil.GetMaxWidthToFit // and needs to be exposed in object model because // custom controls may need to access the value just like // DesignerAdapterUtil.GetMaxWidthToFit does. public override int TemplateWidth { get { return _templateWidth; } } private MobilePage MobilePage { get { IComponent component = DesignerAdapterUtil.GetRootComponent(Component); if (component is MobileUserControl) { return ((Control)component).Page as MobilePage; } return component as MobilePage; } } private Control RootControl { get { IComponent component = DesignerAdapterUtil.GetRootComponent(Component); return component as Control; } } /// /// /// Initializes the designer. /// /// /// /// The control element being designed. /// /// /// /// This is called by the designer host to establish the component being /// designed. /// /// /// public override void Initialize(IComponent component) { Debug.Assert(component is System.Web.UI.MobileControls.StyleSheet, "StyleSheetDesigner.Initialize - Invalid StyleSheet Control"); base.Initialize(component); _isDuplicate = false; _styleSheet = (System.Web.UI.MobileControls.StyleSheet) component; if(_requiresDesignTimeChanges) { _shouldRepersistStyles = true; } _loadComplete = new EventHandler(this.OnLoadComplete); IWebFormsDocumentService.LoadComplete += _loadComplete; if (IMobileWebFormServices != null) { TemplateStyle = (String) IMobileWebFormServices.GetCache(_styleSheet.ID, _templateStyle); TemplateDeviceFilter = (String) IMobileWebFormServices.GetCache( _styleSheet.ID, MobileTemplatedControlDesigner.DefaultTemplateDeviceFilter); } } private void OnLoadComplete(Object source, EventArgs e) { if(_shouldRepersistStyles) { IsDirty = true; OnInternalChange(); } _requiresDesignTimeChanges = false; _shouldRepersistStyles = false; UpdateDesignTimeHtml(); } internal static void SetRequiresDesignTimeChanges() { _requiresDesignTimeChanges = true; } private IWebFormsDocumentService IWebFormsDocumentService { get { if (_iWebFormsDocumentService == null) { _iWebFormsDocumentService = (IWebFormsDocumentService)GetService(typeof(IWebFormsDocumentService)); Debug.Assert(_iWebFormsDocumentService != null); } return _iWebFormsDocumentService; } } protected override ITemplateEditingFrame CreateTemplateEditingFrame(TemplateEditingVerb verb) { ITemplateEditingService teService = (ITemplateEditingService)GetService(typeof(ITemplateEditingService)); Debug.Assert(teService != null, "How did we get this far without an ITemplateEditingService"); String[] templateNames = GetTemplateFrameNames(verb.Index); ITemplateEditingFrame editingFrame = teService.CreateFrame( this, TemplateDeviceFilter + " (" + TemplateStyle + ")", templateNames, WebCtrlStyle, null /* we don't have template styles */); editingFrame.InitialWidth = _templateWidth; return editingFrame; } protected override void Dispose(bool disposing) { if (disposing) { UpdateActiveStyleSheet(); if (_loadComplete != null) { IWebFormsDocumentService.LoadComplete -= _loadComplete; _loadComplete = null; } if (IMobileWebFormServices != null) { // If the page is in loading mode, it means the remove is trigged by webformdesigner. if (!LoadComplete) { IMobileWebFormServices.SetCache(_styleSheet.ID, (Object) _templateStyle, (Object) this.TemplateStyle); } else { // setting to null will remove the entry. IMobileWebFormServices.SetCache(_styleSheet.ID, (Object) _templateStyle, null); } } } base.Dispose(disposing); } private void UpdateActiveStyleSheet() { if (MobilePage != null && MobilePage.StyleSheet == _styleSheet) { IDesigner designer = null; // currently active stylesheet is deleted MobilePage.StyleSheet = StyleSheet.Default; StyleSheet _newStyleSheet = null; Debug.Assert(RootControl != null); foreach (Control control in RootControl.Controls) { // Find new stylesheet if (control is StyleSheet && _newStyleSheet == null && control != _styleSheet) { designer = Host.GetDesigner((IComponent) control); // AUI 7285 if (designer != null) { _newStyleSheet = (StyleSheet) control; } } } MobilePage.StyleSheet = _newStyleSheet; if (null != _newStyleSheet) { Debug.Assert(designer != null); StyleSheetDesigner ssd = designer as StyleSheetDesigner; Debug.Assert(ssd != null, "ssd is null in StyleSheetDesigner"); ssd.TreatAsDuplicate(false); } RefreshPageView(); } } protected override String[] GetTemplateFrameNames(int index) { Debug.Assert(index >= 0 & index <= _templateFrameNames.Length); return _templateFrameNames[index]; } protected override TemplateEditingVerb[] GetTemplateVerbs() { TemplateEditingVerb[] templateVerbs = new TemplateEditingVerb[_numberOfTemplateFrames]; templateVerbs[_headerFooterTemplates] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_HeaderFooterTemplates), _headerFooterTemplates, this); templateVerbs[_itemTemplates] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_ItemTemplates), _itemTemplates, this); templateVerbs[_separatorTemplate] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_SeparatorTemplate), _separatorTemplate, this); templateVerbs[_contentTemplate] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_ContentTemplate), _contentTemplate, this); return templateVerbs; } /// /// /// Delegate to handle component changed event. /// /// /// /// The object sending the event. /// /// /// The event object used when firing a component changed notification. /// /// /// /// This is called after a property has been changed. It allows the implementor /// to do any post-processing that may be needed after a property change. /// /// public override void OnComponentChanged(Object sender, ComponentChangedEventArgs ce) { // Delegate to the base class implementation first! base.OnComponentChanged(sender, ce); MemberDescriptor member = ce.Member; if (member != null && member.GetType().FullName.Equals(Constants.ReflectPropertyDescriptorTypeFullName)) { PropertyDescriptor propDesc = (PropertyDescriptor)member; if (propDesc.Name.Equals("ID")) { // Update the dictionary of device filters stored in the page designer // setting to null will remove the entry. IMobileWebFormServices.SetCache(ce.OldValue.ToString(), (Object) _templateStyle, null); } } } internal void OnStylesChanged() { // If this is not a new stylesheet and it is the current stylesheet if (MobilePage != null && MobilePage.StyleSheet == _styleSheet) { // Refresh the whole page assuming styles have been changed. RefreshPageView(); ClearCycledStyles(); } } private void RefreshPageView() { if (IMobileWebFormServices != null) { IMobileWebFormServices.RefreshPageView(); } } public override void OnSetParent() { base.OnSetParent(); // This is not a MobilePage or the styleSheet is already the active styleSheet. // The latter happens when the active StyleSheet is drag/drop to another location // which forces its parent to be changed. if (MobilePage == null) { return; } if (MobilePage.StyleSheet == _styleSheet) { if (!(_styleSheet.Parent is MobilePage || _styleSheet.Parent is MobileUserControl)) { UpdateActiveStyleSheet(); } return; } if (MobilePage.StyleSheet != StyleSheet.Default) { // can't accept more than 1 stylesheet TreatAsDuplicate(true); // the current valid StyleSheet is intentionaly refreshed because // if this stylesheet instance is recreated via a Undo operation // the current valid StyleSheet appears as a duplicate if not refreshed. IDesigner designer = Host.GetDesigner((IComponent) MobilePage.StyleSheet); Debug.Assert(designer != null, "designer is null in StyleSheetDesigner"); StyleSheetDesigner ssd = (StyleSheetDesigner) designer; ssd.UpdateRendering(); } else if (_styleSheet.Parent is MobilePage || _styleSheet.Parent is MobileUserControl) { // the active stylesheet is changed MobilePage.StyleSheet = _styleSheet; _isDuplicate = false; } RefreshPageView(); } protected override void OnTemplateModeChanged() { base.OnTemplateModeChanged(); // Refresh all mobilecontrols after exit template editing mode. if (!InTemplateMode) { RefreshPageView(); } } public void TreatAsDuplicate(bool isDuplicate) { if (isDuplicate != _isDuplicate) { _isDuplicate = isDuplicate; SetTemplateVerbsDirty(); UpdateDesignTimeHtml(); } } protected override bool ErrorMode { get { return base.ErrorMode || _isDuplicate || _styleSheet.DuplicateStyles.Count > 0; } } private StringCollection GetDuplicateStyleNames() { StringCollection duplicateNamesList = new StringCollection(); // Filter out repeated duplicate names using case insensitive // hash table HybridDictionary duplicateNamesHash = new HybridDictionary( true /* Names not case sensitive */ ); foreach(Style style in _styleSheet.DuplicateStyles) { duplicateNamesHash[style.Name] = true; } // Copy remaining names into a string list foreach(DictionaryEntry entry in duplicateNamesHash) { duplicateNamesList.Add((String)entry.Key); } return duplicateNamesList; } protected override String GetDesignTimeNormalHtml() { String curStyle, message; ArrayList lstStylesInCycle = null; if (null == CurrentStyle) { curStyle = SR.GetString(SR.StyleSheet_PropNotSet); } else { curStyle = HttpUtility.HtmlEncode(CurrentStyle.Name); } String curChoice; if (null == CurrentChoice) { curChoice = SR.GetString(SR.StyleSheet_PropNotSet); } else { if (CurrentChoice.Filter.Length == 0) { curChoice = SR.GetString(SR.DeviceFilter_DefaultChoice); } else { curChoice = HttpUtility.HtmlEncode(DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice)); } } message = SR.GetString(SR.StyleSheet_DefaultMessage); bool renderErrorMsg = false; String errorMsg = null; String errorIconUrl = null; if(_isDuplicate) { renderErrorMsg = true; errorMsg = SR.GetString(SR.StyleSheet_DuplicateWarningMessage); errorIconUrl = MobileControlDesigner.errorIcon; } else if(_styleSheet.DuplicateStyles.Count > 0) { renderErrorMsg = true; errorMsg = SR.GetString( SR.StyleSheet_DuplicateStyleNamesMessage, GenericUI.BuildCommaDelimitedList( GetDuplicateStyleNames() ) ); errorIconUrl = MobileControlDesigner.errorIcon; } else if (null != CurrentStyle && null != CurrentChoice) { if (IsHTMLSchema(CurrentChoice)) { message = SR.GetString(SR.StyleSheet_TemplateEditingMessage); } else { // User has selected non-html schema renderErrorMsg = true; errorMsg = SR.GetString(SR.MobileControl_NonHtmlSchemaErrorMessage); errorIconUrl = MobileControlDesigner.infoIcon; } } if (renderErrorMsg) { Debug.Assert(errorMsg != null && errorIconUrl != null); return String.Format(CultureInfo.CurrentCulture, _specialCaseDesignTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message, errorIconUrl, errorMsg }); } else { lstStylesInCycle = DetectCycles(); // if (lstStylesInCycle != null && lstStylesInCycle.Count > 0) { String cycledStyles = String.Empty; // foreach (Object obj in lstStylesInCycle) { Style cycledStyle = (Style) obj; if (cycledStyles.Length > 0) { cycledStyles += ", "; } cycledStyles += cycledStyle.Name; } return String.Format(CultureInfo.CurrentCulture, _specialCaseDesignTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message, MobileControlDesigner.errorIcon, SR.GetString(SR.StyleSheet_RefCycleErrorMessage, cycledStyles) }); } else { return String.Format(CultureInfo.CurrentCulture, _designTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message }); } } } private void ClearCycledStyles() { _cycledStyles = null; } /* O(n) algorithm for loop detection private HybridDictionary DetectCycles() { if (_cycledStyles == null) { _cycledStyles = new HybridDictionary(); ICollection styles = _styleSheet.Styles; // Initialize the set Hashtable styleSet = new Hashtable(styles.Count); foreach (String key in styles) { styleSet.Add(key, true); } while (styleSet.Count > 0) { Style style = null; foreach (String key in styleSet.Keys) { style = (Style)_styleSheet[key]; Debug.Assert(style != null); break; } int count = 0; Traverse(styleSet, style, count); } } return _cycledStyles; } private bool Traverse(Hashtable styleSet, Style style) { String reference = style.StyleReference; Style nextStyle = null; bool result = false; styleSet.Remove(style.Name.ToLower(CultureInfo.InvariantCulture)); if (reference == null || reference.Length == 0 || ((nextStyle = (Style)_styleSheet[reference]) == null) || (!styleSet.Contains(nextStyle))) { result = false; } else if (_cycledStyles.Contains(nextStyle) || Traverse(styleSet, nextStyle, ++count)) { Debug.Assert(_cycledStyles != null); if (!_cycledStyles.Contains(style)) { _cycledStyles.Add(style, ""); } result = true; } return result; } */ private ArrayList DetectCycles() { if (_cycledStyles == null) { _cycledStyles = new ArrayList(); ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; Style styleTmp; Debug.Assert(style != null); bool cycle = false; String reference = style.StyleReference; String name = style.Name; int count = styles.Count + 1; while ((reference != null && reference.Length > 0) && count > 0) { if (0 == String.Compare(name, reference, StringComparison.OrdinalIgnoreCase)) { cycle = true; break; } else { styleTmp = _styleSheet[reference]; if (null != styleTmp) { reference = styleTmp.StyleReference; count --; } else { reference = null; } } } if (cycle) { _cycledStyles.Add(style); } } } return _cycledStyles; } //////////////////////////////////////////////////////////////////////// // Begin IDeviceSpecificDesigner Implementation //////////////////////////////////////////////////////////////////////// void IDeviceSpecificDesigner.SetDeviceSpecificEditor (IRefreshableDeviceSpecificEditor editor) { _deviceSpecificEditor = editor; } String IDeviceSpecificDesigner.CurrentDeviceSpecificID { get { if (_tmpCurrentStyle == null) { return null; } if (_styleSheet[_tmpCurrentStyle.Name] == null) { _tmpCurrentStyle = null; } return (_tmpCurrentStyle != null) ? _tmpCurrentStyle.Name.ToLower(CultureInfo.InvariantCulture) : null; } } System.Windows.Forms.Control IDeviceSpecificDesigner.Header { get { return _mergedUI; } } System.Web.UI.Control IDeviceSpecificDesigner.UnderlyingControl { get { return _styleSheet; } } Object IDeviceSpecificDesigner.UnderlyingObject { get { if (null != _mergedUI.CbStyles.SelectedItem) { String styleName = (String) _mergedUI.CbStyles.SelectedItem; return _styleSheet[styleName]; } else { return null; } } } bool IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds) { Style style = (Style) _styleSheet[deviceSpecificParentID]; if (null == style) { ds = null; return false; } else { ds = style.DeviceSpecific; return true; } } void IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds) { Style style = (Style) _styleSheet[deviceSpecificParentID]; Debug.Assert(null != style, "style is null in IDeviceSpecificDesigner.SetDeviceSpecific"); if (null != ds) { ds.SetOwner((MobileControl) _styleSheet); } style.DeviceSpecific = ds; if (CurrentChoice != null && 0 == String.Compare(CurrentStyle.Name, deviceSpecificParentID, StringComparison.OrdinalIgnoreCase)) { if (ds == null) { CurrentChoice = null; } else { // This makes sure that the CurrentChoice value is set to null is // it was deleted during the deviceSpecific object editing if (CurrentChoice.Filter.Length == 0) { TemplateDeviceFilter = SR.GetString(SR.DeviceFilter_DefaultChoice); } else { TemplateDeviceFilter = DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice); } } } } void IDeviceSpecificDesigner.InitHeader(int mergingContext) { _mergedUI = new MergedUI(); _mergedUI.LblStyles.Text = SR.GetString(SR.StyleSheet_StylesCaption); _mergedUI.LblStyles.TabIndex = 1; _mergedUI.CbStyles.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; _mergedUI.CbStyles.SelectedIndexChanged += new EventHandler(this.OnSelectedIndexChangedStylesComboBox); _mergedUI.CbStyles.TabIndex = 2; _mergedUI.CbStyles.Sorted = true; _mergedUI.BtnEdit.Text = SR.GetString(SR.Stylesheet_EditBtnCaption); _mergedUI.BtnEdit.Click += new EventHandler(this.OnClickEditStylesButton); _mergedUI.BtnEdit.TabIndex = 3; switch (mergingContext) { case MobileControlDesigner.MergingContextTemplates: { _mergedUI.LblHeader.Text = SR.GetString(SR.StyleSheet_SettingTemplatingStyleChoiceDescription); // AUI 2730 _mergedUI.CbStyles.Width = 195; _mergedUI.BtnEdit.Location = new System.Drawing.Point(201, 39); break; } default: { _mergedUI.LblHeader.Text = SR.GetString(SR.StyleSheet_SettingGenericStyleChoiceDescription); // AUI 2730 _mergedUI.CbStyles.Width = 195; _mergedUI.BtnEdit.Location = new System.Drawing.Point(201, 39); break; } } } void IDeviceSpecificDesigner.RefreshHeader(int mergingContext) { _mergedUI.CbStyles.Items.Clear(); ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; Debug.Assert(style != null); _mergedUI.CbStyles.Items.Add(style.Name); } if (_mergedUI.CbStyles.Items.Count > 0) { Debug.Assert(null != CurrentStyle); _mergedUI.CbStyles.SelectedItem = CurrentStyle.Name; _oldSelectedIndex = _mergedUI.CbStyles.SelectedIndex; } _mergedUI.CbStyles.Enabled = (_mergedUI.CbStyles.Items.Count > 0); } void IDeviceSpecificDesigner.UseCurrentDeviceSpecificID() { if (CurrentStyle != _tmpCurrentStyle) { CurrentChoice = null; CurrentStyle = _tmpCurrentStyle; } } ///////////////////////////////////////////////////////////////////////// // End IDeviceSpecificDesigner Implementation ///////////////////////////////////////////////////////////////////////// private int _oldSelectedIndex; private void OnSelectedIndexChangedStylesComboBox(Object source, EventArgs e) { if (_mergedUI.CbStyles.SelectedIndex != _oldSelectedIndex && !_deviceSpecificEditor.RequestRefresh()) { // User needs to correct error before editing a new style. _mergedUI.CbStyles.SelectedIndex = _oldSelectedIndex; return; } if (_mergedUI.CbStyles.SelectedIndex >= 0) { _tmpCurrentStyle = (Style) _styleSheet[((String) _mergedUI.CbStyles.SelectedItem).ToLower(CultureInfo.InvariantCulture)]; _deviceSpecificEditor.Refresh((String) _mergedUI.CbStyles.SelectedItem, _tmpCurrentStyle.DeviceSpecific); } _oldSelectedIndex = _mergedUI.CbStyles.SelectedIndex; } private void OnStyleRenamedInEditor(Object source, StyleRenamedEventArgs e) { _deviceSpecificEditor.DeviceSpecificRenamed(e.OldName, e.NewName); } private void OnStyleDeletedInEditor(Object source, StyleDeletedEventArgs e) { _deviceSpecificEditor.DeviceSpecificDeleted(e.Name); } private void OnClickEditStylesButton(Object source, EventArgs e) { StylesEditorDialog dialog; try { dialog = new StylesEditorDialog( _styleSheet, this, (null != _tmpCurrentStyle) ? _tmpCurrentStyle.Name : null ); } catch(ArgumentException ex) { Debug.Fail(ex.ToString()); // Block user from entering StylesEditorDialog until they fix // duplicate style declarations. return; } StylesEditorDialog.StyleRenamedEventHandler renameHandler = new StylesEditorDialog.StyleRenamedEventHandler(OnStyleRenamedInEditor); StylesEditorDialog.StyleDeletedEventHandler deleteHandler = new StylesEditorDialog.StyleDeletedEventHandler(OnStyleDeletedInEditor); dialog.StyleRenamed += renameHandler; dialog.StyleDeleted += deleteHandler; try { _deviceSpecificEditor.BeginExternalDeviceSpecificEdit(); if (dialog.ShowDialog() == DialogResult.OK) { _deviceSpecificEditor.EndExternalDeviceSpecificEdit( true /* commit changes */ ); OnInternalChange(); ((IDeviceSpecificDesigner) this).RefreshHeader(0); // using mergingContext 0 because this implementation does not use the param. if (_mergedUI.CbStyles.Items.Count == 0) { _deviceSpecificEditor.Refresh(null, null); // force the clean up and // disabling of the filter controls. _tmpCurrentStyle = null; } _deviceSpecificEditor.UnderlyingObjectsChanged(); } else { _deviceSpecificEditor.EndExternalDeviceSpecificEdit( false /* do not commit changes */ ); } } finally { dialog.StyleRenamed -= renameHandler; dialog.StyleDeleted -= deleteHandler; } } public Style CurrentStyle { get { if (null == _currentStyle) { // Since this property is registered to property window (from TemplateStyle), // it will be accessed even before Initialize is called. In that case, // _styleSheet will be null; if (_styleSheet != null && _styleSheet.Styles.Count > 0) { // how else can you get an entry in the Styles hashtable? // this needs to be fixed once we use an ordered list of styles. ICollection styles = _styleSheet.Styles; foreach (String key in styles) { _currentStyle = (Style) _styleSheet[key]; Debug.Assert (_currentStyle != null); break; } } } return _currentStyle; } set { _currentStyle = value; } } public override DeviceSpecific CurrentDeviceSpecific { get { if (null == CurrentStyle) { return null; } return CurrentStyle.DeviceSpecific; } } public String TemplateStyle { get { if (null == CurrentStyle) { return SR.GetString(SR.StyleSheet_PropNotSet); } return CurrentStyle.Name; } set { // Clear DeviceSpecificChoice of previously selected Style CurrentChoice = null; CurrentStyle = null; if (!String.IsNullOrEmpty(value) && !value.Equals(SR.GetString(SR.StyleSheet_PropNotSet))) { ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; if (style.Name.Equals(value)) { CurrentStyle = style; break; } } } // Clear DeviceSpecificChoice of currently selected Style CurrentChoice = null; // Invalidate the type descriptor so that the TemplateDeviceFilter gets updated TypeDescriptor.Refresh(Component); } } protected override void SetStyleAttributes() { Debug.Assert(Behavior != null, "Behavior is null"); String marginTop = null, marginBottom = null, marginRight = null; if (ContainmentStatus == ContainmentStatus.AtTopLevel) { marginTop = "5px"; marginBottom = "5px"; marginRight = "30%"; } else { marginTop = "3px"; marginBottom = "3px"; marginRight = "5px"; } Behavior.SetStyleAttribute("marginTop", true, marginTop, true); Behavior.SetStyleAttribute("marginBottom", true, marginBottom, true); Behavior.SetStyleAttribute("marginRight", true, marginRight, true); Behavior.SetStyleAttribute("marginLeft", true, "5px", true); } protected override void PreFilterProperties(IDictionary properties) { base.PreFilterProperties(properties); // DesignTime Property only, we will use this to select the current style. PropertyDescriptor designerTemplateStyleProp; designerTemplateStyleProp = TypeDescriptor.CreateProperty(this.GetType(), _templatesStylePropName, typeof(String), DesignerSerializationVisibilityAttribute.Hidden, MobileCategoryAttribute.Design, InTemplateMode ? ReadOnlyAttribute.Yes : ReadOnlyAttribute.No, InTemplateMode ? BrowsableAttribute.No : BrowsableAttribute.Yes, new DefaultValueAttribute(SR.GetString(SR.StyleSheet_PropNotSet)), new TypeConverterAttribute(typeof(StyleConverter)), new DescriptionAttribute(SR.GetString(SR.StyleSheet_TemplateStyleDescription))); properties[_templatesStylePropName] = designerTemplateStyleProp; PropertyDescriptor designerPersistedStyles; designerPersistedStyles = TypeDescriptor.CreateProperty(this.GetType(), _persistedStylesPropName, typeof(ICollection), //PersistenceTypeAttribute.InnerChild, PersistenceModeAttribute.InnerDefaultProperty, BrowsableAttribute.No); properties[_persistedStylesPropName] = designerPersistedStyles; } public ICollection PersistedStyles { get { Debug.Assert(null != _styleSheet, "_styleSheet is null"); ICollection styleKeys = _styleSheet.Styles; ArrayList persistedStyles = new ArrayList(); foreach (String key in styleKeys) { Style style = _styleSheet[key]; persistedStyles.Add(style); } foreach (Style style in _styleSheet.DuplicateStyles) { persistedStyles.Add(style); } return persistedStyles; } } /// /// /// The designer's collection of verbs. /// /// /// /// /// An array of type containing the verbs available to the /// designer. /// /// public override DesignerVerbCollection Verbs { get { if (_designerVerbs == null) { _designerVerbs = base.Verbs; _designerVerbs.Add(new DesignerVerb(SR.GetString(SR.StyleSheet_StylesEditorVerb), new EventHandler(this.OnShowStylesEditor))); } Debug.Assert(_designerVerbs.Count == 2); _designerVerbs[0].Enabled = !this.InTemplateMode; _designerVerbs[1].Enabled = !this.InTemplateMode; return _designerVerbs; } } ///////////////////////////////////////////////////////////////////////// // BEGIN STYLE DESIGNER EVENTHANDLERS ///////////////////////////////////////////////////////////////////////// protected void OnShowStylesEditor(Object sender, EventArgs e) { IComponentChangeService changeService = null; changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); if (changeService != null) { try { changeService.OnComponentChanging(_styleSheet, null); } catch (CheckoutException ex) { if (ex == CheckoutException.Canceled) { return; } throw; } } DialogResult result = DialogResult.Cancel; try { StylesEditorDialog dialog = new StylesEditorDialog(_styleSheet, this, null); result = dialog.ShowDialog(); } catch(ArgumentException ex) { Debug.Fail(ex.ToString()); // Block user from entering StylesEditorDialog until they fix // duplicate style declarations. } finally { if (changeService != null) { changeService.OnComponentChanged(_styleSheet, null, null, null); if (IMobileWebFormServices != null) { IMobileWebFormServices.ClearUndoStack(); } } } } protected override void OnCurrentChoiceChange() { SetCurrentChoice(); RefreshPageView(); } private void SetCurrentChoice() { if (CurrentStyle != null && CurrentStyle.DeviceSpecific != null) { this.CurrentStyle.DeviceSpecific.SetDesignerChoice(CurrentChoice); } } private bool ValidContainment { get { return (ContainmentStatus == ContainmentStatus.AtTopLevel); } } protected override String GetErrorMessage(out bool infoMode) { infoMode = false; if (!DesignerAdapterUtil.InMobileUserControl(_styleSheet)) { if (DesignerAdapterUtil.InUserControl(_styleSheet)) { infoMode = true; return MobileControlDesigner._userControlWarningMessage; } if (!DesignerAdapterUtil.InMobilePage(_styleSheet)) { return MobileControlDesigner._mobilePageErrorMessage; } } if (!ValidContainment) { return MobileControlDesigner._topPageContainmentErrorMessage; } // No error condition, return null; return null; } ///////////////////////////////////////////////////////////////////////// // END STYLE DESIGNER EVENTHANDLERS ///////////////////////////////////////////////////////////////////////// [ System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) ] private class MergedUI : HeaderPanel { internal System.Windows.Forms.Label LblStyles; internal System.Windows.Forms.ComboBox CbStyles; internal System.Windows.Forms.Button BtnEdit; internal HeaderLabel LblHeader; internal MergedUI() { this.LblStyles = new System.Windows.Forms.Label(); this.CbStyles = new System.Windows.Forms.ComboBox(); this.BtnEdit = new System.Windows.Forms.Button(); this.LblHeader = new HeaderLabel(); // this.LblStyles.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) // | System.Windows.Forms.AnchorStyles.Right); this.LblStyles.Location = new System.Drawing.Point(0, 24); this.LblStyles.Size = new System.Drawing.Size(160, 16); // this.CbStyles.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) // | System.Windows.Forms.AnchorStyles.Right); this.CbStyles.DropDownWidth = 124; this.CbStyles.Location = new System.Drawing.Point(0, 40); this.CbStyles.Size = new System.Drawing.Size(160, 21); // this.BtnEdit.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); this.BtnEdit.Location = new System.Drawing.Point(164, 39); this.BtnEdit.Size = new System.Drawing.Size(75, 23); this.LblHeader.Location = new System.Drawing.Point(0, 0); this.LblHeader.Size = new System.Drawing.Size(240, 16); this.Controls.AddRange(new System.Windows.Forms.Control[] {this.CbStyles, this.LblStyles, this.BtnEdit, this.LblHeader}); this.Size = new System.Drawing.Size(240, 70); this.Location = new System.Drawing.Point(5,6); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // 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.Diagnostics; using System.Drawing.Design; using System.Globalization; using System.Text; using System.Web.UI; using System.Web.UI.Design; using System.Web.UI.Design.MobileControls.Adapters; using System.Web.UI.Design.MobileControls.Converters; using System.Web.UI.Design.MobileControls.Util; using System.Web.UI.MobileControls; using System.Windows.Forms; using Control = System.Web.UI.Control; using DataBindingCollectionEditor = System.Web.UI.Design.DataBindingCollectionEditor; [ 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 StyleSheetDesigner : MobileTemplatedControlDesigner, IDeviceSpecificDesigner { internal static BooleanSwitch StyleSheetDesignerSwitch = new BooleanSwitch("StyleSheetDesigner", "Enable StyleSheet designer general purpose traces."); private IWebFormsDocumentService _iWebFormsDocumentService; private IRefreshableDeviceSpecificEditor _deviceSpecificEditor; private DesignerVerbCollection _designerVerbs; private System.Web.UI.MobileControls.StyleSheet _styleSheet; private Style _currentStyle, _tmpCurrentStyle; private bool _isDuplicate; private MergedUI _mergedUI = null; private ArrayList _cycledStyles = null; private const int _templateWidth = 300; private static bool _requiresDesignTimeChanges = false; private bool _shouldRepersistStyles = false; private EventHandler _loadComplete = null; private const String _templatesStylePropName = "TemplateStyle"; private const String _persistedStylesPropName = "PersistedStyles"; private const String _designTimeHTML = @"
StyleSheet - {0}
Template Style:{1}
Template Device Filter:{2}
{3}
"; private const String _specialCaseDesignTimeHTML = @"
StyleSheet - {0}
Template Style:{1}
Template Device Filter:{2}
{3}
{5}
"; private const int _headerFooterTemplates = 0; private const int _itemTemplates = 1; private const int _separatorTemplate = 2; private const int _contentTemplate = 3; private const int _numberOfTemplateFrames = 4; private static readonly String[][] _templateFrameNames = new String[][] { new String [] { Constants.HeaderTemplateTag, Constants.FooterTemplateTag }, new String [] { Constants.ItemTemplateTag, Constants.AlternatingItemTemplateTag, Constants.ItemDetailsTemplateTag }, new String [] { Constants.SeparatorTemplateTag }, new String [] { Constants.ContentTemplateTag } }; private const String _templateStyle = "__TemplateStyle__"; // used by DesignerAdapterUtil.GetMaxWidthToFit // and needs to be exposed in object model because // custom controls may need to access the value just like // DesignerAdapterUtil.GetMaxWidthToFit does. public override int TemplateWidth { get { return _templateWidth; } } private MobilePage MobilePage { get { IComponent component = DesignerAdapterUtil.GetRootComponent(Component); if (component is MobileUserControl) { return ((Control)component).Page as MobilePage; } return component as MobilePage; } } private Control RootControl { get { IComponent component = DesignerAdapterUtil.GetRootComponent(Component); return component as Control; } } /// /// /// Initializes the designer. /// /// /// /// The control element being designed. /// /// /// /// This is called by the designer host to establish the component being /// designed. /// /// /// public override void Initialize(IComponent component) { Debug.Assert(component is System.Web.UI.MobileControls.StyleSheet, "StyleSheetDesigner.Initialize - Invalid StyleSheet Control"); base.Initialize(component); _isDuplicate = false; _styleSheet = (System.Web.UI.MobileControls.StyleSheet) component; if(_requiresDesignTimeChanges) { _shouldRepersistStyles = true; } _loadComplete = new EventHandler(this.OnLoadComplete); IWebFormsDocumentService.LoadComplete += _loadComplete; if (IMobileWebFormServices != null) { TemplateStyle = (String) IMobileWebFormServices.GetCache(_styleSheet.ID, _templateStyle); TemplateDeviceFilter = (String) IMobileWebFormServices.GetCache( _styleSheet.ID, MobileTemplatedControlDesigner.DefaultTemplateDeviceFilter); } } private void OnLoadComplete(Object source, EventArgs e) { if(_shouldRepersistStyles) { IsDirty = true; OnInternalChange(); } _requiresDesignTimeChanges = false; _shouldRepersistStyles = false; UpdateDesignTimeHtml(); } internal static void SetRequiresDesignTimeChanges() { _requiresDesignTimeChanges = true; } private IWebFormsDocumentService IWebFormsDocumentService { get { if (_iWebFormsDocumentService == null) { _iWebFormsDocumentService = (IWebFormsDocumentService)GetService(typeof(IWebFormsDocumentService)); Debug.Assert(_iWebFormsDocumentService != null); } return _iWebFormsDocumentService; } } protected override ITemplateEditingFrame CreateTemplateEditingFrame(TemplateEditingVerb verb) { ITemplateEditingService teService = (ITemplateEditingService)GetService(typeof(ITemplateEditingService)); Debug.Assert(teService != null, "How did we get this far without an ITemplateEditingService"); String[] templateNames = GetTemplateFrameNames(verb.Index); ITemplateEditingFrame editingFrame = teService.CreateFrame( this, TemplateDeviceFilter + " (" + TemplateStyle + ")", templateNames, WebCtrlStyle, null /* we don't have template styles */); editingFrame.InitialWidth = _templateWidth; return editingFrame; } protected override void Dispose(bool disposing) { if (disposing) { UpdateActiveStyleSheet(); if (_loadComplete != null) { IWebFormsDocumentService.LoadComplete -= _loadComplete; _loadComplete = null; } if (IMobileWebFormServices != null) { // If the page is in loading mode, it means the remove is trigged by webformdesigner. if (!LoadComplete) { IMobileWebFormServices.SetCache(_styleSheet.ID, (Object) _templateStyle, (Object) this.TemplateStyle); } else { // setting to null will remove the entry. IMobileWebFormServices.SetCache(_styleSheet.ID, (Object) _templateStyle, null); } } } base.Dispose(disposing); } private void UpdateActiveStyleSheet() { if (MobilePage != null && MobilePage.StyleSheet == _styleSheet) { IDesigner designer = null; // currently active stylesheet is deleted MobilePage.StyleSheet = StyleSheet.Default; StyleSheet _newStyleSheet = null; Debug.Assert(RootControl != null); foreach (Control control in RootControl.Controls) { // Find new stylesheet if (control is StyleSheet && _newStyleSheet == null && control != _styleSheet) { designer = Host.GetDesigner((IComponent) control); // AUI 7285 if (designer != null) { _newStyleSheet = (StyleSheet) control; } } } MobilePage.StyleSheet = _newStyleSheet; if (null != _newStyleSheet) { Debug.Assert(designer != null); StyleSheetDesigner ssd = designer as StyleSheetDesigner; Debug.Assert(ssd != null, "ssd is null in StyleSheetDesigner"); ssd.TreatAsDuplicate(false); } RefreshPageView(); } } protected override String[] GetTemplateFrameNames(int index) { Debug.Assert(index >= 0 & index <= _templateFrameNames.Length); return _templateFrameNames[index]; } protected override TemplateEditingVerb[] GetTemplateVerbs() { TemplateEditingVerb[] templateVerbs = new TemplateEditingVerb[_numberOfTemplateFrames]; templateVerbs[_headerFooterTemplates] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_HeaderFooterTemplates), _headerFooterTemplates, this); templateVerbs[_itemTemplates] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_ItemTemplates), _itemTemplates, this); templateVerbs[_separatorTemplate] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_SeparatorTemplate), _separatorTemplate, this); templateVerbs[_contentTemplate] = new TemplateEditingVerb( SR.GetString(SR.TemplateFrame_ContentTemplate), _contentTemplate, this); return templateVerbs; } /// /// /// Delegate to handle component changed event. /// /// /// /// The object sending the event. /// /// /// The event object used when firing a component changed notification. /// /// /// /// This is called after a property has been changed. It allows the implementor /// to do any post-processing that may be needed after a property change. /// /// public override void OnComponentChanged(Object sender, ComponentChangedEventArgs ce) { // Delegate to the base class implementation first! base.OnComponentChanged(sender, ce); MemberDescriptor member = ce.Member; if (member != null && member.GetType().FullName.Equals(Constants.ReflectPropertyDescriptorTypeFullName)) { PropertyDescriptor propDesc = (PropertyDescriptor)member; if (propDesc.Name.Equals("ID")) { // Update the dictionary of device filters stored in the page designer // setting to null will remove the entry. IMobileWebFormServices.SetCache(ce.OldValue.ToString(), (Object) _templateStyle, null); } } } internal void OnStylesChanged() { // If this is not a new stylesheet and it is the current stylesheet if (MobilePage != null && MobilePage.StyleSheet == _styleSheet) { // Refresh the whole page assuming styles have been changed. RefreshPageView(); ClearCycledStyles(); } } private void RefreshPageView() { if (IMobileWebFormServices != null) { IMobileWebFormServices.RefreshPageView(); } } public override void OnSetParent() { base.OnSetParent(); // This is not a MobilePage or the styleSheet is already the active styleSheet. // The latter happens when the active StyleSheet is drag/drop to another location // which forces its parent to be changed. if (MobilePage == null) { return; } if (MobilePage.StyleSheet == _styleSheet) { if (!(_styleSheet.Parent is MobilePage || _styleSheet.Parent is MobileUserControl)) { UpdateActiveStyleSheet(); } return; } if (MobilePage.StyleSheet != StyleSheet.Default) { // can't accept more than 1 stylesheet TreatAsDuplicate(true); // the current valid StyleSheet is intentionaly refreshed because // if this stylesheet instance is recreated via a Undo operation // the current valid StyleSheet appears as a duplicate if not refreshed. IDesigner designer = Host.GetDesigner((IComponent) MobilePage.StyleSheet); Debug.Assert(designer != null, "designer is null in StyleSheetDesigner"); StyleSheetDesigner ssd = (StyleSheetDesigner) designer; ssd.UpdateRendering(); } else if (_styleSheet.Parent is MobilePage || _styleSheet.Parent is MobileUserControl) { // the active stylesheet is changed MobilePage.StyleSheet = _styleSheet; _isDuplicate = false; } RefreshPageView(); } protected override void OnTemplateModeChanged() { base.OnTemplateModeChanged(); // Refresh all mobilecontrols after exit template editing mode. if (!InTemplateMode) { RefreshPageView(); } } public void TreatAsDuplicate(bool isDuplicate) { if (isDuplicate != _isDuplicate) { _isDuplicate = isDuplicate; SetTemplateVerbsDirty(); UpdateDesignTimeHtml(); } } protected override bool ErrorMode { get { return base.ErrorMode || _isDuplicate || _styleSheet.DuplicateStyles.Count > 0; } } private StringCollection GetDuplicateStyleNames() { StringCollection duplicateNamesList = new StringCollection(); // Filter out repeated duplicate names using case insensitive // hash table HybridDictionary duplicateNamesHash = new HybridDictionary( true /* Names not case sensitive */ ); foreach(Style style in _styleSheet.DuplicateStyles) { duplicateNamesHash[style.Name] = true; } // Copy remaining names into a string list foreach(DictionaryEntry entry in duplicateNamesHash) { duplicateNamesList.Add((String)entry.Key); } return duplicateNamesList; } protected override String GetDesignTimeNormalHtml() { String curStyle, message; ArrayList lstStylesInCycle = null; if (null == CurrentStyle) { curStyle = SR.GetString(SR.StyleSheet_PropNotSet); } else { curStyle = HttpUtility.HtmlEncode(CurrentStyle.Name); } String curChoice; if (null == CurrentChoice) { curChoice = SR.GetString(SR.StyleSheet_PropNotSet); } else { if (CurrentChoice.Filter.Length == 0) { curChoice = SR.GetString(SR.DeviceFilter_DefaultChoice); } else { curChoice = HttpUtility.HtmlEncode(DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice)); } } message = SR.GetString(SR.StyleSheet_DefaultMessage); bool renderErrorMsg = false; String errorMsg = null; String errorIconUrl = null; if(_isDuplicate) { renderErrorMsg = true; errorMsg = SR.GetString(SR.StyleSheet_DuplicateWarningMessage); errorIconUrl = MobileControlDesigner.errorIcon; } else if(_styleSheet.DuplicateStyles.Count > 0) { renderErrorMsg = true; errorMsg = SR.GetString( SR.StyleSheet_DuplicateStyleNamesMessage, GenericUI.BuildCommaDelimitedList( GetDuplicateStyleNames() ) ); errorIconUrl = MobileControlDesigner.errorIcon; } else if (null != CurrentStyle && null != CurrentChoice) { if (IsHTMLSchema(CurrentChoice)) { message = SR.GetString(SR.StyleSheet_TemplateEditingMessage); } else { // User has selected non-html schema renderErrorMsg = true; errorMsg = SR.GetString(SR.MobileControl_NonHtmlSchemaErrorMessage); errorIconUrl = MobileControlDesigner.infoIcon; } } if (renderErrorMsg) { Debug.Assert(errorMsg != null && errorIconUrl != null); return String.Format(CultureInfo.CurrentCulture, _specialCaseDesignTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message, errorIconUrl, errorMsg }); } else { lstStylesInCycle = DetectCycles(); // if (lstStylesInCycle != null && lstStylesInCycle.Count > 0) { String cycledStyles = String.Empty; // foreach (Object obj in lstStylesInCycle) { Style cycledStyle = (Style) obj; if (cycledStyles.Length > 0) { cycledStyles += ", "; } cycledStyles += cycledStyle.Name; } return String.Format(CultureInfo.CurrentCulture, _specialCaseDesignTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message, MobileControlDesigner.errorIcon, SR.GetString(SR.StyleSheet_RefCycleErrorMessage, cycledStyles) }); } else { return String.Format(CultureInfo.CurrentCulture, _designTimeHTML, new Object[] { _styleSheet.Site.Name, curStyle, curChoice, message }); } } } private void ClearCycledStyles() { _cycledStyles = null; } /* O(n) algorithm for loop detection private HybridDictionary DetectCycles() { if (_cycledStyles == null) { _cycledStyles = new HybridDictionary(); ICollection styles = _styleSheet.Styles; // Initialize the set Hashtable styleSet = new Hashtable(styles.Count); foreach (String key in styles) { styleSet.Add(key, true); } while (styleSet.Count > 0) { Style style = null; foreach (String key in styleSet.Keys) { style = (Style)_styleSheet[key]; Debug.Assert(style != null); break; } int count = 0; Traverse(styleSet, style, count); } } return _cycledStyles; } private bool Traverse(Hashtable styleSet, Style style) { String reference = style.StyleReference; Style nextStyle = null; bool result = false; styleSet.Remove(style.Name.ToLower(CultureInfo.InvariantCulture)); if (reference == null || reference.Length == 0 || ((nextStyle = (Style)_styleSheet[reference]) == null) || (!styleSet.Contains(nextStyle))) { result = false; } else if (_cycledStyles.Contains(nextStyle) || Traverse(styleSet, nextStyle, ++count)) { Debug.Assert(_cycledStyles != null); if (!_cycledStyles.Contains(style)) { _cycledStyles.Add(style, ""); } result = true; } return result; } */ private ArrayList DetectCycles() { if (_cycledStyles == null) { _cycledStyles = new ArrayList(); ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; Style styleTmp; Debug.Assert(style != null); bool cycle = false; String reference = style.StyleReference; String name = style.Name; int count = styles.Count + 1; while ((reference != null && reference.Length > 0) && count > 0) { if (0 == String.Compare(name, reference, StringComparison.OrdinalIgnoreCase)) { cycle = true; break; } else { styleTmp = _styleSheet[reference]; if (null != styleTmp) { reference = styleTmp.StyleReference; count --; } else { reference = null; } } } if (cycle) { _cycledStyles.Add(style); } } } return _cycledStyles; } //////////////////////////////////////////////////////////////////////// // Begin IDeviceSpecificDesigner Implementation //////////////////////////////////////////////////////////////////////// void IDeviceSpecificDesigner.SetDeviceSpecificEditor (IRefreshableDeviceSpecificEditor editor) { _deviceSpecificEditor = editor; } String IDeviceSpecificDesigner.CurrentDeviceSpecificID { get { if (_tmpCurrentStyle == null) { return null; } if (_styleSheet[_tmpCurrentStyle.Name] == null) { _tmpCurrentStyle = null; } return (_tmpCurrentStyle != null) ? _tmpCurrentStyle.Name.ToLower(CultureInfo.InvariantCulture) : null; } } System.Windows.Forms.Control IDeviceSpecificDesigner.Header { get { return _mergedUI; } } System.Web.UI.Control IDeviceSpecificDesigner.UnderlyingControl { get { return _styleSheet; } } Object IDeviceSpecificDesigner.UnderlyingObject { get { if (null != _mergedUI.CbStyles.SelectedItem) { String styleName = (String) _mergedUI.CbStyles.SelectedItem; return _styleSheet[styleName]; } else { return null; } } } bool IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds) { Style style = (Style) _styleSheet[deviceSpecificParentID]; if (null == style) { ds = null; return false; } else { ds = style.DeviceSpecific; return true; } } void IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds) { Style style = (Style) _styleSheet[deviceSpecificParentID]; Debug.Assert(null != style, "style is null in IDeviceSpecificDesigner.SetDeviceSpecific"); if (null != ds) { ds.SetOwner((MobileControl) _styleSheet); } style.DeviceSpecific = ds; if (CurrentChoice != null && 0 == String.Compare(CurrentStyle.Name, deviceSpecificParentID, StringComparison.OrdinalIgnoreCase)) { if (ds == null) { CurrentChoice = null; } else { // This makes sure that the CurrentChoice value is set to null is // it was deleted during the deviceSpecific object editing if (CurrentChoice.Filter.Length == 0) { TemplateDeviceFilter = SR.GetString(SR.DeviceFilter_DefaultChoice); } else { TemplateDeviceFilter = DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice); } } } } void IDeviceSpecificDesigner.InitHeader(int mergingContext) { _mergedUI = new MergedUI(); _mergedUI.LblStyles.Text = SR.GetString(SR.StyleSheet_StylesCaption); _mergedUI.LblStyles.TabIndex = 1; _mergedUI.CbStyles.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; _mergedUI.CbStyles.SelectedIndexChanged += new EventHandler(this.OnSelectedIndexChangedStylesComboBox); _mergedUI.CbStyles.TabIndex = 2; _mergedUI.CbStyles.Sorted = true; _mergedUI.BtnEdit.Text = SR.GetString(SR.Stylesheet_EditBtnCaption); _mergedUI.BtnEdit.Click += new EventHandler(this.OnClickEditStylesButton); _mergedUI.BtnEdit.TabIndex = 3; switch (mergingContext) { case MobileControlDesigner.MergingContextTemplates: { _mergedUI.LblHeader.Text = SR.GetString(SR.StyleSheet_SettingTemplatingStyleChoiceDescription); // AUI 2730 _mergedUI.CbStyles.Width = 195; _mergedUI.BtnEdit.Location = new System.Drawing.Point(201, 39); break; } default: { _mergedUI.LblHeader.Text = SR.GetString(SR.StyleSheet_SettingGenericStyleChoiceDescription); // AUI 2730 _mergedUI.CbStyles.Width = 195; _mergedUI.BtnEdit.Location = new System.Drawing.Point(201, 39); break; } } } void IDeviceSpecificDesigner.RefreshHeader(int mergingContext) { _mergedUI.CbStyles.Items.Clear(); ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; Debug.Assert(style != null); _mergedUI.CbStyles.Items.Add(style.Name); } if (_mergedUI.CbStyles.Items.Count > 0) { Debug.Assert(null != CurrentStyle); _mergedUI.CbStyles.SelectedItem = CurrentStyle.Name; _oldSelectedIndex = _mergedUI.CbStyles.SelectedIndex; } _mergedUI.CbStyles.Enabled = (_mergedUI.CbStyles.Items.Count > 0); } void IDeviceSpecificDesigner.UseCurrentDeviceSpecificID() { if (CurrentStyle != _tmpCurrentStyle) { CurrentChoice = null; CurrentStyle = _tmpCurrentStyle; } } ///////////////////////////////////////////////////////////////////////// // End IDeviceSpecificDesigner Implementation ///////////////////////////////////////////////////////////////////////// private int _oldSelectedIndex; private void OnSelectedIndexChangedStylesComboBox(Object source, EventArgs e) { if (_mergedUI.CbStyles.SelectedIndex != _oldSelectedIndex && !_deviceSpecificEditor.RequestRefresh()) { // User needs to correct error before editing a new style. _mergedUI.CbStyles.SelectedIndex = _oldSelectedIndex; return; } if (_mergedUI.CbStyles.SelectedIndex >= 0) { _tmpCurrentStyle = (Style) _styleSheet[((String) _mergedUI.CbStyles.SelectedItem).ToLower(CultureInfo.InvariantCulture)]; _deviceSpecificEditor.Refresh((String) _mergedUI.CbStyles.SelectedItem, _tmpCurrentStyle.DeviceSpecific); } _oldSelectedIndex = _mergedUI.CbStyles.SelectedIndex; } private void OnStyleRenamedInEditor(Object source, StyleRenamedEventArgs e) { _deviceSpecificEditor.DeviceSpecificRenamed(e.OldName, e.NewName); } private void OnStyleDeletedInEditor(Object source, StyleDeletedEventArgs e) { _deviceSpecificEditor.DeviceSpecificDeleted(e.Name); } private void OnClickEditStylesButton(Object source, EventArgs e) { StylesEditorDialog dialog; try { dialog = new StylesEditorDialog( _styleSheet, this, (null != _tmpCurrentStyle) ? _tmpCurrentStyle.Name : null ); } catch(ArgumentException ex) { Debug.Fail(ex.ToString()); // Block user from entering StylesEditorDialog until they fix // duplicate style declarations. return; } StylesEditorDialog.StyleRenamedEventHandler renameHandler = new StylesEditorDialog.StyleRenamedEventHandler(OnStyleRenamedInEditor); StylesEditorDialog.StyleDeletedEventHandler deleteHandler = new StylesEditorDialog.StyleDeletedEventHandler(OnStyleDeletedInEditor); dialog.StyleRenamed += renameHandler; dialog.StyleDeleted += deleteHandler; try { _deviceSpecificEditor.BeginExternalDeviceSpecificEdit(); if (dialog.ShowDialog() == DialogResult.OK) { _deviceSpecificEditor.EndExternalDeviceSpecificEdit( true /* commit changes */ ); OnInternalChange(); ((IDeviceSpecificDesigner) this).RefreshHeader(0); // using mergingContext 0 because this implementation does not use the param. if (_mergedUI.CbStyles.Items.Count == 0) { _deviceSpecificEditor.Refresh(null, null); // force the clean up and // disabling of the filter controls. _tmpCurrentStyle = null; } _deviceSpecificEditor.UnderlyingObjectsChanged(); } else { _deviceSpecificEditor.EndExternalDeviceSpecificEdit( false /* do not commit changes */ ); } } finally { dialog.StyleRenamed -= renameHandler; dialog.StyleDeleted -= deleteHandler; } } public Style CurrentStyle { get { if (null == _currentStyle) { // Since this property is registered to property window (from TemplateStyle), // it will be accessed even before Initialize is called. In that case, // _styleSheet will be null; if (_styleSheet != null && _styleSheet.Styles.Count > 0) { // how else can you get an entry in the Styles hashtable? // this needs to be fixed once we use an ordered list of styles. ICollection styles = _styleSheet.Styles; foreach (String key in styles) { _currentStyle = (Style) _styleSheet[key]; Debug.Assert (_currentStyle != null); break; } } } return _currentStyle; } set { _currentStyle = value; } } public override DeviceSpecific CurrentDeviceSpecific { get { if (null == CurrentStyle) { return null; } return CurrentStyle.DeviceSpecific; } } public String TemplateStyle { get { if (null == CurrentStyle) { return SR.GetString(SR.StyleSheet_PropNotSet); } return CurrentStyle.Name; } set { // Clear DeviceSpecificChoice of previously selected Style CurrentChoice = null; CurrentStyle = null; if (!String.IsNullOrEmpty(value) && !value.Equals(SR.GetString(SR.StyleSheet_PropNotSet))) { ICollection styles = _styleSheet.Styles; foreach (String key in styles) { Style style = (Style) _styleSheet[key]; if (style.Name.Equals(value)) { CurrentStyle = style; break; } } } // Clear DeviceSpecificChoice of currently selected Style CurrentChoice = null; // Invalidate the type descriptor so that the TemplateDeviceFilter gets updated TypeDescriptor.Refresh(Component); } } protected override void SetStyleAttributes() { Debug.Assert(Behavior != null, "Behavior is null"); String marginTop = null, marginBottom = null, marginRight = null; if (ContainmentStatus == ContainmentStatus.AtTopLevel) { marginTop = "5px"; marginBottom = "5px"; marginRight = "30%"; } else { marginTop = "3px"; marginBottom = "3px"; marginRight = "5px"; } Behavior.SetStyleAttribute("marginTop", true, marginTop, true); Behavior.SetStyleAttribute("marginBottom", true, marginBottom, true); Behavior.SetStyleAttribute("marginRight", true, marginRight, true); Behavior.SetStyleAttribute("marginLeft", true, "5px", true); } protected override void PreFilterProperties(IDictionary properties) { base.PreFilterProperties(properties); // DesignTime Property only, we will use this to select the current style. PropertyDescriptor designerTemplateStyleProp; designerTemplateStyleProp = TypeDescriptor.CreateProperty(this.GetType(), _templatesStylePropName, typeof(String), DesignerSerializationVisibilityAttribute.Hidden, MobileCategoryAttribute.Design, InTemplateMode ? ReadOnlyAttribute.Yes : ReadOnlyAttribute.No, InTemplateMode ? BrowsableAttribute.No : BrowsableAttribute.Yes, new DefaultValueAttribute(SR.GetString(SR.StyleSheet_PropNotSet)), new TypeConverterAttribute(typeof(StyleConverter)), new DescriptionAttribute(SR.GetString(SR.StyleSheet_TemplateStyleDescription))); properties[_templatesStylePropName] = designerTemplateStyleProp; PropertyDescriptor designerPersistedStyles; designerPersistedStyles = TypeDescriptor.CreateProperty(this.GetType(), _persistedStylesPropName, typeof(ICollection), //PersistenceTypeAttribute.InnerChild, PersistenceModeAttribute.InnerDefaultProperty, BrowsableAttribute.No); properties[_persistedStylesPropName] = designerPersistedStyles; } public ICollection PersistedStyles { get { Debug.Assert(null != _styleSheet, "_styleSheet is null"); ICollection styleKeys = _styleSheet.Styles; ArrayList persistedStyles = new ArrayList(); foreach (String key in styleKeys) { Style style = _styleSheet[key]; persistedStyles.Add(style); } foreach (Style style in _styleSheet.DuplicateStyles) { persistedStyles.Add(style); } return persistedStyles; } } /// /// /// The designer's collection of verbs. /// /// /// /// /// An array of type containing the verbs available to the /// designer. /// /// public override DesignerVerbCollection Verbs { get { if (_designerVerbs == null) { _designerVerbs = base.Verbs; _designerVerbs.Add(new DesignerVerb(SR.GetString(SR.StyleSheet_StylesEditorVerb), new EventHandler(this.OnShowStylesEditor))); } Debug.Assert(_designerVerbs.Count == 2); _designerVerbs[0].Enabled = !this.InTemplateMode; _designerVerbs[1].Enabled = !this.InTemplateMode; return _designerVerbs; } } ///////////////////////////////////////////////////////////////////////// // BEGIN STYLE DESIGNER EVENTHANDLERS ///////////////////////////////////////////////////////////////////////// protected void OnShowStylesEditor(Object sender, EventArgs e) { IComponentChangeService changeService = null; changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService)); if (changeService != null) { try { changeService.OnComponentChanging(_styleSheet, null); } catch (CheckoutException ex) { if (ex == CheckoutException.Canceled) { return; } throw; } } DialogResult result = DialogResult.Cancel; try { StylesEditorDialog dialog = new StylesEditorDialog(_styleSheet, this, null); result = dialog.ShowDialog(); } catch(ArgumentException ex) { Debug.Fail(ex.ToString()); // Block user from entering StylesEditorDialog until they fix // duplicate style declarations. } finally { if (changeService != null) { changeService.OnComponentChanged(_styleSheet, null, null, null); if (IMobileWebFormServices != null) { IMobileWebFormServices.ClearUndoStack(); } } } } protected override void OnCurrentChoiceChange() { SetCurrentChoice(); RefreshPageView(); } private void SetCurrentChoice() { if (CurrentStyle != null && CurrentStyle.DeviceSpecific != null) { this.CurrentStyle.DeviceSpecific.SetDesignerChoice(CurrentChoice); } } private bool ValidContainment { get { return (ContainmentStatus == ContainmentStatus.AtTopLevel); } } protected override String GetErrorMessage(out bool infoMode) { infoMode = false; if (!DesignerAdapterUtil.InMobileUserControl(_styleSheet)) { if (DesignerAdapterUtil.InUserControl(_styleSheet)) { infoMode = true; return MobileControlDesigner._userControlWarningMessage; } if (!DesignerAdapterUtil.InMobilePage(_styleSheet)) { return MobileControlDesigner._mobilePageErrorMessage; } } if (!ValidContainment) { return MobileControlDesigner._topPageContainmentErrorMessage; } // No error condition, return null; return null; } ///////////////////////////////////////////////////////////////////////// // END STYLE DESIGNER EVENTHANDLERS ///////////////////////////////////////////////////////////////////////// [ System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) ] private class MergedUI : HeaderPanel { internal System.Windows.Forms.Label LblStyles; internal System.Windows.Forms.ComboBox CbStyles; internal System.Windows.Forms.Button BtnEdit; internal HeaderLabel LblHeader; internal MergedUI() { this.LblStyles = new System.Windows.Forms.Label(); this.CbStyles = new System.Windows.Forms.ComboBox(); this.BtnEdit = new System.Windows.Forms.Button(); this.LblHeader = new HeaderLabel(); // this.LblStyles.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) // | System.Windows.Forms.AnchorStyles.Right); this.LblStyles.Location = new System.Drawing.Point(0, 24); this.LblStyles.Size = new System.Drawing.Size(160, 16); // this.CbStyles.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) // | System.Windows.Forms.AnchorStyles.Right); this.CbStyles.DropDownWidth = 124; this.CbStyles.Location = new System.Drawing.Point(0, 40); this.CbStyles.Size = new System.Drawing.Size(160, 21); // this.BtnEdit.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); this.BtnEdit.Location = new System.Drawing.Point(164, 39); this.BtnEdit.Size = new System.Drawing.Size(75, 23); this.LblHeader.Location = new System.Drawing.Point(0, 0); this.LblHeader.Size = new System.Drawing.Size(240, 16); this.Controls.AddRange(new System.Windows.Forms.Control[] {this.CbStyles, this.LblStyles, this.BtnEdit, this.LblHeader}); this.Size = new System.Drawing.Size(240, 70); this.Location = new System.Drawing.Point(5,6); } } } } // 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