Das ist richtig. Hier ist der Code eine Klasse, eine Collection, UserControl und TypeConverter in C#. Habe ich gerade ausgegraben.
using System;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
namespace VTControl
{
/// <summary>
/// Summary description for VTProperty.
/// </summary>
//[TypeConverter(typeof(ExpandableObjectConverter))]
[TypeConverter(typeof(VTPropertyTypeConverter))]
public struct VTProperty
{
private int _f1;
private int _f2;
public VTProperty(int f1, int f2)
{
_f1 = f1;
_f2 = f2;
}
//[RefreshProperties(RefreshProperties.Repaint)]
[DefaultValue(0)]
public int f1
{
get{return _f1;}
set {_f1 = value;}
}
//[RefreshProperties(RefreshProperties.Repaint)]
[DefaultValue(0)]
public int f2
{
get{return _f2;}
set {_f2 = value;}
}
public override string ToString()
{
return _f1.ToString()+", "+_f2.ToString();
}
public static VTProperty Parse(string sval)
{
string[] svals = sval.Split(',');
//MessageBox.Show("svals1: "+svals[0]+" / "+svals[1]);
if (svals.Length!=2)
throw new NotSupportedException("Invalid format");
try
{
//MessageBox.Show("svals2: "+svals[0]+" / "+svals[1]);
int f1 = int.Parse(svals[0].Trim());
int f2 = int.Parse(svals[1].Trim());
return new VTProperty(f1, f2);
}
catch
{
throw new NotSupportedException("Invalid format");
}
}
}
} using System;
using System.Collections;
using System.Diagnostics;
using CCommon;
namespace VTControl
{
/// <summary>
/// Collection of VTProperty items
/// </summary>
public class VTPropertyCollection : BaseCollection
{
public int Add(VTProperty item)
{
return base.List.Add(item as object);
}
public void AddRange(VTProperty[] VTPropertys)
{
base.AddRange(VTPropertys);
}
public void InsertRange(int index, VTProperty[] VTPropertys)
{
base.InsertRange(index, VTPropertys);
}
public int IndexOf(VTProperty item)
{
OnValidate(item);
return base.List.IndexOf(item);
}
public void Remove(VTProperty item)
{
base.List.Remove(item as object);
}
public void Insert(int index, VTProperty item)
{
base.List.Insert(index, item as object);
}
public bool Contains(VTProperty item)
{
OnValidate(item);
return base.List.Contains(item as object);
}
public VTProperty this[int index]
{
get {return (VTProperty)base.List[index];}
set {base.List[index] = value;}
}
protected override void OnValidate(object item)
{
if (!(item is VTProperty))
throw new ArgumentException("Item must be of type VTProperty", "item");
base.OnValidate(item);
}
}
} sing System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
namespace VTControl
{
/// <summary>
/// Summary description for VTPropertyControl.
/// </summary>
public class VTPropertyControl : System.Windows.Forms.UserControl
{
private System.Windows.Forms.Label lblField1;
private System.Windows.Forms.Label lblField2;
private System.Windows.Forms.ImageList imageList1;
private System.ComponentModel.IContainer components;
public VTPropertyControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
private VTPropertyCollection _vtproperties = new VTPropertyCollection();
private VTProperty _vtproperty;
[Category("Appearance"),
Description("Collection of VTProperties"),
Browsable(true),
EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public VTPropertyCollection vtpcoll
{
get{return _vtproperties;}
set
{
_vtproperties = value;
}
}
[Category("Appearance"),
Description("Values of the two labels"),
Browsable(true),
EditorBrowsable(EditorBrowsableState.Always)]
//DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public VTProperty vtp
{
get{return _vtproperty;}
set
{
_vtproperty = value;
lblField1.Text = value.f1.ToString();
lblField2.Text = value.f2.ToString();
this.Refresh();
}
}
// Prevent serialization of property vtp
// Documentation for this special designer function
// Of course, not much point putting
// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
// on the property above...
// private bool ShouldSerializevtp()
// {
// return false;
// }
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( 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.components = new System.ComponentModel.Container();
this.lblField1 = new System.Windows.Forms.Label();
this.lblField2 = new System.Windows.Forms.Label();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.SuspendLayout();
//
// lblField1
//
this.lblField1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblField1.Location = new System.Drawing.Point(24, 24);
this.lblField1.Name = "lblField1";
this.lblField1.Size = new System.Drawing.Size(96, 32);
this.lblField1.TabIndex = 0;
this.lblField1.Text = "0";
//
// lblField2
//
this.lblField2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblField2.Location = new System.Drawing.Point(24, 72);
this.lblField2.Name = "lblField2";
this.lblField2.Size = new System.Drawing.Size(96, 32);
this.lblField2.TabIndex = 1;
this.lblField2.Text = "0";
//
// imageList1
//
this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
//
// VTPropertyControl
//
this.Controls.Add(this.lblField2);
this.Controls.Add(this.lblField1);
this.Name = "VTPropertyControl";
this.ResumeLayout(false);
}
#endregion
}
} using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
namespace VTControl
{
/// <summary>
/// Summary description for VTPropertyTypeConverter.
/// </summary>
public class VTPropertyTypeConverter : ExpandableObjectConverter
{
public VTPropertyTypeConverter() : base()
{
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type _
sourceType)
{
if (sourceType==typeof(string)) return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, _
System.Globalization.CultureInfo culture, object value)
{
if (value==null)
return null;
string sval = value as string;
//MessageBox.Show("sval: "+sval);
if (sval==null)
throw new NotSupportedException("Unsuported type");
return VTProperty.Parse(sval);
}
// GetCreateInstanceSupported() and CreateInstance() are not actually needed
// since PropertyGrid appears to use ConvertTo() (InstanceDescriptor) to _
create
// an object of the required type if these routines are not present.
// In fact both routines are called if present, so quite what's going on
// is a bit mysterious...
// On the other hand it's fun writing more code, so why not?
// However we get an exception when these routines are present and try to _
display
// the structure directly in a ProperttyGrid, so we leave it commented out.
// public override bool GetCreateInstanceSupported(ITypeDescriptorContext _
context)
// {
// return true;
// }
//
// public override object CreateInstance(ITypeDescriptorContext context, _
System.Collections.IDictionary propertyValues)
// {
// VTProperty vtp = new VTProperty();
// vtp.f1 = (int)propertyValues["f1"];
// vtp.f2 = (int)propertyValues["f2"];
// //MessageBox.Show("vtp 1: "+vtp.f1.ToString()+", "+vtp.f2.ToString());
// return vtp;
// }
// Convert to InstanceDescriptor
public override bool CanConvertTo(ITypeDescriptorContext context,
Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture,
object value,
Type destinationType)
{
// other TypeConverter operations go here...
//
//MessageBox.Show("value is VTProperty: "+(value is VTProperty).ToString()+"" & _
"("+value.GetType().ToString()+")");
if (destinationType == typeof(InstanceDescriptor) && value is VTProperty)
{
VTProperty vtp = (VTProperty)value;
//MessageBox.Show("vtp 2: "+vtp.f1.ToString()+", "+vtp.f2.ToString());
ConstructorInfo ctor =
typeof(VTProperty).GetConstructor(
new Type[] {typeof(int), typeof(int)});
if (ctor != null)
{
return new InstanceDescriptor(ctor,
new object[] {vtp.f1, vtp.f2});
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
} ________
Alle Angaben ohne Gewähr. Keine Haftung für Vorschläge, Tipps oder sonstige Hilfe, falls es schiefgeht, nur Zeit verschwendet oder man sonst nicht zufrieden ist |