Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / PropertyGridInternal / PropertyDescriptorGridEntry.cs / 1 / PropertyDescriptorGridEntry.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
/*
*/
namespace System.Windows.Forms.PropertyGridInternal {
using System.Runtime.Serialization.Formatters;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System;
using System.Collections;
using System.Reflection;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
using System.Drawing.Design;
using Microsoft.Win32;
using System.Globalization;
internal class PropertyDescriptorGridEntry : GridEntry {
internal PropertyDescriptor propertyInfo;
private TypeConverter exceptionConverter = null;
private UITypeEditor exceptionEditor = null;
private bool isSerializeContentsProp = false;
private byte parensAroundName = ParensAroundNameUnknown;
private IPropertyValueUIService pvSvc;
protected IEventBindingService eventBindings = null;
private bool pvSvcChecked;
private PropertyValueUIItem[] pvUIItems = null;
private Rectangle [] uiItemRects;
private bool readOnlyVerified = false;
private bool forceRenderReadOnly = false;
private string helpKeyword;
private string toolTipText = null;
private bool activeXHide = false;
private const int IMAGE_SIZE = 8;
private const byte ParensAroundNameUnknown = (byte)0xFF;
private const byte ParensAroundNameNo = (byte)0;
private const byte ParensAroundNameYes = (byte)1;
static IEventBindingService targetBindingService;
static IComponent targetComponent;
static EventDescriptor targetEventdesc;
[
SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // GridEntry classes are internal so we have complete
// control over who does what in the constructor.
]
internal PropertyDescriptorGridEntry(PropertyGrid ownerGrid, GridEntry peParent, bool hide)
: base(ownerGrid, peParent){
this.activeXHide = hide;
}
[
SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // GridEntry classes are internal so we have complete
// control over who does what in the constructor.
]
internal PropertyDescriptorGridEntry(PropertyGrid ownerGrid, GridEntry peParent, PropertyDescriptor propInfo, bool hide)
: base(ownerGrid, peParent) {
this.activeXHide = hide;
Initialize(propInfo);
}
///
///
/// specify that this grid entry should be allowed to be merged for.
/// multi-select.
///
public override bool AllowMerge {
get {
MergablePropertyAttribute mpa = (MergablePropertyAttribute)propertyInfo.Attributes[typeof(MergablePropertyAttribute)];
return mpa == null || mpa.IsDefaultAttribute();
}
}
internal override AttributeCollection Attributes {
get {
return propertyInfo.Attributes;
}
}
///
///
/// Retrieves the keyword that the VS help dynamic help window will
/// use when this IPE is selected.
///
public override string HelpKeyword {
get {
if (this.helpKeyword == null) {
object owner = GetValueOwner();
if (owner == null)
return null; //null exception protection.
HelpKeywordAttribute helpAttribute = (HelpKeywordAttribute)propertyInfo.Attributes[typeof(HelpKeywordAttribute)];
if (helpAttribute != null && !helpAttribute.IsDefaultAttribute()) {
return helpAttribute.HelpKeyword;
}
else if (this is ImmutablePropertyDescriptorGridEntry) {
helpKeyword = this.PropertyName;
GridEntry ge = this;
while (ge.ParentGridEntry != null) {
ge = ge.ParentGridEntry;
// for value classes, the equality will never work, so
// just try the type equality
if (ge.PropertyValue == owner || (owner.GetType().IsValueType && owner.GetType() == ge.PropertyValue.GetType())) {
helpKeyword = ge.PropertyName + "." + helpKeyword;
break;
}
}
}
else {
string typeName = "";
Type componentType = propertyInfo.ComponentType;
if (componentType.IsCOMObject) {
typeName = TypeDescriptor.GetClassName(owner);
}
else {
// make sure this property is declared on a class that
// is related to the component we're looking at.
// if it's not, it could be a shadow property so we need
// to try to find the real property.
//
Type ownerType = owner.GetType();
if (!componentType.IsPublic || !componentType.IsAssignableFrom(ownerType)) {
PropertyDescriptor componentProperty = TypeDescriptor.GetProperties(ownerType)[this.PropertyName];
if (componentProperty != null) {
componentType = componentProperty.ComponentType;
}
else {
componentType = null;
}
}
if (componentType == null) {
typeName = TypeDescriptor.GetClassName(owner);
}
else {
//
//if (helpAttribute != null && !helpAttribute.IsDefaultAttribute()) {
// typeName = helpAttribute.HelpKeyword;
//}
//else {
typeName = componentType.FullName;
//}
}
}
helpKeyword = typeName + "." + propertyInfo.Name;
}
}
return this.helpKeyword;
}
}
internal override string LabelToolTipText {
get {
return (toolTipText != null ? toolTipText : base.LabelToolTipText);
}
}
internal override string HelpKeywordInternal{
get {
return this.PropertyLabel;
}
}
internal override bool Enumerable {
get {
return base.Enumerable && !IsPropertyReadOnly;
}
}
protected virtual bool IsPropertyReadOnly {
get {
return propertyInfo.IsReadOnly;
}
}
public override bool IsValueEditable {
get {
return this.exceptionConverter == null && !IsPropertyReadOnly && base.IsValueEditable;
}
}
public override bool NeedsDropDownButton{
get {
return base.NeedsDropDownButton && !IsPropertyReadOnly;
}
}
internal bool ParensAroundName {
get {
if (ParensAroundNameUnknown == this.parensAroundName) {
if (((ParenthesizePropertyNameAttribute)propertyInfo.Attributes[typeof(ParenthesizePropertyNameAttribute)]).NeedParenthesis) {
this.parensAroundName = ParensAroundNameYes;
}
else {
this.parensAroundName = ParensAroundNameNo;
}
}
return (this.parensAroundName == ParensAroundNameYes);
}
}
public override string PropertyCategory {
get {
string category = propertyInfo.Category;
if (category == null || category.Length == 0) {
category = base.PropertyCategory;
}
return category;
}
}
///
///
/// Retrieves the PropertyDescriptor that is surfacing the given object/
///
public override PropertyDescriptor PropertyDescriptor {
get {
return propertyInfo;
}
}
public override string PropertyDescription {
get {
return propertyInfo.Description;
}
}
public override string PropertyLabel {
get {
string label = propertyInfo.DisplayName;
if (ParensAroundName) {
label = "(" + label + ")";
}
return label;
}
}
///
///
/// Returns non-localized name of this property.
///
public override string PropertyName {
get {
if (propertyInfo != null) {
return propertyInfo.Name;
}
return null;
}
}
public override Type PropertyType {
get {
return propertyInfo.PropertyType;
}
}
///
///
/// Gets or sets the value for the property that is represented
/// by this GridEntry.
///
public override object PropertyValue{
get {
try
{
object objRet = GetPropertyValueCore(GetValueOwner());
if (this.exceptionConverter != null)
{
// undo the exception converter
SetFlagsAndExceptionInfo(0, null, null);
}
return objRet;
}
catch (Exception e)
{
if (this.exceptionConverter == null)
{
// clear the flags
SetFlagsAndExceptionInfo(0, new ExceptionConverter(), new ExceptionEditor());
}
return e;
}
}
set {
SetPropertyValue(GetValueOwner(), value, false, null);
}
}
private IPropertyValueUIService PropertyValueUIService {
get {
if (!pvSvcChecked && this.pvSvc == null) {
this.pvSvc = (IPropertyValueUIService)GetService(typeof(IPropertyValueUIService));
pvSvcChecked = true;
}
return this.pvSvc;
}
}
private void SetFlagsAndExceptionInfo(int flags, ExceptionConverter converter, ExceptionEditor editor)
{
this.Flags = flags;
this.exceptionConverter = converter;
this.exceptionEditor = editor;
}
public override bool ShouldRenderReadOnly
{
get {
if (base.ForceReadOnly || forceRenderReadOnly) {
return true;
}
// if read only editable is set, make sure it's valid
//
if (propertyInfo.IsReadOnly && !readOnlyVerified && GetFlagSet(GridEntry.FLAG_READONLY_EDITABLE)) {
Type propType = this.PropertyType;
if (propType != null && (propType.IsArray || propType.IsValueType || propType.IsPrimitive)) {
SetFlag(FLAG_READONLY_EDITABLE,false);
SetFlag(FLAG_RENDER_READONLY, true);
forceRenderReadOnly = true;
}
}
readOnlyVerified = true;
if (base.ShouldRenderReadOnly){
if (!this.isSerializeContentsProp && !base.NeedsCustomEditorButton) {
return true;
}
}
return false;
}
}
///
///
/// Returns the type converter for this entry.
///
internal override TypeConverter TypeConverter {
get {
if (exceptionConverter != null) {
return exceptionConverter;
}
if (converter == null) {
converter = propertyInfo.Converter;
}
return base.TypeConverter;
}
}
///
///
/// Returns the type editor for this entry. This may return null if there
/// is no type editor.
///
internal override UITypeEditor UITypeEditor {
get {
if (exceptionEditor != null) {
return exceptionEditor;
}
editor = (UITypeEditor)propertyInfo.GetEditor(typeof(System.Drawing.Design.UITypeEditor));
return base.UITypeEditor;
}
}
///
///
/// Invokes the type editor for editing this item.
///
internal override void EditPropertyValue(PropertyGridView iva) {
base.EditPropertyValue(iva);
if (!IsValueEditable) {
RefreshPropertiesAttribute refreshAttr = (RefreshPropertiesAttribute)propertyInfo.Attributes[typeof(RefreshPropertiesAttribute)];
if ((refreshAttr != null && !refreshAttr.RefreshProperties.Equals(RefreshProperties.None))) {
this.GridEntryHost.Refresh(refreshAttr != null && refreshAttr.Equals(RefreshPropertiesAttribute.All));
}
}
}
internal override Point GetLabelToolTipLocation(int mouseX, int mouseY){
if (pvUIItems != null) {
for (int i = 0; i < pvUIItems.Length; i++) {
if (uiItemRects[i].Contains(mouseX, GridEntryHost.GetGridEntryHeight() / 2)) {
this.toolTipText = pvUIItems[i].ToolTip;
return new Point(mouseX, mouseY);
}
}
}
this.toolTipText = null;
return base.GetLabelToolTipLocation(mouseX, mouseY);
}
protected object GetPropertyValueCore(object target) {
if (propertyInfo == null) {
return null;
}
if (target is ICustomTypeDescriptor) {
target = ((ICustomTypeDescriptor)target).GetPropertyOwner(propertyInfo);
}
try {
return propertyInfo.GetValue(target);
}
catch {
throw;
}
}
protected void Initialize(PropertyDescriptor propInfo) {
propertyInfo = propInfo;
this.isSerializeContentsProp = (propertyInfo.SerializationVisibility == DesignerSerializationVisibility.Content);
Debug.Assert(propInfo != null, "Can't create propEntry because of null prop info");
if (!this.activeXHide && IsPropertyReadOnly) {
SetFlag(FLAG_TEXT_EDITABLE, false);
}
if (isSerializeContentsProp && TypeConverter.GetPropertiesSupported()) {
SetFlag(FL_EXPANDABLE, true);
}
}
protected virtual void NotifyParentChange(GridEntry ge) {
// now see if we need to notify the parent(s) up the chain
while (ge != null &&
ge is PropertyDescriptorGridEntry &&
((PropertyDescriptorGridEntry)ge).propertyInfo.Attributes.Contains(NotifyParentPropertyAttribute.Yes)) {
// find the next parent property with a differnet value owner
object owner = ge.GetValueOwner();
// find the next property descriptor with a different parent
while (!(ge is PropertyDescriptorGridEntry) || owner == ge.GetValueOwner()) {
ge = ge.ParentGridEntry;
if (ge == null) {
break;
}
}
// fire the change on that owner
if (ge != null) {
owner = ge.GetValueOwner();
IComponentChangeService changeService = ComponentChangeService;
if (changeService != null) {
changeService.OnComponentChanging(owner, ((PropertyDescriptorGridEntry)ge).propertyInfo);
changeService.OnComponentChanged(owner, ((PropertyDescriptorGridEntry)ge).propertyInfo, null, null);
}
ge.ClearCachedValues(false); //clear the value so it paints correctly next time.
PropertyGridView gv = this.GridEntryHost;
if (gv != null) {
gv.InvalidateGridEntryValue(ge);
}
}
}
}
internal override bool NotifyValueGivenParent(object obj, int type) {
if (obj is ICustomTypeDescriptor) {
obj = ((ICustomTypeDescriptor)obj).GetPropertyOwner(propertyInfo);
}
switch (type) {
case NOTIFY_RESET:
SetPropertyValue(obj, null, true, SR.GetString(SR.PropertyGridResetValue, this.PropertyName));
if (pvUIItems != null) {
for (int i = 0; i < pvUIItems.Length; i++) {
pvUIItems[i].Reset();
}
}
pvUIItems = null;
return false;
case NOTIFY_CAN_RESET:
try {
return propertyInfo.CanResetValue(obj) || (pvUIItems != null && pvUIItems.Length > 0);
}
catch {
if (this.exceptionConverter == null) {
// clear the flags
this.Flags = 0;
this.exceptionConverter = new ExceptionConverter();
this.exceptionEditor = new ExceptionEditor();
}
return false;
}
case NOTIFY_SHOULD_PERSIST:
try{
return propertyInfo.ShouldSerializeValue(obj);
}
catch {
if (this.exceptionConverter == null) {
// clear the flags
this.Flags = 0;
this.exceptionConverter = new ExceptionConverter();
this.exceptionEditor = new ExceptionEditor();
}
return false;
}
case NOTIFY_DBL_CLICK:
case NOTIFY_RETURN:
if (eventBindings == null) {
eventBindings = (IEventBindingService)GetService(typeof(IEventBindingService));
}
if (eventBindings != null) {
EventDescriptor descriptor = eventBindings.GetEvent(propertyInfo);
if (descriptor != null) {
return ViewEvent(obj, null, null, true);
}
}
break;
}
return false;
}
public override void OnComponentChanged() {
base.OnComponentChanged();
// If we got this it means someone called ITypeDescriptorContext.OnCompnentChanged.
// so we need to echo that change up the inheritance change in case the owner object isn't a sited component.
NotifyParentChange(this);
}
public override bool OnMouseClick(int x, int y, int count, MouseButtons button) {
if (pvUIItems != null && count == 2 && ((button & MouseButtons.Left) == MouseButtons.Left)) {
for (int i = 0; i < pvUIItems.Length; i++) {
if (uiItemRects[i].Contains(x, GridEntryHost.GetGridEntryHeight() / 2)) {
pvUIItems[i].InvokeHandler(this, propertyInfo, pvUIItems[i]);
return true;
}
}
}
return base.OnMouseClick(x, y, count, button);
}
public override void PaintLabel(System.Drawing.Graphics g, Rectangle rect, Rectangle clipRect, bool selected, bool paintFullLabel) {
base.PaintLabel(g, rect, clipRect, selected, paintFullLabel);
IPropertyValueUIService propValSvc = this.PropertyValueUIService;
if (propValSvc == null) {
return;
}
pvUIItems = propValSvc.GetPropertyUIValueItems(this, propertyInfo);
if (pvUIItems != null) {
if (uiItemRects == null || uiItemRects.Length != pvUIItems.Length) {
uiItemRects = new Rectangle[pvUIItems.Length];
}
for (int i = 0; i < pvUIItems.Length; i++) {
uiItemRects[i] = new Rectangle(rect.Right - ((IMAGE_SIZE+1)*(i+1)), (rect.Height - IMAGE_SIZE) / 2, IMAGE_SIZE, IMAGE_SIZE);
g.DrawImage(pvUIItems[i].Image, uiItemRects[i]);
}
GridEntryHost.LabelPaintMargin = (IMAGE_SIZE + 1) * pvUIItems.Length;
}
}
private object SetPropertyValue(object obj,object objVal, bool reset, string undoText) {
DesignerTransaction trans = null;
try
{
object oldValue = GetPropertyValueCore(obj);
if (objVal != null && objVal.Equals(oldValue))
{
return objVal;
}
ClearCachedValues();
IDesignerHost host = DesignerHost;
if (host != null)
{
string text = (undoText == null ? SR.GetString(SR.PropertyGridSetValue, propertyInfo.Name) : undoText);
trans = host.CreateTransaction(text);
}
// Usually IComponent things are sited and this notification will be
// fired automatically by the PropertyDescriptor. However, for non-IComponent sub objects
// or sub objects that are non-sited sub components, we need to manuall fire
// the notification.
//
bool needChangeNotify = !(obj is IComponent) || ((IComponent)obj).Site == null;
if (needChangeNotify)
{
try
{
if (ComponentChangeService != null)
{
ComponentChangeService.OnComponentChanging(obj, propertyInfo);
}
}
catch (CheckoutException coEx)
{
if (coEx == CheckoutException.Canceled)
{
return oldValue;
}
throw coEx;
}
}
bool wasExpanded = this.InternalExpanded;
int childCount = -1;
if (wasExpanded)
{
childCount = this.ChildCount;
}
RefreshPropertiesAttribute refreshAttr = (RefreshPropertiesAttribute)propertyInfo.Attributes[typeof(RefreshPropertiesAttribute)];
bool needsRefresh = wasExpanded || (refreshAttr != null && !refreshAttr.RefreshProperties.Equals(RefreshProperties.None));
if (needsRefresh)
{
DisposeChildren();
}
// Determine if this is an event being created, and if so, navigate to the event code
//
EventDescriptor eventDesc = null;
// This is possibly an event. Check it out.
//
if (obj != null && objVal is string)
{
if (eventBindings == null)
{
eventBindings = (IEventBindingService)GetService(typeof(IEventBindingService));
}
if (eventBindings != null)
{
eventDesc = eventBindings.GetEvent(propertyInfo);
}
// For a merged set of properties, the event binding service won't
// find an event. So, we ask type descriptor directly.
//
if (eventDesc == null)
{
// If we have a merged property descriptor, pull out one of
// the elements.
//
object eventObj = obj;
if (propertyInfo is MergePropertyDescriptor && obj is Array)
{
Array objArray = obj as Array;
if (objArray.Length > 0)
{
eventObj = objArray.GetValue(0);
}
}
eventDesc = TypeDescriptor.GetEvents(eventObj)[propertyInfo.Name];
}
}
bool setSuccessful = false;
try
{
if (reset)
{
propertyInfo.ResetValue(obj);
}
else if (eventDesc != null)
{
ViewEvent(obj, (string)objVal, eventDesc, false);
}
else
{ // Not an event
SetPropertyValueCore(obj, objVal, true);
}
setSuccessful = true;
// Now notify the change service that the change was successful.
//
if (needChangeNotify && ComponentChangeService != null)
{
ComponentChangeService.OnComponentChanged(obj, propertyInfo, null, objVal);
}
NotifyParentChange(this);
}
finally
{
// see if we need to refresh the property browser
// 1) if this property has the refreshpropertiesattribute, or
// 2) it's got expanded sub properties
//
if (needsRefresh && this.GridEntryHost != null)
{
RecreateChildren(childCount);
if (setSuccessful) {
this.GridEntryHost.Refresh(refreshAttr != null && refreshAttr.Equals(RefreshPropertiesAttribute.All));
}
}
}
}
catch (CheckoutException checkoutEx)
{
if (trans != null)
{
trans.Cancel();
trans = null;
}
if (checkoutEx == CheckoutException.Canceled)
{
return null;
}
throw;
}
catch
{
if (trans != null)
{
trans.Cancel();
trans = null;
}
throw;
}
finally {
if (trans != null) {
trans.Commit();
}
}
return obj;
}
protected void SetPropertyValueCore(object obj, object value, bool doUndo) {
if (propertyInfo == null) {
return;
}
// Store the current cursor and set it to the HourGlass.
//
Cursor oldCursor = Cursor.Current;
try {
Cursor.Current = Cursors.WaitCursor;
object target = obj;
if (target is ICustomTypeDescriptor) {
target = ((ICustomTypeDescriptor)target).GetPropertyOwner(propertyInfo);
}
// check the type of the object we are modifying. If it's a value type or an array,
// we need to modify the object and push the value back up to the parent.
//
bool treatAsValueType = false;
if (ParentGridEntry != null) {
Type propType = ParentGridEntry.PropertyType;
treatAsValueType = propType.IsValueType || propType.IsArray;
}
if (target != null) {
propertyInfo.SetValue(target, value);
// [....], okay, since the value that we modified may not
// be stored by the parent property, we need to push this
// value back into the parent. An example here is Size or
// Location, which return Point objects that are unconnected
// to the object they relate to. So we modify the Point object and
// push it back into the object we got it from.
//
if (treatAsValueType) {
GridEntry parent = this.ParentGridEntry;
if (parent != null && parent.IsValueEditable) {
parent.PropertyValue = obj;
}
}
}
}
finally {
// Flip back to the old cursor.
//
Cursor.Current = oldCursor;
}
}
///
///
/// Navigates code to the given event.
///
protected bool ViewEvent(object obj, string newHandler, EventDescriptor eventdesc, bool alwaysNavigate) {
object value = GetPropertyValueCore(obj);
string handler = value as string;
if (handler == null && value != null && TypeConverter != null && TypeConverter.CanConvertTo(typeof(string))) {
handler = TypeConverter.ConvertToString(value);
}
if (newHandler == null && !String.IsNullOrEmpty(handler)) {
newHandler = handler;
}
else if (handler == newHandler && !String.IsNullOrEmpty(newHandler)) {
return true;
}
IComponent component = obj as IComponent;
if (component == null && propertyInfo is MergePropertyDescriptor) {
// It's possible that multiple objects are selected, and we're trying to create an event for each of them
//
Array objArray = obj as Array;
if (objArray != null && objArray.Length > 0) {
component = objArray.GetValue(0) as IComponent;
}
}
if (component == null) {
return false;
}
if (propertyInfo.IsReadOnly) {
return false;
}
if (eventdesc == null) {
if (eventBindings == null) {
eventBindings = (IEventBindingService)GetService(typeof(IEventBindingService));
}
if (eventBindings != null) {
eventdesc = eventBindings.GetEvent(propertyInfo);
}
}
IDesignerHost host = this.DesignerHost;
DesignerTransaction trans = null;
try {
// This check can cause exceptions if the event has unreferenced dependencies, which we want to cath.
// This must be done before the transaction is started or the commit/cancel will also throw.
if (eventdesc.EventType == null) {
return false;
}
if (host != null) {
string compName = component.Site != null ? component.Site.Name : component.GetType().Name;
trans = DesignerHost.CreateTransaction(SR.GetString(SR.WindowsFormsSetEvent, compName + "." + this.PropertyName));
}
if (eventBindings == null) {
ISite site = component.Site;
if (site != null) {
eventBindings = (IEventBindingService)site.GetService(typeof(IEventBindingService));
}
}
if (newHandler == null && eventBindings != null) {
newHandler = eventBindings.CreateUniqueMethodName(component, eventdesc);
}
if (newHandler != null) {
// now walk through all the matching methods to see if this one exists.
// if it doesn't we'll wanna show code.
//
if (eventBindings != null) {
bool methodExists = false;
foreach (string methodName in eventBindings.GetCompatibleMethods(eventdesc)) {
if (newHandler == methodName) {
methodExists = true;
break;
}
}
if (!methodExists) {
alwaysNavigate = true;
}
}
propertyInfo.SetValue(obj, newHandler);
}
if (alwaysNavigate && eventBindings != null) {
targetBindingService = eventBindings;
targetComponent = component;
targetEventdesc = eventdesc;
Application.Idle += new EventHandler(PropertyDescriptorGridEntry.ShowCodeIdle);
}
}
catch {
if (trans != null) {
trans.Cancel();
trans = null;
}
throw;
}
finally {
if (trans != null) {
trans.Commit();
}
}
return true;
}
///
///
/// Displays the user code for the given event. This will return true if the user
/// code could be displayed, or false otherwise.
///
static private void ShowCodeIdle(object sender, EventArgs e) {
Application.Idle -= new EventHandler(PropertyDescriptorGridEntry.ShowCodeIdle);
if (targetBindingService != null) {
targetBindingService.ShowCode(targetComponent, targetEventdesc);
targetBindingService = null;
targetComponent = null;
targetEventdesc = null;
}
}
///
///
/// The exception converter is a type converter that displays an exception to the user.
///
private class ExceptionConverter : TypeConverter {
///
///
/// Converts the given object to another type. The most common types to convert
/// are to and from a string object. The default implementation will make a call
/// to ToString on the object if the object is valid and if the destination
/// type is string. If this cannot convert to the desitnation type, this will
/// throw a NotSupportedException.
///
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
if (destinationType == typeof(string)) {
if (value is Exception) {
Exception ex = (Exception)value;
if (ex.InnerException != null) {
ex = ex.InnerException;
}
return ex.Message;
}
return null;
}
throw GetConvertToException(value, destinationType);
}
}
///
///
/// The exception editor displays a message to the user.
///
private class ExceptionEditor : UITypeEditor {
///
///
/// Edits the given object value using the editor style provided by
/// GetEditorStyle. A service provider is provided so that any
/// required editing services can be obtained.
///
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
Exception except = value as Exception;
if (except != null) {
IUIService uis = null;
if (context != null) {
uis = (IUIService)context.GetService(typeof(IUIService));
}
if (uis != null) {
uis.ShowError(except);
}
else {
string message = except.Message;
if (message == null || message.Length == 0) message = except.ToString();
RTLAwareMessageBox.Show(null, message, SR.GetString(SR.PropertyGridExceptionInfo),
MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
}
}
return value;
}
///
///
/// Retrieves the editing style of the Edit method. If the method
/// is not supported, this will return None.
///
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
return UITypeEditorEditStyle.Modal;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DependencyPropertyValueSerializer.cs
- DataControlFieldHeaderCell.cs
- CustomErrorsSection.cs
- XmlKeywords.cs
- StateMachine.cs
- GeometryModel3D.cs
- ValidationResult.cs
- XslVisitor.cs
- EntitySetDataBindingList.cs
- MenuAdapter.cs
- RequestCachePolicyConverter.cs
- RelatedEnd.cs
- DataGridViewRow.cs
- RadioButtonBaseAdapter.cs
- ResourcePermissionBase.cs
- PropertyDescriptorCollection.cs
- SpellCheck.cs
- MD5.cs
- DecoderBestFitFallback.cs
- ChtmlTextWriter.cs
- DiagnosticEventProvider.cs
- UIPermission.cs
- SmiEventSink_Default.cs
- EventLogPropertySelector.cs
- WinFormsComponentEditor.cs
- XamlTypeMapper.cs
- ExpressionHelper.cs
- DBCSCodePageEncoding.cs
- MetadataCollection.cs
- DocumentSchemaValidator.cs
- RegistryPermission.cs
- Psha1DerivedKeyGeneratorHelper.cs
- PreProcessInputEventArgs.cs
- ServiceDebugBehavior.cs
- HttpApplication.cs
- FilterableAttribute.cs
- ObjectView.cs
- DecimalKeyFrameCollection.cs
- NavigationProperty.cs
- DocComment.cs
- Int32AnimationBase.cs
- IPAddress.cs
- SmiSettersStream.cs
- ProbeDuplexCD1AsyncResult.cs
- ClientScriptItemCollection.cs
- XamlStackWriter.cs
- CompositeFontFamily.cs
- ToolStripRendererSwitcher.cs
- BamlLocalizableResourceKey.cs
- HttpRawResponse.cs
- SchemaImporter.cs
- ProvideValueServiceProvider.cs
- MeshGeometry3D.cs
- Label.cs
- MexNamedPipeBindingElement.cs
- EntityPropertyMappingAttribute.cs
- safemediahandle.cs
- AssociationTypeEmitter.cs
- ImportContext.cs
- DescendantQuery.cs
- OracleParameterBinding.cs
- StylusDownEventArgs.cs
- XmlWrappingReader.cs
- PerfService.cs
- _BasicClient.cs
- CodeGen.cs
- TableProviderWrapper.cs
- SortedDictionary.cs
- HostingEnvironmentException.cs
- DataBoundControlAdapter.cs
- TableColumnCollection.cs
- MissingMethodException.cs
- AnnotationHighlightLayer.cs
- BasicCellRelation.cs
- RootBrowserWindowProxy.cs
- ConfigXmlSignificantWhitespace.cs
- XmlDataSource.cs
- DetailsViewCommandEventArgs.cs
- AxisAngleRotation3D.cs
- SmiMetaDataProperty.cs
- Point4D.cs
- PagePropertiesChangingEventArgs.cs
- glyphs.cs
- CharacterString.cs
- DataGridViewRowHeightInfoPushedEventArgs.cs
- XsltConvert.cs
- AppSecurityManager.cs
- WorkflowFileItem.cs
- X509CertificateValidator.cs
- Sequence.cs
- InvokeMethod.cs
- counter.cs
- XpsS0ValidatingLoader.cs
- CqlBlock.cs
- ListViewCommandEventArgs.cs
- FrameworkReadOnlyPropertyMetadata.cs
- OutputCacheProfileCollection.cs
- ACE.cs
- EditorPart.cs
- ContentOperations.cs