|
|
56.1 When a property gets modified, how do you refresh other properties of a Component/Control in the property browser?
|
 |
Set this attribute for the property: |
RefreshProperties(RefreshProperties.Repaint)
|
56.2 How to Reinitialize extender provider dependencies (the logic within CanExtend) from within the designer?
|
 |
Set the Browsable attribute on the new property that hides the existing one. Here is a code snippet that hides the WordWrap property in the derived TextBox.
|
public class MyTextBox : TextBox
|
get{ return false;} //always false
|
Public Shadows Property WordWrap() As Boolean
|
Return False 'always false
|
56.3 How do you detect the designer host getting loaded for the first time in your designer?
|
 |
Subscribe to IDesignerHost.LoadComplete event. Make any changes to the designerhost (like adding/deleting component, etc.) only after this event, or else the design document will not be made "dirty".
(IdesignerSerializationManager.SerializationComplete will tell you when Code is deserialized into design time components). |
56.4 How do you provide "dynamic" default values?
|
 |
Provide ShouldSerialize#PropertyName# and Reset#PropertyName# along with your property.
Example:
|
private bool ShouldSerializeFont()
|
/// Resets the property to its default value.
|
56.5 How to debug your design time code (like designers, typeconverters, etc.)?
|
 |
You need to use a second instance of VS.NET to debug the one that's running
the code.
Put your control on a from in VS.NET
Start a 2nd Vs.Net
Choose the Debug menu >> Processes ...
Double click "devenv.exe" and choose "Common Language Runtime" as the types
of debugging
Open your code file, set your breakpoint, and you're debugging.
Posted by Shawn Burke of MSFT in microsoft.public.dotnet.framework.windowsforms.
|
56.6 How do you make your custom data types property browser browsable when contained in a Control/Component (as a property)?
|
 |
public int Width{get{...}set{...}}
|
public int Height{get{...}set{...}}
|
public class MySizeConverter:
|
ExpandableObjectConverter
|
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
|
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
|
MySize size = new MySize();
|
size.Width = (int)propertyValues[(object)"Width"];
|
size.Height = (int)propertyValues[(object)"Height"];
|
56.7 How to make properties in your custom data type appear in a particular order in the property browser?
|
 |
For example, in the above class (MySize) if you want to your properties "Width" and "Height" to
appear in that order, you should provide this override:
|
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
|
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
|
System.ComponentModel.PropertyDescriptorCollection propertyDescriptorCollection;
|
propertyDescriptorCollection =
|
TypeDescriptor.GetProperties(typeof(System.Drawing.Size),attributes);
|
propNames = (string[])new System.String[2];
|
propNames[1] = @"Height";
|
return propertyDescriptorCollection0.Sort(propNames);
|
} // end of method GetProperties
|
56.8 How do I provide Intellisense support to my controls while coding against them and also provide Description support for the properties in the property grid?
|
 |
You can provide Intellisense support to your type and it's members by providing xml comments in code as follows:
|
/// Summary description for Form3.
|
public class Form3 : System.Windows.Forms.Form
|
/// Clean up any resources being used.
|
protected override void Dispose( bool disposing )
|
/// Summary of my property
|
Search for the "Tags for Documentation Comments" topic in MSDN for all the available documentation tags.
Then in your project, go to the Project Properties dialog, to the Configuration Properties/Build tab and specify a file for the XML Documentation File property. This will generate a file by that name when you compile your assembly. Place this xml file beside your dll. This will provide Intellisense support for your types in that assembly.
To provide Description support for your properties in the property grid in the designer, add the DescriptionAttribute attribute to your properties in code.
|
56.9 How do I change the Zorder of my docked windows at design time?
|
 |
You can use the menu selection Format|Move To Front or Format|Send To Back to change the Zorder and update your docking. |
56.10 How can I tell my form is being used in design time and not runtime?
|
 |
Check the the property Form.DesignMode.
But, note that when in Visual Inheritance mode (designing a derived form), your Control's DesignMode property will be true when the base form's constructor gets executed in the design-time.
To workaround this, you could check if the app in which your control is running is not devenv.exe, as follows:
|
string exePath = Application.ExecutablePath;
|
exePath = exePath.ToLower();
|
if(Application.ExecutablePath.ToLower().IndexOf("devenv.exe") > -1)
|
// Then you are running in vs.net.
|
56.11 How can I persist a collection of items into code?
|
 |
The CollectionEditor allows adding and removing items from a collection at design time. If the items in this collection implement IComponent or if they are derived from Component, the items in your collection can be persisted in code.
Download collectioneditorsample.zip for a complete sample project.
Here are some steps you should follow:
1) Make sure your item is derived from Component or implements Icomponent.
For example:
|
public class SomeItem : Component
|
private string label = "";
|
public SomeItem(string label)
|
public override string ToString()
|
return String.Format("SomeItem: ( Label = '{0}' )", label);
|
2) Next implement your Collection. You have to implement the Ilist interface. The CollectionEditor will determine the type of instances to be added to your collection using reflection inspecting the return type of the Item property (Indexer).
|
Description("The set of properties to be edited with CollectionEditor."),
|
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
|
Editor(typeof(System.ComponentModel.Design.CollectionEditor),
|
typeof(System.Drawing.Design.UITypeEditor))
|
public SomeItemCollection SomeItems
|
if (someItemCollection == null)
|
someItemCollection = CreateItemCollection();
|
return someItemCollection;
|
protected SomeItemCollection CreateItemCollection()
|
return new SomeItemCollection(this);
|
public class SomeItemCollection : IList
|
private SomeItemDisplayer owner;
|
public event EventHandler Changed;
|
public SomeItemCollection(SomeItemDisplayer owner)
|
internal ArrayList InnerArray
|
if (this.Changed != null)
|
this.Changed(this, EventArgs.Empty);
|
/// The CollectionEditor will determine the type of objects to be created by
|
/// looking at the property type of the following method. CollectionEditor
|
/// internally uses reflection to get the PropertyInfo for the "Item" property.
|
/// This method must be public.
|
public SomeItem this[int index]
|
throw new ArgumentNullException("value");
|
if (index < 0 || index >= this.InnerArray.Count)
|
throw new ArgumentOutOfRangeException(String.Format("Invalid Argument {0}: {1}", "index", index.ToString()));
|
this.InnerArray[index] = value;
|
if (index < 0 || index >= this.InnerArray.Count)
|
throw new ArgumentOutOfRangeException("Invalid Argument {0}: {1}", "index", index.ToString());
|
return (SomeItem) this.InnerArray[index];
|
public void AddRange(object[] items)
|
InnerArray.AddRange(items);
|
/// This implementation for the Item property for the IList interface. It's
|
/// property type is object.
|
object IList.this[int index]
|
// forward call to public indexer
|
this[index] = (SomeItem) value;
|
// forward call to public indexer
|
public /*IEnumerable*/ IEnumerator GetEnumerator()
|
return InnerArray.GetEnumerator();
|
public /*ICollection*/ int Count
|
public /*IList*/ void RemoveAt(int index)
|
if (index < 0 || index >= this.InnerArray.Count)
|
throw new ArgumentOutOfRangeException(String.Format("Invalid Argument {0}: {1}", "index", index.ToString()));
|
this.InnerArray.RemoveAt(index);
|
public /*IList*/ void Remove(object value)
|
int n = this.InnerArray.IndexOf(value,0);
|
public /*IList*/ void Insert(int index, object item)
|
throw new ArgumentNullException("item");
|
if (index < 0 || index > this.InnerArray.Count)
|
throw new ArgumentOutOfRangeException(String.Format("Invalid Argument {0}: {1}","index", index.ToString()));
|
this.InnerArray.Insert(index,item);
|
public /*IList*/ int IndexOf(object value)
|
throw new ArgumentNullException(String.Format("Invalid Argument {0}: {1}","value", "null"));
|
return this.InnerArray.IndexOf(value,0);
|
public /*IList*/ bool IsReadOnly
|
public /*IList*/ void Clear()
|
public /*IList*/ bool Contains(object value)
|
return this.IndexOf(value) != -1;
|
void System.Collections.ICollection.CopyTo(Array dest, int index)
|
int count = this.InnerArray.Count;
|
for (int n1 = 0; n1 < count; n1++)
|
dest.SetValue(this.InnerArray[n1], (n1 + index));
|
int System.Collections.IList.Add(object item)
|
int n = this.InnerArray.Add(item);
|
bool System.Collections.IList.IsFixedSize
|
bool System.Collections.ICollection.IsSynchronized
|
object System.Collections.ICollection.SyncRoot
|
3) Reference this collection in your control or component that should be designable. You need to supply a DesignerSerializationVisibility and an Editor attribute:
|
private SomeItemCollection someItemCollection = null;
|
ArrayList someItems = new ArrayList();
|
Description("The set of properties to be edited with CollectionEditor."),
|
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
|
Editor(typeof(System.ComponentModel.Design.CollectionEditor),
|
typeof(System.Drawing.Design.UITypeEditor))
|
public SomeItemCollection SomeItems
|
if (someItemCollection == null)
|
someItemCollection = CreateItemCollection();
|
return someItemCollection;
|
protected SomeItemCollection CreateItemCollection()
|
return new SomeItemCollection(this);
|
56.12 How can I supply a list of values to be chosen from a dropdown list at runtime for a specific type similar to enums?
|
 |
You have to implement a TypeConverter for your class and override the GetStandardValues and GetStandardValuesSupported method. In your override of GetStandardValuesSupported you have to return true. In your override of GetStandardValues you should return the list of values.
Optionally you can override GetStandardValuesExclusive and allow the user to specify values that are not in the value list.
Note: The standard values collection can be initialized at runtime depending on the context of the instance object.
|
public class GridCellValueTypeConverter: TypeConverter
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
if (sourceType == typeof(System.String))
|
return base.CanConvertFrom(context,sourceType);
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
if (value is System.String)
|
if (((string) value) != "")
|
return Type.GetType((string) value);
|
return base.ConvertFrom(context,culture,value);
|
| |