Your class inherits from ExpandableObjectConverter. That type defines an overridable method called GetStandardValueSupported(). If you don't like what that method does then you have the option to overrride it in your code. If you do like what ExpandableObjectConverter.GetStandardValueSupported()
does then you don't need to override it, it is all up to you.
2) Then copy my codes below inside after creating a new cs (Class file):
namespace CSharp
{
[TypeConverter(typeof(MyConvertor))]
public struct DPoint
{
private double _x;
private double _y;
private double _z;
[NotifyParentProperty(true)]
public double Z
{
get { return _z; }
set { _z = value; }
}
[NotifyParentProperty(true)]
public double Y
{
get { return _y; }
set { _y = value; }
}
[NotifyParentProperty(true)]
public double X
{
get { return _x; }
set { _x = value; }
}
public DPoint(double x, double y, double z)
{
_x = x;
_y = y;
_z = z;
}
public static explicit operator DPoint(string s)
{
string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 3)
{
double d = Convert.ToDouble(values[0]);
double d2 = Convert.ToDouble(values[1]);
double d3 = Convert.ToDouble(values[2]);
return new DPoint(d, d2, d3);
}
}
}
public class MyConvertor : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return typeof(string) == sourceType.GetType();
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
return (DPoint)value.ToString();
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is DPoint)
{
DPoint dp = (DPoint)value;
return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z);
}
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType.GetType() == typeof(string);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new DPoint((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]);
}
public override bool GetStandardValueSupported()
{
return true;
}
}
[ParseChildren(true), PersistChildren(false)]
public class MyDPoint : WebControl
{
DPoint dp = new DPoint();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public DPoint DPoint
{
get
{
return dp;
}
set
{
dp = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(string.Format("[{0},{1},{2}]", DPoint.X, DPoint.Y, DPoint.Z));
}
}
}
3) Plz comment "GetStandardValueSupported" overridable method above and re-compile the whole proj, drag and drop the control from the toolbox onto your Web Form, then plz change your X,Y,Z properties from the property panel, what's happening?
At first, let we figure out what the GetStandardValuesSupported method does:
It returns whether this object supports a standard set of values that can be picked from a list, using the specified context. By default, this method returns false, if the developers want to find a common set of values of objects supports via GetStandardValues
method, the GetStandardValuesSupported ought to return "true". From this explanation, you may know what the GetStandardValuesSupported's purpose is(The second sample code show that in the below "HOW TO" article).
ToughMan
2) Then copy my codes below inside after creating a new cs (Class file):
ToughMan
public static explicit operator DPoint(string s)
{
string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 3)
{
double d = Convert.ToDouble(values[0]);
double d2 = Convert.ToDouble(values[1]);
double d3 = Convert.ToDouble(values[2]);
return new DPoint(d, d2, d3);
}
}
ToughMan
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is DPoint)
{
DPoint dp = (DPoint)value;
return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z);
}
}
The code snippets above have the same error "not all code paths return a value", and the method you want to override should be GetStandardValuesSupported not GetStandardValueSupported. So I modify them like below(It's the full sample code I test it on my machine):
Notice: this method is overloaded, the one of them without parameter can't be override as it's not a virtual,abstract and override method, another having parameter can be override as it's a virtual method .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication3
{
[TypeConverter(typeof(MyConvertor))]
public struct DPoint
{
private double _x;
private double _y;
private double _z;
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Z
{
get { return _z; }
set { _z = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Y
{
get { return _y; }
set { _y = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double X
{
get { return _x; }
set { _x = value; }
}
public DPoint(double x, double y, double z)
{
_x = x;
_y = y;
_z = z;
}
public static explicit operator DPoint(string s)
{
string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 3)
{
double d = Convert.ToDouble(values[0]);
double d2 = Convert.ToDouble(values[1]);
double d3 = Convert.ToDouble(values[2]);
return new DPoint(d, d2, d3);
}
else
{
return new DPoint(2,3,4);
}
}
}
public class MyConvertor : ExpandableObjectConverter
{
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 is string)
{
return (DPoint)value.ToString();
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is DPoint)
{
DPoint dp = (DPoint)value;
return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType.GetType() == typeof(string);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new DPoint((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]);
}
//public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
//{
// // Passes the local integer array.
// StandardValuesCollection svc =
// new StandardValuesCollection(
// return svc;
//}
//public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
//{
// return true;
//}
}
[ParseChildren(true), PersistChildren(false)]
public class MyDPoint : WebControl
{
DPoint dp = new DPoint();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public DPoint DPoint
{
get
{
return dp;
}
set
{
dp = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(string.Format("[{0},{1},{2}]", DPoint.X, DPoint.Y, DPoint.Z));
}
}
}
3) Plz comment "GetStandardValueSupported" overridable method above and re-compile the whole proj, drag and drop the control from the toolbox onto your Web Form, then plz change your X,Y,Z properties from the property panel, what's happening?
4) Plz uncomment them to see what's happening?
No matter whether I comment or uncomment the code line you mentioned, nothing changes, the propeties can be modified.
Please mark the replies as answers if they help or unmark if not.
Feedback to us
I mean——Why must I override the GetSupportedValuesSupported?
1) Have u tried to change from "struct" to "class"? If u do that, NO NEED TO OVERRIDE THAT FUNCTION AT ALL
Sorry about don't make your clear. Have you checked my reply carefully? Like this sentence:
Mamba Dai - MSFT
No matter whether I comment or uncomment the code line you mentioned, nothing changes, the propeties can be modified.
To explain why the GetSupportedValuesSupported have to be overrided. Please refer to below:
Mamba Dai - MSFT
By default, this method returns false, if the developers want to find a common set of values of objects supports via GetStandardValues method, the GetStandardValuesSupported ought to return "true"
I apologize for I didn't explicitly point out why this method should be overrided. Since this method returns false by default, and this method should be overrided to return true if the developers want to find a common set of values of objects(it's the reason
why develoers need to override this method). And I also mentioned, this method is overloaded, one can't be override, another can be(the reason I also mentioned in the above reply).
Now I modify the sample code above again and test again. Which I create two custom controls with the class and struct type(I comment out the GetStandardValuesSupported method in the both objects, namely I don't override this method).
Check the code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication3
{
[TypeConverter(typeof(MyConvertorUseStruct))]
public struct DPointUseStruct
{
private double _x;
private double _y;
private double _z;
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Z
{
get { return _z; }
set { _z = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Y
{
get { return _y; }
set { _y = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double X
{
get { return _x; }
set { _x = value; }
}
public DPointUseStruct(double x, double y, double z)
{
_x = x;
_y = y;
_z = z;
}
public static explicit operator DPointUseStruct(string s)
{
string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 3)
{
double d = Convert.ToDouble(values[0]);
double d2 = Convert.ToDouble(values[1]);
double d3 = Convert.ToDouble(values[2]);
return new DPointUseStruct(d, d2, d3);
}
else
{
return new DPointUseStruct(2, 3, 4);
}
}
}
[TypeConverter(typeof(MyConvertorUseClass))]
public class DPointUseClass
{
private double _x;
private double _y;
private double _z;
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Z
{
get { return _z; }
set { _z = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double Y
{
get { return _y; }
set { _y = value; }
}
[NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)]
public double X
{
get { return _x; }
set { _x = value; }
}
public DPointUseClass(double x, double y, double z)
{
_x = x;
_y = y;
_z = z;
}
public DPointUseClass()
{ }
public static explicit operator DPointUseClass(string s)
{
string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length == 3)
{
double d = Convert.ToDouble(values[0]);
double d2 = Convert.ToDouble(values[1]);
double d3 = Convert.ToDouble(values[2]);
return new DPointUseClass(d, d2, d3);
}
else
{
return new DPointUseClass(2, 3, 4);
}
}
}
public class MyConvertorUseStruct : ExpandableObjectConverter
{
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 is string)
{
return (DPointUseStruct)value.ToString();
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is DPointUseStruct)
{
DPointUseStruct dp = (DPointUseStruct)value;
return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType.GetType() == typeof(string);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new DPointUseStruct((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]);
}
//public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
//{
// // Passes the local integer array.
// StandardValuesCollection svc =
// new StandardValuesCollection(
// return svc;
//}
//public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
//{
// return true;
//}
}
public class MyConvertorUseClass : ExpandableObjectConverter
{
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 is string)
{
return (DPointUseClass)value.ToString();
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (value is DPointUseClass)
{
DPointUseClass dp = (DPointUseClass)value;
return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z);
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType.GetType() == typeof(string);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new DPointUseClass((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]);
}
//public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
//{
// // Passes the local integer array.
// StandardValuesCollection svc =
// new StandardValuesCollection(
// return svc;
//}
//public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
//{
// return true;
//}
}
[ParseChildren(true), PersistChildren(false)]
public class MyDPointUseStruct : WebControl
{
DPointUseStruct dp = new DPointUseStruct();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public DPointUseStruct DPoint
{
get
{
return dp;
}
set
{
dp = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(string.Format("[{0},{1},{2}],use struct", DPoint.X, DPoint.Y, DPoint.Z));
}
}
public class MyDPointUseClass : WebControl
{
DPointUseClass dp = new DPointUseClass();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[NotifyParentProperty(true)]
public DPointUseClass DPoint
{
get
{
return dp;
}
set
{
dp = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write(string.Format("[{0},{1},{2}],use class", DPoint.X, DPoint.Y, DPoint.Z));
}
}
}
Please mark the replies as answers if they help or unmark if not.
Feedback to us
I just copy your code and test it on my machine, when it runs, there are some error occurs(I mentioned them at my first reply)
ToughMan
Why must I add this underlined, bold overridable method for a struct, but not for a class?
Based on my testing, it doesn't have to override this method for a struct(I didn't said "doestn't have to" explicitly at the beginning), check my reply above or the quote below:
Mamba Dai - MSFT
No matter whether I comment or uncomment the code line you mentioned, nothing changes, the propeties can be modified.
And the testing code please refer to my second reply, it includes struct and class.
Now could you just create a new project and copy my testing code to run? Or send you project to me, I will test it on my machine.
You can remove any confidential information and business logic.
Hope it helps. Any question please feel free to comment. I will go ahead.
Please mark the replies as answers if they help or unmark if not.
Feedback to us
ToughMan
Participant
1490 Points
635 Posts
Why struct doesn't work properly?
Nov 22, 2012 07:48 AM|LINK
Hello everyone,
I did a Customized control and everything goes well with me. My question is very simple, plz look at the bold statement:
Why must I add this underlined, bold overridable method for a struct, but not for a class?
Paul Linton
Star
13405 Points
2532 Posts
Re: Why struct doesn't work properly?
Nov 22, 2012 08:46 PM|LINK
Nothing to do with struct vs class.
Your class inherits from ExpandableObjectConverter. That type defines an overridable method called GetStandardValueSupported(). If you don't like what that method does then you have the option to overrride it in your code. If you do like what ExpandableObjectConverter.GetStandardValueSupported() does then you don't need to override it, it is all up to you.
ToughMan
Participant
1490 Points
635 Posts
Re: Why struct doesn't work properly?
Nov 23, 2012 03:03 AM|LINK
Hello,
What I mean is:
I must override that, because if I don't do that for struct type, it will NOT allow me to change the value directly in the property panel.
But for class type, it goes well, no matter struct or class.
Why?
Paul Linton
Star
13405 Points
2532 Posts
Re: Why struct doesn't work properly?
Nov 23, 2012 03:07 AM|LINK
I'm sorry, I can't help you. I have no idea what you are talking about.
"I must" "I don't" "NOT allow" property panel. All the negatives confused me and I don't know what property panel you are talking about.
"for class type ... no matter struct or class" huh? "It goes well" what goes well?
Perhpas someone else knows what you are talking about.
ToughMan
Participant
1490 Points
635 Posts
Re: Why struct doesn't work properly?
Nov 23, 2012 03:30 AM|LINK
Well, everyone here u can produce my issue:
1) First create a WebApp.
2) Then copy my codes below inside after creating a new cs (Class file):
namespace CSharp { [TypeConverter(typeof(MyConvertor))] public struct DPoint { private double _x; private double _y; private double _z; [NotifyParentProperty(true)] public double Z { get { return _z; } set { _z = value; } } [NotifyParentProperty(true)] public double Y { get { return _y; } set { _y = value; } } [NotifyParentProperty(true)] public double X { get { return _x; } set { _x = value; } } public DPoint(double x, double y, double z) { _x = x; _y = y; _z = z; } public static explicit operator DPoint(string s) { string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 3) { double d = Convert.ToDouble(values[0]); double d2 = Convert.ToDouble(values[1]); double d3 = Convert.ToDouble(values[2]); return new DPoint(d, d2, d3); } } } public class MyConvertor : ExpandableObjectConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return typeof(string) == sourceType.GetType(); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { return (DPoint)value.ToString(); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is DPoint) { DPoint dp = (DPoint)value; return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z); } } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType.GetType() == typeof(string); } public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { return new DPoint((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]); } public override bool GetStandardValueSupported() { return true; } } [ParseChildren(true), PersistChildren(false)] public class MyDPoint : WebControl { DPoint dp = new DPoint(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [PersistenceMode(PersistenceMode.InnerProperty)] [NotifyParentProperty(true)] public DPoint DPoint { get { return dp; } set { dp = value; } } protected override void Render(HtmlTextWriter writer) { writer.Write(string.Format("[{0},{1},{2}]", DPoint.X, DPoint.Y, DPoint.Z)); } } }3) Plz comment "GetStandardValueSupported" overridable method above and re-compile the whole proj, drag and drop the control from the toolbox onto your Web Form, then plz change your X,Y,Z properties from the property panel, what's happening?
4) Plz uncomment them to see what's happening?
Mamba Dai - ...
All-Star
23531 Points
2683 Posts
Microsoft
Re: Why struct doesn't work properly?
Dec 03, 2012 08:03 AM|LINK
Hi,
At first, let we figure out what the GetStandardValuesSupported method does:
It returns whether this object supports a standard set of values that can be picked from a list, using the specified context. By default, this method returns false, if the developers want to find a common set of values of objects supports via GetStandardValues method, the GetStandardValuesSupported ought to return "true". From this explanation, you may know what the GetStandardValuesSupported's purpose is(The second sample code show that in the below "HOW TO" article).
The code snippets above have the same error "not all code paths return a value", and the method you want to override should be GetStandardValuesSupported not GetStandardValueSupported. So I modify them like below(It's the full sample code I test it on my machine):
Notice: this method is overloaded, the one of them without parameter can't be override as it's not a virtual,abstract and override method, another having parameter can be override as it's a virtual method .
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication3 { [TypeConverter(typeof(MyConvertor))] public struct DPoint { private double _x; private double _y; private double _z; [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Z { get { return _z; } set { _z = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Y { get { return _y; } set { _y = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double X { get { return _x; } set { _x = value; } } public DPoint(double x, double y, double z) { _x = x; _y = y; _z = z; } public static explicit operator DPoint(string s) { string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 3) { double d = Convert.ToDouble(values[0]); double d2 = Convert.ToDouble(values[1]); double d3 = Convert.ToDouble(values[2]); return new DPoint(d, d2, d3); } else { return new DPoint(2,3,4); } } } public class MyConvertor : ExpandableObjectConverter { 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 is string) { return (DPoint)value.ToString(); } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is DPoint) { DPoint dp = (DPoint)value; return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z); } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType.GetType() == typeof(string); } public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { return new DPoint((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]); } //public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) //{ // // Passes the local integer array. // StandardValuesCollection svc = // new StandardValuesCollection( // return svc; //} //public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) //{ // return true; //} } [ParseChildren(true), PersistChildren(false)] public class MyDPoint : WebControl { DPoint dp = new DPoint(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [PersistenceMode(PersistenceMode.InnerProperty)] [NotifyParentProperty(true)] public DPoint DPoint { get { return dp; } set { dp = value; } } protected override void Render(HtmlTextWriter writer) { writer.Write(string.Format("[{0},{1},{2}]", DPoint.X, DPoint.Y, DPoint.Z)); } } }3) Plz comment "GetStandardValueSupported" overridable method above and re-compile the whole proj, drag and drop the control from the toolbox onto your Web Form, then plz change your X,Y,Z properties from the property panel, what's happening?
4) Plz uncomment them to see what's happening?
No matter whether I comment or uncomment the code line you mentioned, nothing changes, the propeties can be modified.
Feedback to us
Develop and promote your apps in Windows Store
ToughMan
Participant
1490 Points
635 Posts
Re: Why struct doesn't work properly?
Dec 04, 2012 04:43 AM|LINK
First many thanks!
But you've avoided my CORE question——
I mean——Why must I override the GetSupportedValuesSupported?
1) Have u tried to change from "struct" to "class"? If u do that, NO NEED TO OVERRIDE THAT FUNCTION AT ALL.
2) Why, plz explain to me in details.
Reguards anyway!
Mamba Dai - ...
All-Star
23531 Points
2683 Posts
Microsoft
Re: Why struct doesn't work properly?
Dec 04, 2012 05:18 AM|LINK
Hi,
Sorry about don't make your clear. Have you checked my reply carefully? Like this sentence:
To explain why the GetSupportedValuesSupported have to be overrided. Please refer to below:
I apologize for I didn't explicitly point out why this method should be overrided. Since this method returns false by default, and this method should be overrided to return true if the developers want to find a common set of values of objects(it's the reason why develoers need to override this method). And I also mentioned, this method is overloaded, one can't be override, another can be(the reason I also mentioned in the above reply).
Now I modify the sample code above again and test again. Which I create two custom controls with the class and struct type(I comment out the GetStandardValuesSupported method in the both objects, namely I don't override this method).
Check the code below:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication3 { [TypeConverter(typeof(MyConvertorUseStruct))] public struct DPointUseStruct { private double _x; private double _y; private double _z; [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Z { get { return _z; } set { _z = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Y { get { return _y; } set { _y = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double X { get { return _x; } set { _x = value; } } public DPointUseStruct(double x, double y, double z) { _x = x; _y = y; _z = z; } public static explicit operator DPointUseStruct(string s) { string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 3) { double d = Convert.ToDouble(values[0]); double d2 = Convert.ToDouble(values[1]); double d3 = Convert.ToDouble(values[2]); return new DPointUseStruct(d, d2, d3); } else { return new DPointUseStruct(2, 3, 4); } } } [TypeConverter(typeof(MyConvertorUseClass))] public class DPointUseClass { private double _x; private double _y; private double _z; [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Z { get { return _z; } set { _z = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double Y { get { return _y; } set { _y = value; } } [NotifyParentProperty(true), RefreshProperties(RefreshProperties.Repaint)] public double X { get { return _x; } set { _x = value; } } public DPointUseClass(double x, double y, double z) { _x = x; _y = y; _z = z; } public DPointUseClass() { } public static explicit operator DPointUseClass(string s) { string[] values = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 3) { double d = Convert.ToDouble(values[0]); double d2 = Convert.ToDouble(values[1]); double d3 = Convert.ToDouble(values[2]); return new DPointUseClass(d, d2, d3); } else { return new DPointUseClass(2, 3, 4); } } } public class MyConvertorUseStruct : ExpandableObjectConverter { 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 is string) { return (DPointUseStruct)value.ToString(); } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is DPointUseStruct) { DPointUseStruct dp = (DPointUseStruct)value; return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z); } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType.GetType() == typeof(string); } public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { return new DPointUseStruct((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]); } //public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) //{ // // Passes the local integer array. // StandardValuesCollection svc = // new StandardValuesCollection( // return svc; //} //public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) //{ // return true; //} } public class MyConvertorUseClass : ExpandableObjectConverter { 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 is string) { return (DPointUseClass)value.ToString(); } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value is DPointUseClass) { DPointUseClass dp = (DPointUseClass)value; return string.Format("{0},{1},{2}", dp.X, dp.Y, dp.Z); } return base.ConvertTo(context, culture, value, destinationType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType.GetType() == typeof(string); } public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues) { return new DPointUseClass((double)propertyValues["X"], (double)propertyValues["Y"], (double)propertyValues["Z"]); } //public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context) //{ // // Passes the local integer array. // StandardValuesCollection svc = // new StandardValuesCollection( // return svc; //} //public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context) //{ // return true; //} } [ParseChildren(true), PersistChildren(false)] public class MyDPointUseStruct : WebControl { DPointUseStruct dp = new DPointUseStruct(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [PersistenceMode(PersistenceMode.InnerProperty)] [NotifyParentProperty(true)] public DPointUseStruct DPoint { get { return dp; } set { dp = value; } } protected override void Render(HtmlTextWriter writer) { writer.Write(string.Format("[{0},{1},{2}],use struct", DPoint.X, DPoint.Y, DPoint.Z)); } } public class MyDPointUseClass : WebControl { DPointUseClass dp = new DPointUseClass(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [PersistenceMode(PersistenceMode.InnerProperty)] [NotifyParentProperty(true)] public DPointUseClass DPoint { get { return dp; } set { dp = value; } } protected override void Render(HtmlTextWriter writer) { writer.Write(string.Format("[{0},{1},{2}],use class", DPoint.X, DPoint.Y, DPoint.Z)); } } }Feedback to us
Develop and promote your apps in Windows Store
ToughMan
Participant
1490 Points
635 Posts
Re: Why struct doesn't work properly?
Dec 05, 2012 04:19 AM|LINK
MSFT;)
Plz read carefully about my 1st issue——Why must I add this underlined, bold overridable method for a struct, but not for a class?
Hope u can save both of our time to answer questions. Nothing is wrong with my codes, but KNOW THE REASON WHY?!
Mamba Dai - ...
All-Star
23531 Points
2683 Posts
Microsoft
Re: Why struct doesn't work properly?
Dec 06, 2012 07:51 AM|LINK
Hi,
I just copy your code and test it on my machine, when it runs, there are some error occurs(I mentioned them at my first reply)
Based on my testing, it doesn't have to override this method for a struct(I didn't said "doestn't have to" explicitly at the beginning), check my reply above or the quote below:
And the testing code please refer to my second reply, it includes struct and class.
Now could you just create a new project and copy my testing code to run? Or send you project to me, I will test it on my machine.
You can remove any confidential information and business logic.
Hope it helps. Any question please feel free to comment. I will go ahead.
Feedback to us
Develop and promote your apps in Windows Store