Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Custom treeview control Nodes(collection) property
 

Custom treeview control Nodes(collection) property

Hello All,

I am creating windowstreeview custom control. Its working fine at runtime. I can add dynamic treenodes in treeview nodes property. At design time I created form, to add treenodes.

In that form I can create treenodes without error. But as soon as I assign my object arrayto

base.Items = objArray ;

it hang up application and I have to close visual studio.
After a tracking a lot I found that if I remove following line

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

fromNodes propertyit will work fine once.
But As soon as I go back on Treenode Editor and click “OK�button it will again hang up.

I need DesignerSerializationVisibility to add nodes at treeview at design time.

I am calling treenode editor like this :-

public
static object EditValue(ComponentDesigner designer, object objectToChange, string propName)
{
try
{
PropertyDescriptor prop = TypeDescriptor.GetProperties(objectToChange)[propName];
aTreeViewEditorServiceContext context = new aTreeViewEditorServiceContext(designer, prop);
UITypeEditor editor = prop.GetEditor(typeof(UITypeEditor)) as UITypeEditor;
object obj1 = prop.GetValue(objectToChange);

object
obj2 = editor.EditValue(context, context, obj1); //Error occurs at second time.

if
(obj2 != obj1)
{
try
{
prop.SetValue(objectToChange, obj2);
}
catch (CheckoutException)
{
}
}
return obj2;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
return null;
}

I am not getting where I am mistaking, so please help.

Anurag_live  Thursday, January 08, 2009 11:00 PM

Hi Anurag,

Based on my understanding, you implement a UITypeEditor for the Nodes property of TreeView and you add tree nodes to the TreeView at design time but encounter an error. If I'm off base, please feel free to let me know.

The TreeNodeCollection type has an internal UITypeEditor called TreeNodeCollectionEditor, however, this UI editor class is not exposed to developers which means we cannot derive from the TreeNodeCollectionEditor class. So if we want to create a custom UI type editor for the type of TreeNodeCollection, we have to implement the UI editor from scratch.

If the problem is not still solved, could you please send me a sample project to look into? My email address is v-lliu@microsoft.com.

I look forward to your reply!

Sincerely,
Linda Liu

Linda Liu  Friday, January 16, 2009 3:25 AM
Hello,

For the same reason i created new classwith the name of aTreeViewEditorServiceContext,
which inherit allthree basic interface of UITypeEditor, where i am implemented
public static object EditValue(.....) { ..} method.

internalclassaTreeViewEditorServiceContext:IWindowsFormsEditorService,
ITypeDescriptorContext,IServiceProvider
{
IComponentChangeService_componentChangeService;
ComponentDesigner_designer;
PropertyDescriptor_targetProperty;
internalaTreeViewEditorServiceContext(ComponentDesignerdesigner)
{
this._designer=designer;
}
internalaTreeViewEditorServiceContext(ComponentDesignerdesigner,PropertyDescriptorprop)
{
this._designer=designer;
this._targetProperty=prop;
if(prop==null)
{
prop=TypeDescriptor.GetDefaultProperty(designer.Component);
if((prop!=null)&&typeof(ICollection).IsAssignableFrom(prop.PropertyType))
{
this._targetProperty=prop;
}
}
}
internalaTreeViewEditorServiceContext(ComponentDesignerdesigner,PropertyDescriptorprop,stringverbText)
:this(designer,prop)
{
this._designer.Verbs.Add(newDesignerVerb(verbText,newEventHandler(this.OnEditItems)));
}
publicstaticobjectEditValue(ComponentDesignerdesigner,objectobjectToChange,stringpropName)
{
try
{
PropertyDescriptorprop=TypeDescriptor.GetProperties(objectToChange)[propName];
aTreeViewEditorServiceContextcontext=
newaTreeViewEditorServiceContext(designer,prop);
UITypeEditoreditor=prop.GetEditor(typeof(UITypeEditor))asUITypeEditor;
objectobj1=prop.GetValue(objectToChange);

objectobj2=editor.EditValue(context,context,obj1);//Error occurs here.
//MessageBox.Show(((aTreeNodeCollection)obj2)[0].Text.ToString());
if(obj2!=obj1)
{
try
{
prop.SetValue(objectToChange,obj2);
}
catch(CheckoutException)
{
}
}
returnobj2;
}
catch(Exceptionex)
{
MessageBox.Show(ex.Message);
}
returnnull;
}
privatevoidOnEditItems(objectsender,EventArgse)
{
try
{
objectcomponent=this._targetProperty.GetValue(this._designer.Component);
if(component!=null)
{
CollectionEditoreditor=TypeDescriptor.GetEditor(component,typeof(UITypeEditor))asCollectionEditor;
if(editor!=null)
{
editor.EditValue(this,this,component);
}
}
}
catch(Exceptionex)
{
MessageBox.Show(ex.Message);
}
}
privateIComponentChangeServiceChangeService
{
get
{
if(this._componentChangeService==null)
{
this._componentChangeService=
(IComponentChangeService)((IServiceProvider)this).GetService(typeof(IComponentChangeService));
}
return_componentChangeService;
}
}
#regionIWindowsFormsEditorService
voidIWindowsFormsEditorService.CloseDropDown()
{
}
voidIWindowsFormsEditorService.DropDownControl(Controlcontrol)
{
}
DialogResultIWindowsFormsEditorService.ShowDialog(Formdialog)
{
IUIServiceservice=(IUIService)((IServiceProvider)this).GetService(typeof(IUIService));
if(service!=null)
{
returnservice.ShowDialog(dialog);
}
returndialog.ShowDialog(this._designer.ComponentasIWin32Window);
}
#endregion
#regionITypeDescriptorContext
objectIServiceProvider.GetService(TypeserviceType)
{
if((serviceType==typeof(ITypeDescriptorContext))||(serviceType==typeof(IWindowsFormsEditorService)))
{
returnthis;
}
if(this._designer.Component.Site!=null)
{
returnthis._designer.Component.Site.GetService(serviceType);
}
returnnull;
}
boolITypeDescriptorContext.OnComponentChanging()
{
try
{
this.ChangeService.OnComponentChanging(this._designer.Component,this._targetProperty);
}
catch(CheckoutExceptionexception)
{
if(exception!=CheckoutException.Canceled)
{
throw;
}
returnfalse;
}
returntrue;
}
voidITypeDescriptorContext.OnComponentChanged()
{
this.ChangeService.OnComponentChanged(this._designer.Component,this._targetProperty,null,null);
}
IContainerITypeDescriptorContext.Container
{
get
{
if(this._designer.Component.Site!=null)
{
returnthis._designer.Component.Site.Container;
}
returnnull;
}
}
objectITypeDescriptorContext.Instance
{
get
{
returnthis._designer.Component;
}
}
PropertyDescriptorITypeDescriptorContext.PropertyDescriptor
{
get
{
returnthis._targetProperty;
}
}
#endregion
}

And create another classaTreeNodeCollectionEditor, which inherited from CollectionEditor. In that class, i designed mycollectionpage for Nodes property which overrides default one.

voidbOk_Click(objectsender,EventArgse)
{
try
{
//ForTestingOnly.
object[]obj=newobject[2];
obj[0]=newaTreeNode("check");
obj[1]=newaTreeNode("checking");
base.Items=obj;//Error occurs here.
this.Close();
}
catch(Exceptionex)
{
MessageBox.Show(ex.Message);
}
}

thanks.
Anurag_live  Tuesday, January 20, 2009 12:37 AM

You can use google to search for other answers

Custom Search

More Threads

• TypeConverter
• PropertyDescriptor, IsBrowsable and the PropertyGrid
• Inherits ListBox and Databinding
• Split Container
• Component not remembering property input
• Tab and menustrip controls
• How to Drag and Drop Custom CONTROLS in Design-Time
• MDI Child Form Problem
• MDI StartPostion.
• Lost Event Enter -> Tab When I am using AutoCompleteSource !