1 //------------------------------------------------------------------------------ 2 // <copyright file="MobileTemplatedControlDesigner.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.UI.Design.MobileControls 8 { 9 using System; 10 using System.Collections; 11 using System.ComponentModel; 12 using System.ComponentModel.Design; 13 using System.Diagnostics; 14 using System.Drawing; 15 using System.Drawing.Design; 16 using System.Globalization; 17 using System.Reflection; 18 using System.Text; 19 using System.Web.UI; 20 using System.Web.UI.Design; 21 using System.Web.UI.Design.MobileControls.Adapters; 22 using System.Web.UI.Design.MobileControls.Converters; 23 using System.Web.UI.Design.MobileControls.Util; 24 using System.Web.UI.MobileControls; 25 using System.Web.UI.MobileControls.Adapters; 26 27 using WebCtrlStyle = System.Web.UI.WebControls.Style; 28 using DialogResult = System.Windows.Forms.DialogResult; 29 30 [ 31 System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, 32 Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 33 ] 34 [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.")] 35 internal abstract class MobileTemplatedControlDesigner : TemplatedControlDesigner, IMobileDesigner, IDeviceSpecificDesigner 36 { 37 #if TRACE 38 internal static BooleanSwitch TemplateableControlDesignerSwitch = 39 new BooleanSwitch("MobileTemplatedControlDesigner", "Enable TemplateableControl designer general purpose traces."); 40 #endif 41 42 private System.Windows.Forms.Control _header; 43 private MobileControl _mobileControl; 44 private System.Web.UI.Control _control; 45 private DesignerVerbCollection _designerVerbs = null; 46 private DeviceSpecificChoice _currentChoice = null; 47 private bool _containmentStatusDirty = true; 48 private ContainmentStatus _containmentStatus; 49 private IDesignerHost _host; 50 private IWebFormsDocumentService _iWebFormsDocumentService; 51 private IMobileWebFormServices _iMobileWebFormServices; 52 private const String _htmlString = "html"; 53 private TemplateEditingVerb[] _templateVerbs; 54 private bool _templateVerbsDirty = true; 55 private const int _templateWidth = 275; 56 57 private static readonly String _noChoiceText = 58 SR.GetString(SR.DeviceFilter_NoChoice); 59 60 private static readonly String _defaultChoiceText = 61 SR.GetString(SR.DeviceFilter_DefaultChoice); 62 63 private static readonly String _nonHtmlSchemaErrorMessage = 64 SR.GetString(SR.MobileControl_NonHtmlSchemaErrorMessage); 65 66 private static readonly String _illFormedWarning = 67 SR.GetString(SR.TemplateFrame_IllFormedWarning); 68 69 private const String _illFormedHtml = 70 "<DIV style=\"font-family:tahoma;font-size:8pt; COLOR: infotext; BACKGROUND-COLOR: infobackground\">{0}</DIV>"; 71 72 internal const String DefaultTemplateDeviceFilter = "__TemplateDeviceFilter__"; 73 private const String _templateDeviceFilterPropertyName = "TemplateDeviceFilter"; 74 private const String _appliedDeviceFiltersPropertyName = "AppliedDeviceFilters"; 75 private const String _propertyOverridesPropertyName = "PropertyOverrides"; 76 private const String _expressionsPropertyName = "Expressions"; 77 private const String _defaultDeviceSpecificIdentifier = "unique"; 78 79 // used by DesignerAdapterUtil.GetMaxWidthToFit 80 // and needs to be exposed in object model because 81 // custom controls may need to access the value just like 82 // DesignerAdapterUtil.GetMaxWidthToFit does. 83 public virtual int TemplateWidth 84 { 85 get 86 { 87 return _templateWidth; 88 } 89 } 90 91 public override bool AllowResize 92 { 93 get 94 { 95 // Non mobilecontrols (ie. DeviceSpecific) does not render templates, no need to resize. 96 // When templates are not defined, we render a read-only fixed 97 // size block. Once templates are defined or are being edited 98 // the control should allow resizing. 99 return InTemplateMode || (_mobileControl != null && _mobileControl.IsTemplated); 100 } 101 } 102 103 private bool AllowTemplateEditing 104 { 105 get 106 { 107 return (CurrentChoice != null && IsHTMLSchema(CurrentChoice) && !ErrorMode); 108 } 109 } 110 111 [ 112 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 113 Editor(typeof(AppliedDeviceFiltersTypeEditor), typeof(UITypeEditor)), 114 MergableProperty(false), 115 MobileCategory("Category_DeviceSpecific"), 116 MobileSysDescription(SR.MobileControl_AppliedDeviceFiltersDescription), 117 ParenthesizePropertyName(true), 118 ] 119 protected String AppliedDeviceFilters 120 { 121 get 122 { 123 return String.Empty; 124 } 125 } 126 127 protected ContainmentStatus ContainmentStatus 128 { 129 get 130 { 131 if (!_containmentStatusDirty) 132 { 133 return _containmentStatus; 134 } 135 136 _containmentStatus = 137 DesignerAdapterUtil.GetContainmentStatus(_control); 138 139 _containmentStatusDirty = false; 140 return _containmentStatus; 141 } 142 } 143 144 public DeviceSpecificChoice CurrentChoice 145 { 146 get 147 { 148 return _currentChoice; 149 } 150 151 set 152 { 153 if (_currentChoice != value) 154 { 155 SetTemplateVerbsDirty(); 156 157 _currentChoice = value; 158 OnCurrentChoiceChange(); 159 } 160 } 161 } 162 163 public virtual DeviceSpecific CurrentDeviceSpecific 164 { 165 get 166 { 167 if (null == _mobileControl) 168 { 169 return null; 170 } 171 172 return _mobileControl.DeviceSpecific; 173 } 174 } 175 176 internal Object DesignTimeElementInternal 177 { 178 get 179 { 180 return typeof(HtmlControlDesigner).InvokeMember("DesignTimeElement", 181 BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic, 182 null, this, null, CultureInfo.InvariantCulture); 183 } 184 } 185 186 public override bool DesignTimeHtmlRequiresLoadComplete 187 { 188 get 189 { 190 return true; 191 } 192 } 193 194 // 195 196 197 // Return true only when GetErrorMessage returns non-null string and 198 // it is not info mode (warning only). 199 protected virtual bool ErrorMode 200 { 201 get 202 { 203 bool infoMode; 204 return (GetErrorMessage(out infoMode) != null && !infoMode); 205 } 206 } 207 208 protected IDesignerHost Host 209 { 210 get 211 { 212 if (_host != null) 213 { 214 return _host; 215 } 216 _host = (IDesignerHost)GetService(typeof(IDesignerHost)); 217 Debug.Assert(_host != null); 218 return _host; 219 } 220 } 221 222 protected IMobileWebFormServices IMobileWebFormServices 223 { 224 get 225 { 226 if (_iMobileWebFormServices == null) 227 { 228 _iMobileWebFormServices = 229 (IMobileWebFormServices)GetService(typeof(IMobileWebFormServices)); 230 } 231 232 return _iMobileWebFormServices; 233 } 234 } 235 236 private IWebFormsDocumentService IWebFormsDocumentService 237 { 238 get 239 { 240 if (_iWebFormsDocumentService == null) 241 { 242 _iWebFormsDocumentService = 243 (IWebFormsDocumentService)GetService(typeof(IWebFormsDocumentService)); 244 245 Debug.Assert(_iWebFormsDocumentService != null); 246 } 247 248 return _iWebFormsDocumentService; 249 } 250 } 251 252 /// <summary> 253 /// Indicates whether the initial page load is completed 254 /// </summary> 255 protected bool LoadComplete 256 { 257 get 258 { 259 return !IWebFormsDocumentService.IsLoading; 260 } 261 } 262 263 [ 264 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 265 Editor(typeof(PropertyOverridesTypeEditor), typeof(UITypeEditor)), 266 MergableProperty(false), 267 MobileCategory("Category_DeviceSpecific"), 268 MobileSysDescription(SR.MobileControl_DeviceSpecificPropsDescription), 269 ParenthesizePropertyName(true), 270 ] 271 protected String PropertyOverrides 272 { 273 get 274 { 275 return String.Empty; 276 } 277 } 278 279 [ 280 DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 281 MobileSysDescription(SR.TemplateableDesigner_TemplateChoiceDescription), 282 TypeConverter(typeof(ChoiceConverter)), 283 ] 284 public String TemplateDeviceFilter 285 { 286 get 287 { 288 if (null == CurrentChoice) 289 { 290 return _noChoiceText; 291 } 292 if (CurrentChoice.Filter.Length == 0) 293 { 294 return _defaultChoiceText; 295 } 296 else 297 { 298 return DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice); 299 } 300 } 301 set 302 { 303 if (String.IsNullOrEmpty(value) || 304 value.Equals(SR.GetString(SR.DeviceFilter_NoChoice))) 305 { 306 CurrentChoice = null; 307 return; 308 } 309 310 if (null == CurrentDeviceSpecific) 311 { 312 return; 313 } 314 315 Debug.Assert(CurrentDeviceSpecific.Choices != null); 316 317 foreach (DeviceSpecificChoice choice in CurrentDeviceSpecific.Choices) 318 { 319 if (DesignerUtility.ChoiceToUniqueIdentifier(choice).Equals(value) || 320 (choice.Filter.Length == 0 && 321 value.Equals(SR.GetString(SR.DeviceFilter_DefaultChoice)))) 322 { 323 CurrentChoice = choice; 324 return; 325 } 326 } 327 328 CurrentChoice = null; 329 } 330 } 331 332 private bool ValidContainment 333 { 334 get 335 { 336 return (ContainmentStatus == ContainmentStatus.InForm || 337 ContainmentStatus == ContainmentStatus.InPanel || 338 ContainmentStatus == ContainmentStatus.InTemplateFrame); 339 } 340 } 341 342 public override DesignerVerbCollection Verbs 343 { 344 get 345 { 346 if (_designerVerbs == null) 347 { 348 _designerVerbs = new DesignerVerbCollection(); 349 350 _designerVerbs.Add(new DesignerVerb( 351 SR.GetString(SR.TemplateableDesigner_SetTemplatesFilterVerb), 352 new EventHandler(this.OnSetTemplatesFilterVerb))); 353 } 354 355 _designerVerbs[0].Enabled = !this.InTemplateMode; 356 return _designerVerbs; 357 } 358 } 359 360 protected WebCtrlStyle WebCtrlStyle 361 { 362 get 363 { 364 WebCtrlStyle style = new WebCtrlStyle(); 365 366 if (_mobileControl != null) 367 { 368 _mobileControl.Style.ApplyTo(style); 369 } 370 else 371 { 372 Debug.Assert(_control is DeviceSpecific); 373 if (_control.Parent is Panel) 374 { 375 ((Panel)_control.Parent).Style.ApplyTo(style); 376 } 377 } 378 379 return style; 380 } 381 } 382 383 [ 384 Conditional("DEBUG") 385 ] CheckTemplateName(String templateName)386 private void CheckTemplateName(String templateName) 387 { 388 Debug.Assert ( 389 templateName == Constants.HeaderTemplateTag || 390 templateName == Constants.FooterTemplateTag || 391 templateName == Constants.ItemTemplateTag || 392 templateName == Constants.AlternatingItemTemplateTag || 393 templateName == Constants.SeparatorTemplateTag || 394 templateName == Constants.ItemDetailsTemplateTag || 395 templateName == Constants.ContentTemplateTag); 396 } 397 CreateTemplateEditingFrame(TemplateEditingVerb verb)398 protected override ITemplateEditingFrame CreateTemplateEditingFrame(TemplateEditingVerb verb) 399 { 400 ITemplateEditingService teService = 401 (ITemplateEditingService)GetService(typeof(ITemplateEditingService)); 402 Debug.Assert(teService != null, 403 "How did we get this far without an ITemplateEditingService"); 404 405 String[] templateNames = GetTemplateFrameNames(verb.Index); 406 ITemplateEditingFrame editingFrame = teService.CreateFrame( 407 this, 408 TemplateDeviceFilter, 409 templateNames, 410 WebCtrlStyle, 411 null /* we don't have template styles */); 412 413 editingFrame.InitialWidth = _templateWidth; 414 return editingFrame; 415 } 416 Dispose(bool disposing)417 protected override void Dispose(bool disposing) 418 { 419 if (disposing) 420 { 421 DisposeTemplateVerbs(); 422 423 if (IMobileWebFormServices != null) 424 { 425 // If the page is in loading mode, it means the remove is trigged by webformdesigner. 426 if (IWebFormsDocumentService.IsLoading) 427 { 428 IMobileWebFormServices.SetCache(_control.ID, (Object) DefaultTemplateDeviceFilter, (Object) this.TemplateDeviceFilter); 429 } 430 else 431 { 432 // setting to null will remove the entry. 433 IMobileWebFormServices.SetCache(_control.ID, (Object) DefaultTemplateDeviceFilter, null); 434 } 435 } 436 } 437 438 base.Dispose(disposing); 439 } 440 OnComponentChanged(Object sender, ComponentChangedEventArgs ce)441 public override void OnComponentChanged(Object sender, ComponentChangedEventArgs ce) 442 { 443 base.OnComponentChanged(sender, ce); 444 445 MemberDescriptor member = ce.Member; 446 if (member != null && 447 member.GetType().FullName.Equals(Constants.ReflectPropertyDescriptorTypeFullName)) 448 { 449 PropertyDescriptor propDesc = (PropertyDescriptor)member; 450 451 switch (propDesc.Name) 452 { 453 case "ID": 454 { 455 // Update the dictionary of device filters stored in the page designer 456 // setting to null will remove the entry. 457 IMobileWebFormServices.SetCache(ce.OldValue.ToString(), (Object) DefaultTemplateDeviceFilter, null); 458 break; 459 } 460 461 case "BackColor": 462 case "ForeColor": 463 case "Font": 464 case "StyleReference": 465 { 466 SetTemplateVerbsDirty(); 467 break; 468 } 469 } 470 } 471 } 472 DisposeTemplateVerbs()473 private void DisposeTemplateVerbs() 474 { 475 if (_templateVerbs != null) 476 { 477 for (int i = 0; i < _templateVerbs.Length; i++) 478 { 479 _templateVerbs[i].Dispose(); 480 } 481 482 _templateVerbs = null; 483 _templateVerbsDirty = true; 484 } 485 } 486 GetCachedTemplateEditingVerbs()487 protected override TemplateEditingVerb[] GetCachedTemplateEditingVerbs() 488 { 489 if (ErrorMode) 490 { 491 return null; 492 } 493 494 // dispose template verbs during template editing would cause exiting from editing mode 495 // without saving. 496 if (_templateVerbsDirty == true && !InTemplateMode) 497 { 498 DisposeTemplateVerbs(); 499 500 _templateVerbs = GetTemplateVerbs(); 501 _templateVerbsDirty = false; 502 } 503 504 foreach(TemplateEditingVerb verb in _templateVerbs) 505 { 506 verb.Enabled = AllowTemplateEditing; 507 } 508 509 return _templateVerbs; 510 } 511 512 // Gets the HTML to be used for the design time representation of the control runtime. GetDesignTimeHtml()513 public sealed override String GetDesignTimeHtml() 514 { 515 if (!LoadComplete) 516 { 517 return null; 518 } 519 520 bool infoMode; 521 String errorMessage = GetErrorMessage(out infoMode); 522 SetStyleAttributes(); 523 524 if (null != errorMessage) 525 { 526 return GetDesignTimeErrorHtml(errorMessage, infoMode); 527 } 528 529 String designTimeHTML = null; 530 531 // This is to avoiding cascading error rendering. 532 try 533 { 534 designTimeHTML = GetDesignTimeNormalHtml(); 535 } 536 catch (Exception ex) 537 { 538 Debug.Fail(ex.ToString()); 539 designTimeHTML = GetDesignTimeErrorHtml(ex.Message, false); 540 } 541 542 return designTimeHTML; 543 } 544 GetDesignTimeErrorHtml(String errorMessage, bool infoMode)545 protected virtual String GetDesignTimeErrorHtml(String errorMessage, bool infoMode) 546 { 547 return DesignerAdapterUtil.GetDesignTimeErrorHtml( 548 errorMessage, infoMode, _control, Behavior, ContainmentStatus); 549 } 550 GetDesignTimeNormalHtml()551 protected virtual String GetDesignTimeNormalHtml() 552 { 553 return GetEmptyDesignTimeHtml(); 554 } 555 556 // We sealed this method because it will never be called 557 // by our designers under current structure. GetErrorDesignTimeHtml(Exception e)558 protected override sealed String GetErrorDesignTimeHtml(Exception e) 559 { 560 return base.GetErrorDesignTimeHtml(e); 561 } 562 GetErrorMessage(out bool infoMode)563 protected virtual String GetErrorMessage(out bool infoMode) 564 { 565 infoMode = false; 566 567 if (!DesignerAdapterUtil.InMobileUserControl(_control)) 568 { 569 if (DesignerAdapterUtil.InUserControl(_control)) 570 { 571 infoMode = true; 572 return MobileControlDesigner._userControlWarningMessage; 573 } 574 575 if (!DesignerAdapterUtil.InMobilePage(_control)) 576 { 577 return MobileControlDesigner._mobilePageErrorMessage; 578 } 579 580 if (!ValidContainment) 581 { 582 return MobileControlDesigner._formPanelContainmentErrorMessage; 583 } 584 } 585 586 if (CurrentChoice != null && !IsHTMLSchema(CurrentChoice)) 587 { 588 infoMode = true; 589 return _nonHtmlSchemaErrorMessage; 590 } 591 592 // Containment is valid, return null; 593 return null; 594 } 595 596 /// <summary> 597 /// <para> 598 /// Gets the HTML to be persisted for the content present within the associated server control runtime. 599 /// </para> 600 /// </summary> 601 /// <returns> 602 /// <para> 603 /// Persistable Inner HTML. 604 /// </para> 605 /// </returns> GetPersistInnerHtml()606 public override String GetPersistInnerHtml() 607 { 608 String persist = null; 609 610 if (InTemplateMode) 611 { 612 SaveActiveTemplateEditingFrame(); 613 } 614 615 if (IsDirty) 616 { 617 persist = MobileControlPersister.PersistInnerProperties(Component, Host); 618 } 619 620 if (InTemplateMode) 621 { 622 IsDirty = true; 623 } 624 625 return persist; 626 } 627 GetTemplateContent( ITemplateEditingFrame editingFrame, String templateName, out bool allowEditing)628 public override String GetTemplateContent( 629 ITemplateEditingFrame editingFrame, 630 String templateName, 631 out bool allowEditing) 632 { 633 Debug.Assert(AllowTemplateEditing); 634 #if DEBUG 635 CheckTemplateName(templateName); 636 #endif 637 allowEditing = true; 638 639 ITemplate template = null; 640 String templateContent = String.Empty; 641 642 // Here we trust the TemplateVerbs to give valid template names 643 template = (ITemplate)CurrentChoice.Templates[templateName]; 644 645 if (template != null) 646 { 647 templateContent = GetTextFromTemplate(template); 648 if (!IsCompleteHtml(templateContent)) 649 { 650 allowEditing = false; 651 templateContent = String.Format(CultureInfo.CurrentCulture, _illFormedHtml, _illFormedWarning); 652 } 653 } 654 655 return templateContent; 656 } 657 GetTemplateFrameNames(int index)658 protected abstract String[] GetTemplateFrameNames(int index); 659 GetTemplateVerbs()660 protected abstract TemplateEditingVerb[] GetTemplateVerbs(); 661 662 /// <summary> 663 /// <para> 664 /// Initializes the designer. 665 /// </para> 666 /// </summary> 667 /// <param name='component'> 668 /// The control element being designed. 669 /// </param> 670 /// <remarks> 671 /// <para> 672 /// This is called by the designer host to establish the component being 673 /// designed. 674 /// </para> 675 /// </remarks> 676 /// <seealso cref='System.ComponentModel.Design.IDesigner'/> Initialize(IComponent component)677 public override void Initialize(IComponent component) 678 { 679 Debug.Assert(component is System.Web.UI.MobileControls.MobileControl || 680 component is System.Web.UI.MobileControls.DeviceSpecific, 681 "MobileTemplatedControlDesigner.Initialize - Invalid (Mobile) Control"); 682 683 base.Initialize(component); 684 685 if (component is System.Web.UI.MobileControls.MobileControl) 686 { 687 _mobileControl = (System.Web.UI.MobileControls.MobileControl) component; 688 } 689 // else the component is a DeviceSpecific control 690 _control = (System.Web.UI.Control) component; 691 692 if (IMobileWebFormServices != null) 693 { 694 this.TemplateDeviceFilter = (String) IMobileWebFormServices.GetCache(_control.ID, (Object)DefaultTemplateDeviceFilter); 695 } 696 } 697 IsCompleteHtml(String templateContent)698 private bool IsCompleteHtml(String templateContent) 699 { 700 if (!String.IsNullOrEmpty(templateContent)) 701 { 702 return SimpleParser.IsWellFormed(templateContent); 703 } 704 705 // if template is empty, it's always editable. 706 return true; 707 } 708 IsHTMLSchema(DeviceSpecificChoice choice)709 protected bool IsHTMLSchema(DeviceSpecificChoice choice) 710 { 711 Debug.Assert(choice != null); 712 713 return choice.Xmlns != null && 714 choice.Xmlns.ToLower(CultureInfo.InvariantCulture).IndexOf(_htmlString, StringComparison.Ordinal) != -1; 715 } 716 717 // Notification that is called when current choice is changed, it is currently 718 // used to notify StyleSheet that template device filter is changed. OnCurrentChoiceChange()719 protected virtual void OnCurrentChoiceChange() 720 { 721 } 722 723 /// <summary> 724 /// <para> 725 /// Notification that is called when internal changes have been made. 726 /// </para> 727 /// </summary> OnInternalChange()728 protected virtual void OnInternalChange() 729 { 730 ISite site = _control.Site; 731 if (site != null) 732 { 733 IComponentChangeService changeService = 734 (IComponentChangeService)site.GetService(typeof(IComponentChangeService)); 735 if (changeService != null) 736 { 737 try 738 { 739 changeService.OnComponentChanging(_control, null); 740 } 741 catch (CheckoutException ex) 742 { 743 if (ex == CheckoutException.Canceled) 744 { 745 return; 746 } 747 throw; 748 } 749 changeService.OnComponentChanged(_control, null, null, null); 750 } 751 } 752 } 753 754 /// <summary> 755 /// <para> 756 /// Notification that is called when the associated control is parented. 757 /// </para> 758 /// </summary> OnSetParent()759 public override void OnSetParent() 760 { 761 base.OnSetParent(); 762 763 // Template verbs may need to be refreshed 764 SetTemplateVerbsDirty(); 765 766 // this needs to be set before OnLoadComplete; 767 _containmentStatusDirty = true; 768 769 if (LoadComplete) 770 { 771 UpdateRendering(); 772 } 773 } 774 OnSetTemplatesFilterVerb(Object sender, EventArgs e)775 private void OnSetTemplatesFilterVerb(Object sender, EventArgs e) 776 { 777 ShowTemplatingOptionsDialog(); 778 } 779 OnTemplateModeChanged()780 protected override void OnTemplateModeChanged() 781 { 782 base.OnTemplateModeChanged(); 783 784 if (InTemplateMode) 785 { 786 // Set xmlns in view linked document to show HTML intrinsic 787 // controls in property grid with same schema used by 788 // Intellisense for current choice tag in HTML view. 789 790 // This code won't work in Venus now since there are no viewlinks and 791 // they don't support this kind of schema. 792 /* 793 NativeMethods.IHTMLElement htmlElement = (NativeMethods.IHTMLElement) ((IHtmlControlDesignerBehavior) Behavior).DesignTimeElementView; 794 Debug.Assert(htmlElement != null, 795 "Invalid HTML element in MobileTemplateControlDesigner.OnTemplateModeChanged"); 796 NativeMethods.IHTMLDocument2 htmlDocument2 = (NativeMethods.IHTMLDocument2) htmlElement.GetDocument(); 797 Debug.Assert(htmlDocument2 != null, 798 "Invalid HTML Document2 in MobileTemplateControlDesigner.OnTemplateModeChanged"); 799 NativeMethods.IHTMLElement htmlBody = (NativeMethods.IHTMLElement) htmlDocument2.GetBody(); 800 Debug.Assert(htmlBody != null, 801 "Invalid HTML Body in MobileTemplateControlDesigner.OnTemplateModeChanged"); 802 htmlBody.SetAttribute("xmlns", (Object) CurrentChoice.Xmlns, 0); 803 */ 804 } 805 } 806 PreFilterProperties(IDictionary properties)807 protected override void PreFilterProperties(IDictionary properties) 808 { 809 base.PreFilterProperties(properties); 810 811 // DesignTime Property only, we will use this to select choices. 812 properties[_templateDeviceFilterPropertyName] = 813 TypeDescriptor.CreateProperty(this.GetType(), 814 _templateDeviceFilterPropertyName, 815 typeof(String), 816 new DefaultValueAttribute(SR.GetString(SR.DeviceFilter_NoChoice)), 817 MobileCategoryAttribute.Design, 818 InTemplateMode ? BrowsableAttribute.No : BrowsableAttribute.Yes 819 ); 820 821 // design time only entry used to display dialog box used to create choices. 822 properties[_appliedDeviceFiltersPropertyName] = 823 TypeDescriptor.CreateProperty(this.GetType(), 824 _appliedDeviceFiltersPropertyName, 825 typeof(String), 826 InTemplateMode? BrowsableAttribute.No : BrowsableAttribute.Yes 827 ); 828 829 // design time only entry used to display dialog box to create choices. 830 properties[_propertyOverridesPropertyName] = 831 TypeDescriptor.CreateProperty(this.GetType(), 832 _propertyOverridesPropertyName, 833 typeof(String), 834 InTemplateMode? BrowsableAttribute.No : BrowsableAttribute.Yes 835 ); 836 837 PropertyDescriptor property = (PropertyDescriptor) properties[_expressionsPropertyName]; 838 if (property != null) { 839 properties[_expressionsPropertyName] = TypeDescriptor.CreateProperty(this.GetType(), property, BrowsableAttribute.No); 840 } 841 } 842 SetStyleAttributes()843 protected virtual void SetStyleAttributes() 844 { 845 Debug.Assert(Behavior != null); 846 DesignerAdapterUtil.SetStandardStyleAttributes(Behavior, ContainmentStatus); 847 } 848 SetTemplateContent( ITemplateEditingFrame editingFrame, String templateName, String templateContent)849 public override void SetTemplateContent( 850 ITemplateEditingFrame editingFrame, 851 String templateName, 852 String templateContent) 853 { 854 Debug.Assert(AllowTemplateEditing); 855 856 // Debug build only checking 857 CheckTemplateName(templateName); 858 859 ITemplate template = null; 860 861 if ((templateContent != null) && (templateContent.Length != 0)) 862 { 863 template = GetTemplateFromText(templateContent); 864 } 865 else 866 { 867 CurrentChoice.Templates.Remove(templateName); 868 return; 869 } 870 871 // Here we trust the TemplateVerbs to give valid template names 872 CurrentChoice.Templates[templateName] = template; 873 } 874 SetTemplateVerbsDirty()875 protected internal void SetTemplateVerbsDirty() 876 { 877 _templateVerbsDirty = true; 878 } 879 ShowTemplatingOptionsDialog()880 protected virtual void ShowTemplatingOptionsDialog() 881 { 882 IComponentChangeService changeService = 883 (IComponentChangeService)GetService(typeof(IComponentChangeService)); 884 if (changeService != null) 885 { 886 try 887 { 888 changeService.OnComponentChanging(_control, null); 889 } 890 catch (CheckoutException ex) 891 { 892 if (ex == CheckoutException.Canceled) 893 { 894 return; 895 } 896 throw; 897 } 898 } 899 900 try 901 { 902 TemplatingOptionsDialog dialog = new TemplatingOptionsDialog( 903 this, 904 _control.Site, 905 MobileControlDesigner.MergingContextTemplates); 906 dialog.ShowDialog(); 907 } 908 finally 909 { 910 if (changeService != null) 911 { 912 changeService.OnComponentChanged(_control, null, null, null); 913 914 if (IMobileWebFormServices != null) 915 { 916 IMobileWebFormServices.ClearUndoStack(); 917 } 918 } 919 } 920 } 921 UpdateRendering()922 public void UpdateRendering() 923 { 924 if (!(null == _mobileControl || _mobileControl is StyleSheet)) 925 { 926 _mobileControl.RefreshStyle(); 927 } 928 929 // template editing frame need to be recreated because the style 930 // (WebCtrlStyle) to use may have to change 931 SetTemplateVerbsDirty(); 932 933 if (!InTemplateMode) 934 { 935 UpdateDesignTimeHtml(); 936 } 937 } 938 939 //////////////////////////////////////////////////////////////////////// 940 // Begin IDeviceSpecificDesigner Implementation 941 //////////////////////////////////////////////////////////////////////// 942 IDeviceSpecificDesigner.SetDeviceSpecificEditor(IRefreshableDeviceSpecificEditor editor)943 void IDeviceSpecificDesigner.SetDeviceSpecificEditor 944 (IRefreshableDeviceSpecificEditor editor) 945 { 946 } 947 948 String IDeviceSpecificDesigner.CurrentDeviceSpecificID 949 { 950 get 951 { 952 return _defaultDeviceSpecificIdentifier; 953 } 954 } 955 956 System.Windows.Forms.Control IDeviceSpecificDesigner.Header 957 { 958 get 959 { 960 return _header; 961 } 962 } 963 964 System.Web.UI.Control IDeviceSpecificDesigner.UnderlyingControl 965 { 966 get 967 { 968 return _control; 969 } 970 } 971 972 Object IDeviceSpecificDesigner.UnderlyingObject 973 { 974 get 975 { 976 return _control; 977 } 978 } 979 IDeviceSpecificDesigner.InitHeader(int mergingContext)980 void IDeviceSpecificDesigner.InitHeader(int mergingContext) 981 { 982 HeaderPanel panel = new HeaderPanel(); 983 HeaderLabel lblDescription = new HeaderLabel(); 984 985 lblDescription.TabIndex = 0; 986 lblDescription.Height = 24; 987 lblDescription.Width = 204; 988 panel.Height = 28; 989 panel.Width = 204; 990 panel.Controls.Add(lblDescription); 991 992 switch (mergingContext) 993 { 994 case MobileControlDesigner.MergingContextTemplates: 995 { 996 lblDescription.Text = SR.GetString(SR.TemplateableDesigner_SettingTemplatingChoiceDescription); 997 break; 998 } 999 1000 default: 1001 { 1002 lblDescription.Text = SR.GetString(SR.TemplateableDesigner_SettingGenericChoiceDescription); 1003 break; 1004 } 1005 } 1006 1007 _header = panel; 1008 } 1009 IDeviceSpecificDesigner.RefreshHeader(int mergingContext)1010 void IDeviceSpecificDesigner.RefreshHeader(int mergingContext) 1011 { 1012 } 1013 IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds)1014 bool IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds) 1015 { 1016 Debug.Assert(_defaultDeviceSpecificIdentifier == deviceSpecificParentID); 1017 ds = CurrentDeviceSpecific; 1018 return true; 1019 } 1020 IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds)1021 void IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds) 1022 { 1023 Debug.Assert(_defaultDeviceSpecificIdentifier == deviceSpecificParentID); 1024 1025 if (_mobileControl != null) 1026 { 1027 if (null != ds) 1028 { 1029 ds.SetOwner(_mobileControl); 1030 } 1031 _mobileControl.DeviceSpecific = ds; 1032 } 1033 else if (_control != null && ds == null) 1034 { 1035 Debug.Assert(_control is DeviceSpecific); 1036 1037 // Clear the choices if it is a DeviceSpecific control. 1038 ((DeviceSpecific)_control).Choices.Clear(); 1039 } 1040 1041 if (null != CurrentChoice) 1042 { 1043 if (null == ds) 1044 { 1045 CurrentChoice = null; 1046 } 1047 else 1048 { 1049 // This makes sure that the CurrentChoice value is set to null if 1050 // it was deleted during the deviceSpecific object editing 1051 if (CurrentChoice.Filter.Length == 0) 1052 { 1053 TemplateDeviceFilter = SR.GetString(SR.DeviceFilter_DefaultChoice); 1054 } 1055 else 1056 { 1057 TemplateDeviceFilter = DesignerUtility.ChoiceToUniqueIdentifier(CurrentChoice); 1058 } 1059 } 1060 } 1061 } 1062 IDeviceSpecificDesigner.UseCurrentDeviceSpecificID()1063 void IDeviceSpecificDesigner.UseCurrentDeviceSpecificID() 1064 { 1065 } 1066 1067 //////////////////////////////////////////////////////////////////////// 1068 // End IDeviceSpecificDesigner Implementation 1069 //////////////////////////////////////////////////////////////////////// 1070 1071 // Hack : Internal class used to provide TemplateContainerAttribute for Templates. 1072 [ 1073 System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, 1074 Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 1075 ] 1076 [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.")] 1077 internal class TemplateContainer 1078 { 1079 [ 1080 TemplateContainer(typeof(MobileListItem)) 1081 ] 1082 internal ITemplate HeaderTemplate 1083 { 1084 get {return null;} 1085 } 1086 1087 [ 1088 TemplateContainer(typeof(MobileListItem)) 1089 ] 1090 internal ITemplate FooterTemplate 1091 { 1092 get {return null;} 1093 } 1094 1095 [ 1096 TemplateContainer(typeof(MobileListItem)) 1097 ] 1098 internal ITemplate ItemTemplate 1099 { 1100 get {return null;} 1101 } 1102 1103 [ 1104 TemplateContainer(typeof(MobileListItem)) 1105 ] 1106 internal ITemplate AlternatingItemTemplate 1107 { 1108 get {return null;} 1109 } 1110 1111 [ 1112 TemplateContainer(typeof(MobileListItem)) 1113 ] 1114 internal ITemplate SeparatorTemplate 1115 { 1116 get {return null;} 1117 } 1118 1119 [ 1120 TemplateContainer(typeof(MobileListItem)) 1121 ] 1122 internal ITemplate ContentTemplate 1123 { 1124 get {return null;} 1125 } 1126 1127 [ 1128 TemplateContainer(typeof(MobileListItem)) 1129 ] 1130 internal ITemplate LabelTemplate 1131 { 1132 get {return null;} 1133 } 1134 1135 [ 1136 TemplateContainer(typeof(MobileListItem)) 1137 ] 1138 internal ITemplate ItemDetailsTemplate 1139 { 1140 get {return null;} 1141 } 1142 } 1143 } 1144 } 1145