|
//------------------------------------------------------------------------------
// <copyright file="PropertyOverridesDialog.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.Design.MobileControls
{
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using Control = System.Web.UI.Control;
using System.Web.UI.MobileControls;
using System.Web.UI.Design.MobileControls.Converters;
using System.Web.UI.Design.MobileControls.Util;
[
System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
internal sealed class PropertyOverridesDialog :
DesignerForm, IRefreshableDeviceSpecificEditor, IDeviceSpecificDesigner
{
private bool _isDirty = true;
private IDeviceSpecificDesigner _designer;
private int _mergingContext;
private System.Windows.Forms.Control _header;
private String _currentDeviceSpecificID;
private IDictionary _cachedDeviceSpecifics =
new HybridDictionary(true /* make case-insensitive */);
private bool _ignoreSelectionChanged = true;
private System.Windows.Forms.Label _lblProperties;
private System.Windows.Forms.PropertyGrid _pgProperties;
private System.Windows.Forms.Button _btnEditFilters;
private System.Windows.Forms.ComboBox _cbChoices;
private System.Windows.Forms.Label _lblAppliedFilters;
private System.Windows.Forms.Button _cmdOK;
private System.Windows.Forms.Button _cmdCancel;
private System.Windows.Forms.Panel _pnlMain;
internal PropertyOverridesDialog(
IDeviceSpecificDesigner designer,
int mergingContext
) : base(designer.UnderlyingControl.Site) {
_designer = designer;
_mergingContext = mergingContext;
// Required for Win Form Designer support
InitializeComponent();
this._lblAppliedFilters.Text =
SR.GetString(SR.PropertyOverridesDialog_AppliedDeviceFilters);
this._btnEditFilters.Text = SR.GetString(SR.GenericDialog_Edit);
this._lblProperties.Text =
SR.GetString(SR.PropertyOverridesDialog_DeviceSpecificProperties);
this._cmdOK.Text = SR.GetString(SR.GenericDialog_OKBtnCaption);
this._cmdCancel.Text = SR.GetString(SR.GenericDialog_CancelBtnCaption);
int tabOffset = GenericUI.InitDialog(
this,
_designer,
_mergingContext
);
this.Text = _designer.UnderlyingControl.ID
+ " - " + SR.GetString(SR.PropertyOverridesDialog_Title);
SetTabIndexes(tabOffset);
_designer.SetDeviceSpecificEditor(this);
// Note that the following can cause an
// IDeviceSpecificDesigner.Refresh() to occur as a side-effect.
_designer.RefreshHeader(_mergingContext);
_ignoreSelectionChanged = false;
// NOTE: Calling CurrentDeviceSpecificID will cause a refresh to
// happen as a side effect.
_currentDeviceSpecificID = _designer.CurrentDeviceSpecificID;
if(_currentDeviceSpecificID != null)
{
_cbChoices.Items.Clear();
LoadChoices(_currentDeviceSpecificID);
if(!ValidateLoadedChoices())
{
// Throw to prevent dialog from opening. Caught and hidden
// by PropertyOverridesTypeEditor.cs
throw new InvalidChoiceException(
"Property overrides dialog can not open because there " +
"are invalid choices defined in the page."
);
}
}
// Register Event Handlers
_cbChoices.SelectedIndexChanged += new EventHandler(
OnFilterSelected
);
_btnEditFilters.Click += new EventHandler(OnEditFilters);
_cmdOK.Click += new EventHandler(OnOK);
_cmdCancel.Click += new EventHandler(OnCancel);
UpdateUI();
}
protected override string HelpTopic {
get {
return "net.Mobile.PropertyOverridesDialog";
}
}
internal void SetTabIndexes(int tabOffset)
{
this._pnlMain.TabIndex = ++tabOffset;
this._lblAppliedFilters.TabIndex = ++tabOffset;
this._cbChoices.TabIndex = ++tabOffset;
this._btnEditFilters.TabIndex = ++tabOffset;
this._lblProperties.TabIndex = ++tabOffset;
this._pgProperties.TabIndex = ++tabOffset;
this._cmdOK.TabIndex = ++tabOffset;
this._cmdCancel.TabIndex = ++tabOffset;
}
private void InitializeComponent()
{
this._cbChoices = new System.Windows.Forms.ComboBox();
this._cmdOK = new System.Windows.Forms.Button();
this._btnEditFilters = new System.Windows.Forms.Button();
this._pnlMain = new System.Windows.Forms.Panel();
this._pgProperties = new System.Windows.Forms.PropertyGrid();
this._lblProperties = new System.Windows.Forms.Label();
this._lblAppliedFilters = new System.Windows.Forms.Label();
this._cmdCancel = new System.Windows.Forms.Button();
this._cbChoices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this._cbChoices.DropDownWidth = 195;
this._cbChoices.Location = new System.Drawing.Point(0, 16);
this._cbChoices.Size = new System.Drawing.Size(195, 21);
this._cmdOK.Location = new System.Drawing.Point(120, 290);
this._cmdCancel.Location = new System.Drawing.Point(201, 290);
this._btnEditFilters.Location = new System.Drawing.Point(201, 15);
this._btnEditFilters.Size = new System.Drawing.Size(75, 23);
this._pnlMain.Anchor = (System.Windows.Forms.AnchorStyles.Bottom
| System.Windows.Forms.AnchorStyles.Left);
this._pnlMain.Controls.AddRange(new System.Windows.Forms.Control[] {
this._cmdCancel,
this._cmdOK,
this._lblProperties,
this._pgProperties,
this._btnEditFilters,
this._cbChoices,
this._lblAppliedFilters});
this._pnlMain.Location = new System.Drawing.Point(6, 5);
this._pnlMain.Size = new System.Drawing.Size(276, 313);
this._pgProperties.CommandsVisibleIfAvailable = false;
this._pgProperties.HelpVisible = false;
this._pgProperties.LargeButtons = false;
this._pgProperties.LineColor = System.Drawing.SystemColors.ScrollBar;
this._pgProperties.Location = new System.Drawing.Point(0, 64);
this._pgProperties.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
this._pgProperties.Size = new System.Drawing.Size(275, 220);
this._pgProperties.Text = "PropertyGrid";
this._pgProperties.ToolbarVisible = false;
this._pgProperties.ViewBackColor = System.Drawing.SystemColors.Window;
this._pgProperties.ViewForeColor = System.Drawing.SystemColors.WindowText;
this._pgProperties.PropertyValueChanged += new PropertyValueChangedEventHandler(this.OnPropertyValueChanged);
this._lblProperties.Location = new System.Drawing.Point(0, 48);
this._lblProperties.Size = new System.Drawing.Size(275, 16);
this._lblAppliedFilters.Size = new System.Drawing.Size(275, 16);
this.AcceptButton = _cmdOK;
this.CancelButton = _cmdCancel;
this.ClientSize = new System.Drawing.Size(285, 325);
this.Controls.AddRange(new System.Windows.Forms.Control[] {this._pnlMain});
}
private void CacheState(String deviceSpecificID)
{
_cachedDeviceSpecifics[deviceSpecificID] =
new PropertyOverridesCachedState(_cbChoices);
}
private void CacheCurrentState()
{
CacheState(_currentDeviceSpecificID);
}
private bool RestoreState(String deviceSpecificID)
{
if (null != deviceSpecificID)
{
_currentDeviceSpecificID = deviceSpecificID.ToLower(CultureInfo.InvariantCulture);
PropertyOverridesCachedState state =
(PropertyOverridesCachedState) _cachedDeviceSpecifics[
_currentDeviceSpecificID
];
if(state != null)
{
state.Restore(_cbChoices);
foreach(ChoiceTreeNode node in state.Choices)
{
node.Choice.Refresh();
}
return true;
}
}
else
{
_currentDeviceSpecificID = null;
}
return false;
}
[Conditional("DEBUG")]
private void debug_CheckChoicesForDuplicate(DeviceSpecificChoice runtimeChoice)
{
foreach(ChoiceTreeNode choiceNode in _cbChoices.Items)
{
if(choiceNode.Name == runtimeChoice.Filter
&& choiceNode.RuntimeChoice.Argument == runtimeChoice.Argument)
{
Debug.Fail("Loaded duplicate choice: " +
DesignerUtility.ChoiceToUniqueIdentifier(runtimeChoice));
}
}
}
private void LoadChoices(String deviceSpecificID)
{
DeviceSpecific ds;
_designer.GetDeviceSpecific(deviceSpecificID, out ds);
LoadChoices(ds);
}
private void LoadChoices(DeviceSpecific deviceSpecific)
{
if(deviceSpecific != null)
{
foreach(DeviceSpecificChoice runtimeChoice in deviceSpecific.Choices)
{
debug_CheckChoicesForDuplicate(runtimeChoice);
ChoiceTreeNode newChoiceNode = new ChoiceTreeNode(
null,
runtimeChoice,
_designer
);
newChoiceNode.IncludeArgument = true;
_cbChoices.Items.Add(newChoiceNode);
}
}
UpdateUI();
}
private bool ValidateLoadedChoices()
{
StringCollection duplicateChoices =
DesignerUtility.GetDuplicateChoiceTreeNodes(
_cbChoices.Items
);
if(duplicateChoices.Count > 0)
{
if (!_ignoreSelectionChanged)
{
GenericUI.ShowWarningMessage(
SR.GetString(SR.PropertyOverridesDialog_Title),
SR.GetString(SR.PropertyOverridesDialog_DuplicateChoices,
GenericUI.BuildCommaDelimitedList(duplicateChoices))
);
}
return false;
}
return true;
}
private void SaveChoices()
{
if(_currentDeviceSpecificID != null)
{
CacheCurrentState();
}
foreach (DictionaryEntry entry in _cachedDeviceSpecifics)
{
PropertyOverridesCachedState state =
(PropertyOverridesCachedState) entry.Value;
state.SaveChoicesFromComboBox(
_designer,
(String) entry.Key
);
}
}
private void UpdateUI()
{
if(_cbChoices.SelectedItem == null && _cbChoices.Items.Count > 0)
{
_cbChoices.SelectedItem = _cbChoices.Items[0];
}
ChoiceTreeNode choice = (ChoiceTreeNode) _cbChoices.SelectedItem;
bool isChoiceSelected = (choice != null);
if (isChoiceSelected)
{
_cbChoices.Text = choice.ToString();
_pgProperties.SelectedObject =
choice.Choice;
}
else
{
_cbChoices.Text = String.Empty;
_pgProperties.SelectedObject = null;
}
_cbChoices.Enabled = isChoiceSelected;
_pgProperties.Enabled = isChoiceSelected;
_btnEditFilters.Enabled = (_currentDeviceSpecificID != null);
}
private void SetDirty(bool dirty)
{
if (dirty)
{
if (false == _isDirty)
{
_isDirty = true;
_cmdCancel.Text = SR.GetString(SR.GenericDialog_CancelBtnCaption);
}
}
else
{
if (true == _isDirty)
{
_isDirty = false;
_cmdCancel.Text = SR.GetString(SR.GenericDialog_CloseBtnCaption);
}
}
}
////////////////////////////////////////////////////////////////////////
// Begin Event Handling
////////////////////////////////////////////////////////////////////////
private void OnEditFilters(Object sender, EventArgs e)
{
ISite componentSite = ((IComponent)(_designer.UnderlyingControl)).Site;
Debug.Assert(componentSite != null, "Expected the runtime control to be sited.");
IComponentChangeService changeService =
(IComponentChangeService)componentSite.GetService(typeof(IComponentChangeService));
IMobileWebFormServices wfServices =
(IMobileWebFormServices)componentSite.GetService(typeof(IMobileWebFormServices));
DialogResult result = DialogResult.Cancel;
try
{
AppliedDeviceFiltersDialog dialog = new
AppliedDeviceFiltersDialog(
this,
_mergingContext
);
result = dialog.ShowDialog();
}
finally
{
if (result != DialogResult.Cancel)
{
SaveChoices();
SetDirty(false);
if (changeService != null)
{
changeService.OnComponentChanged(_designer.UnderlyingControl, null, null, null);
}
}
}
}
private void OnFilterSelected(Object sender, EventArgs e)
{
UpdateUI();
}
private void OnOK(Object sender, EventArgs e)
{
SaveChoices();
Close();
DialogResult = DialogResult.OK;
}
private void OnCancel(Object sender, EventArgs e)
{
Close();
DialogResult = DialogResult.Cancel;
}
private void OnPropertyValueChanged(Object sender,
PropertyValueChangedEventArgs e)
{
SetDirty(true);
}
////////////////////////////////////////////////////////////////////////
// End Event Handling
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Begin IRefreshableComponentEditor Implementation
////////////////////////////////////////////////////////////////////////
bool IRefreshableDeviceSpecificEditor.RequestRefresh()
{
return true;
}
void IRefreshableDeviceSpecificEditor.Refresh(
String deviceSpecificID,
DeviceSpecific deviceSpecific
) {
if (_currentDeviceSpecificID != null)
{
CacheCurrentState();
}
_cbChoices.Items.Clear();
if (!RestoreState(deviceSpecificID))
{
LoadChoices(deviceSpecific);
if(!ValidateLoadedChoices())
{
_designer.RefreshHeader(
MobileControlDesigner.MergingContextProperties
);
}
}
UpdateUI();
}
void IRefreshableDeviceSpecificEditor.UnderlyingObjectsChanged()
{
SaveChoices();
SetDirty(false);
}
private bool InExternalCacheEditMode
{
get
{
return _cacheBuffer != null;
}
}
private IDictionary _cacheBuffer = null;
void IRefreshableDeviceSpecificEditor.BeginExternalDeviceSpecificEdit()
{
Debug.Assert(!InExternalCacheEditMode,
"Call to BeginExternalDeviceSpecificEdit() while already in external "
+ "cache edit mode.");
if(_currentDeviceSpecificID != null)
{
CacheCurrentState();
_currentDeviceSpecificID = null;
}
_cacheBuffer = new HybridDictionary(
true /* make case-insensitive*/ );
foreach(DictionaryEntry entry in _cachedDeviceSpecifics)
{
_cacheBuffer.Add(entry.Key, entry.Value);
}
}
void IRefreshableDeviceSpecificEditor.EndExternalDeviceSpecificEdit(
bool commitChanges)
{
Debug.Assert(InExternalCacheEditMode,
"Call to EndExternalDeviceSpecificEdit() while not in external "
+ "cache edit mode.");
if(commitChanges)
{
_cachedDeviceSpecifics = _cacheBuffer;
}
_cacheBuffer = null;
}
void IRefreshableDeviceSpecificEditor.DeviceSpecificRenamed(
String oldDeviceSpecificID, String newDeviceSpecificID)
{
Debug.Assert(InExternalCacheEditMode,
"Call to DeviceSpecificRenamed() while not in external "
+ "cache edit mode.");
Object value = _cacheBuffer[oldDeviceSpecificID];
if(value != null)
{
_cacheBuffer.Remove(oldDeviceSpecificID);
_cacheBuffer.Add(newDeviceSpecificID, value);
}
}
void IRefreshableDeviceSpecificEditor.DeviceSpecificDeleted(
String deviceSpecificID)
{
Debug.Assert(InExternalCacheEditMode,
"Call to DeviceSpecificDeleted() while not in external "
+ "cache edit mode.");
_cacheBuffer.Remove(deviceSpecificID);
}
////////////////////////////////////////////////////////////////////////
// End IRefreshableComponentEditor Implementation
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// Begin IDeviceSpecificDesigner Implementation
////////////////////////////////////////////////////////////////////////
void IDeviceSpecificDesigner.SetDeviceSpecificEditor
(IRefreshableDeviceSpecificEditor editor)
{
}
String IDeviceSpecificDesigner.CurrentDeviceSpecificID
{
get
{
return _currentDeviceSpecificID;
}
}
System.Windows.Forms.Control IDeviceSpecificDesigner.Header
{
get
{
return _header;
}
}
System.Web.UI.Control IDeviceSpecificDesigner.UnderlyingControl
{
get
{
return _designer.UnderlyingControl;
}
}
Object IDeviceSpecificDesigner.UnderlyingObject
{
get
{
return _designer.UnderlyingObject;
}
}
bool IDeviceSpecificDesigner.GetDeviceSpecific(String deviceSpecificParentID, out DeviceSpecific ds)
{
Debug.Assert(deviceSpecificParentID == _currentDeviceSpecificID);
ds = null;
if (_cbChoices.Items.Count > 0)
{
ds = new DeviceSpecific();
foreach (ChoiceTreeNode choiceNode in _cbChoices.Items)
{
DeviceSpecificChoice choice = choiceNode.Choice.RuntimeChoice;
ds.Choices.Add(choice);
}
}
return true;
}
void IDeviceSpecificDesigner.SetDeviceSpecific(String deviceSpecificParentID, DeviceSpecific ds)
{
Debug.Assert(_currentDeviceSpecificID != null);
_cbChoices.Items.Clear();
LoadChoices(ds);
UpdateUI();
}
void IDeviceSpecificDesigner.InitHeader(int mergingContext)
{
HeaderPanel panel = new HeaderPanel();
HeaderLabel lblDescription = new HeaderLabel();
lblDescription.TabIndex = 0;
lblDescription.Text = SR.GetString(SR.MobileControl_SettingGenericChoiceDescription);
panel.Height = lblDescription.Height;
panel.Width = lblDescription.Width;
panel.Controls.Add(lblDescription);
_header = panel;
}
void IDeviceSpecificDesigner.RefreshHeader(int mergingContext)
{
}
void IDeviceSpecificDesigner.UseCurrentDeviceSpecificID()
{
}
/////////////////////////////////////////////////////////////////////////
// End IDeviceSpecificDesigner Implementation
/////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////
// Begin Internal Class
////////////////////////////////////////////////////////////////////////////
[
System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
internal class ChoicePropertyFilter :
ICustomTypeDescriptor, IDeviceSpecificChoiceDesigner, IComponent
{
private DeviceSpecificChoice _choice;
private Object _copyOfOriginalObject;
private Object _underlyingObject;
private IDeviceSpecificDesigner _designer;
private Hashtable _specialProp_buffer = new Hashtable();
private EventHandler _specialProp_delegate = null;
private ISite _site = null;
private EventHandlerList _events;
private static readonly Object _eventDisposed = new Object();
private static readonly String _alternateUrl = "AlternateUrl";
private static readonly String _navigateUrl = "NavigateUrl";
internal ChoicePropertyFilter(
DeviceSpecificChoice choice,
IDeviceSpecificDesigner designer,
ISite site
) {
_events = new EventHandlerList();
_choice = choice;
_site = site;
_designer = designer;
CreateLocalCopiesOfObjects();
}
private void CreateLocalCopiesOfObjects()
{
// We make this copy of the original to remove the object from
// the inheritance chain.
_copyOfOriginalObject = CloneTarget(_designer.UnderlyingObject);
_underlyingObject = CloneTarget(_designer.UnderlyingObject);
// We need to pop up editors when certain property values change
RegisterForPropertyChangeEvents();
// Copy properties set on DeviceSpecificChoice
ApplyChoiceToRuntimeControl();
}
internal void Refresh()
{
ApplyChangesToRuntimeChoice();
CreateLocalCopiesOfObjects();
}
private void RegisterForPropertyChangeEvents()
{
foreach(PropertyDescriptor property in TypeDescriptor.GetProperties(
_underlyingObject.GetType()
)) {
if(property.Converter is NavigateUrlConverter &&
(property.Name == _navigateUrl ||
property.Name == _alternateUrl))
{
//
if (property.Name == _navigateUrl)
{
_specialProp_delegate = new EventHandler(OnNavigateUrlChanged);
}
else
{
_specialProp_delegate = new EventHandler(OnAlternateUrlChanged);
}
_specialProp_buffer[property.Name] = property.GetValue(_underlyingObject);
property.AddValueChanged(
_underlyingObject,
_specialProp_delegate
);
}
}
}
private Object CloneTarget(Object target)
{
Object clone = Activator.CreateInstance(
target.GetType()
);
// We need to copy the Site over to the new object incase setting
// properties has a side effect that requires the component model
// to be intact. (e.g., Launching UrlPicker for NavigateUrl).
if(clone is IComponent)
{
((IComponent)clone).Site = ((IComponent)target).Site;
}
// We also need to copy the Page over in case runtime properties
// try to access the page.
if(clone is System.Web.UI.Control)
{
((Control)clone).Page = ((Control)target).Page;
}
CopyOverridableProperties(target, clone);
return clone;
}
private void CopyStyleProperties(Style source, Style dest)
{
// We copy the StateBag to duplicate the style properties without
// walking the inheritance.
dest.State.Clear();
foreach(String key in source.State.Keys)
{
dest.State[key] = source.State[key];
}
}
private void CopyOverridableProperties(Object source, Object dest)
{
MobileControl destControl = null;
// HACK: To avoid copying expandable property FontInfo. We will
// need to required that expandable properties implement
// ICloneable for our designer extensibility story.
if(source is Style)
{
CopyStyleProperties((Style)source, (Style)dest);
return;
}
if(source is MobileControl)
{
// If the control is a MobileControl, we copy the style's
// StateBag to get the non-inherited proprety values.
destControl = (MobileControl) dest;
MobileControl sourceControl = (MobileControl) source;
CopyStyleProperties(sourceControl.Style, destControl.Style);
}
// Copy remaining properties not contained in the style (or
// all properties if not a mobile control.)
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(dest.GetType());
foreach(PropertyDescriptor property in properties)
{
if(IsDeviceOverridable(property)
&& (destControl == null
|| !PropertyExistsInStyle(property, destControl.Style)))
{
CopyProperty(property, source, dest);
}
}
}
private void CopyProperty(PropertyDescriptor property,
Object source,
Object dest)
{
Object value = property.GetValue(source);
if(property.Converter is ExpandableObjectConverter)
{
if(value is ICloneable)
{
value = ((ICloneable)value).Clone();
}
else
{
throw new Exception(
SR.GetString(
SR.PropertyOverridesDialog_NotICloneable,
property.Name,
property.PropertyType.FullName
)
);
}
}
property.SetValue(dest, value);
}
private bool PropertyExistsInStyle(
PropertyDescriptor property, Style style)
{
return style.GetType().GetProperty(property.Name) != null;
}
public event EventHandler Disposed
{
add
{
_events.AddHandler(_eventDisposed, value);
}
remove
{
_events.RemoveHandler(_eventDisposed, value);
}
}
public ISite Site
{
get
{
Debug.Assert(_site != null);
return _site;
}
set
{
_site = value;
}
}
public void Dispose()
{
if (_events != null)
{
EventHandler handler = (EventHandler)_events[_eventDisposed];
if (handler != null) handler(this, EventArgs.Empty);
}
}
private void OnNavigateUrlChanged(Object sender, EventArgs e)
{
OnSpecialPropertyChanged(sender, true);
}
private void OnAlternateUrlChanged(Object sender, EventArgs e)
{
OnSpecialPropertyChanged(sender, false);
}
//
private void OnSpecialPropertyChanged(Object sender, bool navigateUrl)
{
IComponent component = (IComponent) sender;
PropertyDescriptor property
= TypeDescriptor.GetProperties(component)[navigateUrl ? _navigateUrl : _alternateUrl];
String newValue = (String) property.GetValue(component);
String oldValue = (String) _specialProp_buffer[navigateUrl ? _navigateUrl : _alternateUrl];
newValue = NavigateUrlConverter.GetUrl(
component,
newValue,
oldValue
);
property.RemoveValueChanged(
_underlyingObject,
_specialProp_delegate
);
property.SetValue(component, newValue);
property.AddValueChanged(
_underlyingObject,
_specialProp_delegate
);
}
private static bool IsDeviceOverridable(PropertyDescriptor property)
{
//
return (
property.IsBrowsable
&& ((!property.IsReadOnly)
|| (property.Converter is ExpandableObjectConverter))
&& !property.SerializationVisibility.Equals(
DesignerSerializationVisibility.Hidden)
&& property.Name != "ID"
);
}
private void ApplyChoiceToRuntimeControl()
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(
_underlyingObject.GetType());
foreach(PropertyDescriptor property in properties)
{
if(IsDeviceOverridable(property))
{
ApplyChoiceToRuntimeControl_helper(
property,
_underlyingObject,
""
);
}
}
}
private void ApplyChoiceToRuntimeControl_helper(
PropertyDescriptor property,
Object target,
String prefix
) {
String propertyName = prefix + property.Name;
String value = ((IAttributeAccessor)_choice).GetAttribute(propertyName) as String;
if(property.Converter is ExpandableObjectConverter)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(
property.PropertyType
);
foreach(PropertyDescriptor embeddedProperty in properties)
{
if(IsDeviceOverridable(embeddedProperty))
{
ApplyChoiceToRuntimeControl_helper(
embeddedProperty,
property.GetValue(target),
propertyName + "-"
);
}
}
return;
}
if(value != null)
{
try
{
property.SetValue(
target,
property.Converter.ConvertFromString(value)
);
}
catch
{
GenericUI.ShowWarningMessage(
SR.GetString(SR.PropertyOverridesDialog_Title),
SR.GetString(
SR.PropertyOverridesDialog_InvalidPropertyValue,
value,
propertyName
)
);
}
}
}
private void ApplyChangesToRuntimeChoice()
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(
_underlyingObject.GetType()
);
foreach(PropertyDescriptor property in properties)
{
if (IsDeviceOverridable(property))
{
ApplyChangesToRuntimeChoice_helper(
property,
_copyOfOriginalObject,
_underlyingObject,
"");
}
}
}
private void ApplyChangesToRuntimeChoice_helper(
PropertyDescriptor property,
Object sourceTarget,
Object destTarget,
String prefix
) {
Object oldValue = property.GetValue(sourceTarget);
Object newValue = property.GetValue(destTarget);
String propertyName = prefix + property.Name;
if(property.Converter is ExpandableObjectConverter)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(
newValue.GetType()
);
foreach(PropertyDescriptor embeddedProperty in properties)
{
if(IsDeviceOverridable(embeddedProperty))
{
ApplyChangesToRuntimeChoice_helper(
embeddedProperty,
oldValue,
newValue,
propertyName + "-"
);
}
}
}
else if(IsDeviceOverridable(property))
{
IAttributeAccessor overrides = (IAttributeAccessor)_choice;
String oldValueString =
property.Converter.ConvertToInvariantString(
oldValue
);
String newValueString =
property.Converter.ConvertToInvariantString(
newValue
);
if(newValueString != oldValueString)
{
overrides.SetAttribute(propertyName, newValueString);
}
else
{
// Clear any previous values we might have loaded
overrides.SetAttribute(propertyName, null);
}
}
}
internal DeviceSpecificChoice RuntimeChoice
{
get
{
ApplyChangesToRuntimeChoice();
return _choice;
}
}
internal IDeviceSpecificDesigner Designer
{
get
{
return _designer;
}
}
internal Object Owner
{
get
{
return _underlyingObject;
}
}
private PropertyDescriptorCollection PreFilterProperties(
PropertyDescriptorCollection originalProperties
) {
PropertyDescriptorCollection newProperties =
new PropertyDescriptorCollection(
new PropertyDescriptor[] {}
);
foreach(PropertyDescriptor property in originalProperties)
{
if (IsDeviceOverridable(property))
{
newProperties.Add(property);
}
}
PropertyDescriptor[] arpd = new PropertyDescriptor[newProperties.Count];
for(int i = 0; i < newProperties.Count; i++)
{
arpd[i] = newProperties[i];
}
newProperties = new PropertyDescriptorCollection(arpd);
return newProperties;
}
////////////////////////////////////////////////////////////////////
// Begin ICustomTypeDescriptor Implementation
////////////////////////////////////////////////////////////////////
System.ComponentModel.AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(this.GetType());
}
String ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(this.GetType());
}
String ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(this.GetType());
}
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this.GetType());
}
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this.GetType());
}
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this.GetType());
}
Object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this.GetType(), editorBaseType);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(this.GetType());
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this.GetType(), attributes);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
PropertyDescriptorCollection collection =
TypeDescriptor.GetProperties(
_underlyingObject.GetType()
);
collection = PreFilterProperties(collection);
return collection;
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
PropertyDescriptorCollection collection =
TypeDescriptor.GetProperties(
_underlyingObject.GetType(),
attributes
);
collection = PreFilterProperties(collection);
return collection;
}
Object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor property)
{
return _underlyingObject;
}
////////////////////////////////////////////////////////////////////////
// End ICustomTypeDescriptor Implementation
////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Begin IDeviceSpecificChoiceDesigner Implementation
///////////////////////////////////////////////////////////////////////
Object IDeviceSpecificChoiceDesigner.UnderlyingObject
{
get
{
return _designer.UnderlyingObject;
}
}
Control IDeviceSpecificChoiceDesigner.UnderlyingControl
{
get
{
return _designer.UnderlyingControl;
}
}
///////////////////////////////////////////////////////////////////////
// End IDeviceSpecificChoiceDesigner Implementation
///////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////
// End Internal Class
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Begin Internal Class
/////////////////////////////////////////////////////////////////////////
[
System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
internal class PropertyOverridesCachedState : DeviceSpecificDialogCachedState
{
private ArrayList _cachedComboBox = null;
internal PropertyOverridesCachedState(
ComboBox comboBox
) {
_cachedComboBox = new ArrayList();
foreach(Object o in comboBox.Items)
{
_cachedComboBox.Add(o);
}
}
internal void Restore(
ComboBox comboBox
) {
Object selectedItem = comboBox.SelectedItem;
comboBox.Items.Clear();
comboBox.Items.AddRange(_cachedComboBox.ToArray());
if(selectedItem != null)
{
int index = comboBox.Items.IndexOf(selectedItem);
if(index >= 0)
{
comboBox.SelectedItem = comboBox.Items[index];
}
}
}
internal bool FilterExistsInComboBox(DeviceFilterNode filter)
{
foreach(DeviceFilterNode availableFilter in _cachedComboBox)
{
if(availableFilter.Name == filter.Name)
{
return true;
}
}
return false;
}
internal void SaveChoicesFromComboBox(
IDeviceSpecificDesigner designer,
String deviceSpecificID
) {
SaveChoices(designer, deviceSpecificID, _cachedComboBox);
}
internal ArrayList Choices
{
get
{
return _cachedComboBox;
}
}
}
/////////////////////////////////////////////////////////////////////////
// End Internal Class
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// Begin Internal Class
/////////////////////////////////////////////////////////////////////////
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
internal class InvalidChoiceException : ApplicationException
{
internal InvalidChoiceException(String message) : base(message)
{
}
}
/////////////////////////////////////////////////////////////////////////
// End Internal Class
/////////////////////////////////////////////////////////////////////////
}
|