I created a sample UserControl that exposes a Collection
Serialization works in this sample, the single problem I found is that I
want to have an edit updated with number of items in the collection. For
that I had to call Control.Refresh() when CollectionEditor.SetItems() is
called. Can you please use this sample and tell if it is close to what you
need?
Tip1: I have to restart VStudio 2005 quite often (almost each time I modify
control)
Tip 2: I use dbmon or DbgView (from www.sysinternals.com) to see the output
of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
Here follows the source code
TestUserControl.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Drawing.Design;
using System.ComponentModel.Design;
namespace TestCollectionProperty
{
public class TestData
{
int intValue;
String strValue = string.Empty;
public int IntValue
{
get { return intValue; }
set { intValue = value; }
}
public String StrValue
{
get { return strValue; }
set { strValue = value; }
}
}
public class ValuesEditor : CollectionEditor
{
public ValuesEditor()
: base(typeof(List<TestData>))
{ }
protected override object SetItems(object editValue, object[] value)
{
System.Diagnostics.Trace.WriteLine("SetItems1");
System.Diagnostics.Trace.WriteLine("SetItems2: " + editValue);
object retValue = base.SetItems(editValue, value);
Control control = this.Context.Instance as Control;
System.Diagnostics.Trace.WriteLine("SetItems3: " + control);
if (control != null)
{
control.Refresh();
}
return retValue;
}
}
public partial class TestUserControl : UserControl
{
private List<TestData> values = new List<TestData>();
public TestUserControl()
{
InitializeComponent();
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[RefreshProperties(RefreshProperties.All)]
[Editor(typeof(ValuesEditor), typeof(UITypeEditor))]
public List<TestData> Values
{
get { return values; }
}
protected override void OnPaint(PaintEventArgs e)
{
this.textBox.Text = values.Count.ToString();
base.OnPaint(e);
}
}
}
TestUserCode.Design.cs
namespace TestCollectionProperty
{
partial class TestUserControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed;
otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox
//
this.textBox.Location = new System.Drawing.Point(24, 50);
this.textBox.Name = "textBox";
this.textBox.Size = new System.Drawing.Size(100, 20);
this.textBox.TabIndex = 0;
//
// TestUserControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.textBox);
this.Name = "TestUserControl";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox;
}
}
> [
> Description("Items Collection"),
[quoted text clipped - 37 lines]
>>>>
>>>>FooCollection FooProperties
Bele din Carpati - 19 Dec 2005 23:28 GMT
For a short period of time the project can be downloaded from:
http://www.geocities.com/balcanuc/TestCollectionProperty.zip
>I created a sample UserControl that exposes a Collection
> Serialization works in this sample, the single problem I found is that I
[quoted text clipped - 290 lines]
>>>>>
>>>>>FooCollection FooProperties
alex sparsky - 20 Dec 2005 02:06 GMT
Hey, I really apprecaite you sending me the example project. I took a
look at it and there is one major thing your doing differently from
me. I'm implementing my own collection editor so I'm deriving from
UITypeEditor instead of CollectionEditor. So basically the routines
that I have to pick from are EditValue().
The crux of my problem seems to be somewhere in the fact that since
there is no Set accessor in the Items collection property then it
doesn't seem to matter what I return from the EditValue override in
the UITypeEditor.
So like I said, it sets the collection correctly, it puts the items
into it (well, it does because I put them in manually from the
editvalue in the uitypeeditor). The problem is that it's not setting
the dirty bit or whatever it is to make the form believe that the
collection changed. So you have to resize the control or something to
make it want to reserialize the collection. Once you do that though
the collection is set and serializes fine.
>I created a sample UserControl that exposes a Collection
>Serialization works in this sample, the single problem I found is that I
[quoted text clipped - 6 lines]
>Tip 2: I use dbmon or DbgView (from www.sysinternals.com) to see the output
>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
Bele din Carpati - 20 Dec 2005 06:53 GMT
I get it. I guess that you have to notify the designer about change using
the IComponentChange service
I used reflector to check how the CollectionEditor does this and seems that
you have to add one more line to your EditValue override:
this.Context.OnComponentChanged();
Cristi
> Hey, I really apprecaite you sending me the example project. I took a
> look at it and there is one major thing your doing differently from
[quoted text clipped - 27 lines]
>>output
>>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
alex sparsky - 20 Dec 2005 16:33 GMT
woohooo! That was the magic call I was looking for. I didn't see
that method in intellisense or the docs when I went looking for it. I
wonder why that wasn't there! Nice job, I really appreciate it. This
works perfectly now.
>I get it. I guess that you have to notify the designer about change using
>the IComponentChange service
[quoted text clipped - 35 lines]
>>>output
>>>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
Bele din Carpati - 20 Dec 2005 19:51 GMT
I'm happy to hear that my advices helped you.
Here another tip: use reflector to see how the CollectionEditor creates a
transaction for property change. This helps designer to mark undo/redo
changes as only one step. ;) (I guess).
key lines related to transaction:
IDesignerHost host1 = (IDesignerHost)
this.GetService(typeof(IDesignerHost));
DesignerTransaction transaction1 = null;
.....
transaction1 =
host1.CreateTransaction(System.Design.SR.GetString("CollectionEditorUndoBatchDesc",
objArray1));
.....
transaction1.Commit();
- Cristi
> woohooo! That was the magic call I was looking for. I didn't see
> that method in intellisense or the docs when I went looking for it. I
[quoted text clipped - 42 lines]
>>>>output
>>>>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
alex sparsky - 20 Dec 2005 21:33 GMT
Great advice, I will do that.
thanks again
>I'm happy to hear that my advices helped you.
>Here another tip: use reflector to see how the CollectionEditor creates a
[quoted text clipped - 64 lines]
>>>>>output
>>>>>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer
Adrian Maull - 21 Dec 2005 14:14 GMT
It's probably a mute point now since you guys nicely worked out this issue.
The following topics touch on the topic at hand:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlr
fsystemcomponentmodelitypedescriptorcontextclasstopic.asp
http://msdn2.microsoft.com/en-us/library/system.componentmodel.itypedescriptorco
ntext_members.aspx
http://msdn2.microsoft.com/en-us/library/system.componentmodel.propertydescripto
r.setvalue.aspx
> woohooo! That was the magic call I was looking for. I didn't see
> that method in intellisense or the docs when I went looking for it. I
[quoted text clipped - 42 lines]
>>>>output
>>>>of System.Diagonostics.Trace.WriteLine even if is in VStudio Designer