TypeConverter question

A

--== Alain ==--

Hi,

i've developed my own TypeConverter and i have some issue.

Here is my custom control class definition :

[Category("Appearance")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description("Setup Style, Type and Color of gridlines to draw.")]
[TypeConverter(typeof(CGridLineConverter))]
public CGridLine GridLines
{
....
}

and here is my TypeConverter class :
public class CGridLineConverter : ExpandableObjectConverter
{
....
}

and my CGridLine class :
public class CGridLine
{
....
}

When i test m custom control in TestContainer i have the following behavior.

test 1.
If i test it like that, the property "GridLines" from my custom control
is not displayed in the propertyGrid of TestContainer window.

test 2.
If i comment the line
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
and
[TypeConverter(typeof(CGridLineConverter))]
the property "GridLines" is displayed but disable (tge same for its
value field)

test 3.
If i comment the line
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
and
[TypeConverter(typeof(CGridLineConverter))] is not commented.
the "GridLines" property is disbled, but its value field is colored in
black (the full cell in property Grid)

test 4.
If
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
is not commented
and
[TypeConverter(typeof(CGridLineConverter))] is commented

the "GridLines" property is displayed as accessible, but its value field
displays : ARListView.Design.CGridLine

which correspond to Namespace1.Namespace2.ClassName of my property.

So where is the problem ?
Why property is not displayed when both attributes are "not commented",
so active ?

It's already 4 days that i'm searching and searching without finding
some reason.

thanks a lot for your help,

Al.
 
O

Oliver Sturm

Hello Al,

I'm sorry, I'm sure this is not too helpful - but I admit I'm having a
hard time reading and following your long-ish description. If you can post
some code I can just copy and paste into a fresh VS project, I'm willing
to do so and see whether I can find a solution for you.


Oliver Sturm
 
A

--== Alain ==--

Ok, so sorry for those who dislike this...here is the code.

My custom control code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MyComponent
{
public partial class Frame : UserControl
{

public Frame()
{
InitializeComponent();
//this.m_GridLines = new CGridLine();
}

private CGridLine m_GridLines= new CGridLine();

[Category("Appearance")]
[Browsable(true)]

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description("Setup Style, Type and Color of gridlines to draw.")]
[TypeConverter(typeof(CGridLineConverter))]
public CGridLine GridLines
{
get
{
return this.m_GridLines;
}
set
{
this.m_GridLines = value;
}
}

}
}


my GridLines class and its converter code :

using System;
using System.Drawing;
using System.ComponentModel;
using System.Globalization;
using System.Diagnostics;

namespace MyComponent
{
/// <summary>
/// Specifies how a Table draws grid lines between its rows and columns
/// </summary>
public enum GridLines
{
/// <summary>
/// No grid lines are drawn
/// </summary>
None = 0,

/// <summary>
/// Grid lines are only drawn between columns
/// </summary>
Columns = 1,

/// <summary>
/// Grid lines are only drawn between rows
/// </summary>
Rows = 2,

/// <summary>
/// Grid lines are drawn between rows and columns
/// </summary>
All = 3
}

/// <summary>
/// Specifies the style of the lines drawn when a Table draws its
grid lines
/// </summary>
public enum GridLineStyle
{
/// <summary>
/// Specifies a solid line
/// </summary>
Solid = 0,

/// <summary>
/// Specifies a line consisting of dashes
/// </summary>
Dash = 1,

/// <summary>
/// Specifies a line consisting of dots
/// </summary>
Dot = 2,

/// <summary>
/// Specifies a line consisting of a repeating pattern of dash-dot
/// </summary>
DashDot = 3,

/// <summary>
/// Specifies a line consisting of a repeating pattern of dash-dot-dot
/// </summary>
DashDotDot = 4
}

[TypeConverter(typeof(CGridLineConverter))]
public class CGridLine
{
#region Class Data

private GridLines m_GridLines;
private GridLineStyle m_GridLinesStyle;
private Color m_GridLinesColor;

#endregion

#region Constructor

public CGridLine()
{
this.m_GridLines = GridLines.None;
this.m_GridLinesColor = System.Drawing.SystemColors.ActiveBorder;
this.m_GridLinesStyle = GridLineStyle.Solid;
}

public CGridLine(GridLines LineType, GridLineStyle LineStyle, Color
LineColor)
{
this.m_GridLines = LineType;
this.m_GridLinesColor = LineColor;
this.m_GridLinesStyle = LineStyle;
}
#endregion

#region Properties

/// <summary>
/// Style of the GridLines
/// </summary>
///
[RefreshProperties(RefreshProperties.Repaint)]
[NotifyParentProperty(true)]
[DefaultValue(typeof(GridLineStyle), "Solid")]
public GridLineStyle Style
{
get
{
return this.m_GridLinesStyle;
}
set
{
this.m_GridLinesStyle = value;
}
}

/// <summary>
/// Types of GridLines
/// </summary>
[RefreshProperties(RefreshProperties.Repaint)]
[NotifyParentProperty(true)]
[DefaultValue(typeof(GridLines), "None")]
public GridLines Lines
{
get
{
return this.m_GridLines;
}
set
{
this.m_GridLines = value;
}
}

/// <summary>
/// Color of the GridLine
/// </summary>
[RefreshProperties(RefreshProperties.Repaint)]
[NotifyParentProperty(true)]
[DefaultValue(typeof(Color), "ActiveBorder")]
public Color Color
{
get
{
return this.m_GridLinesColor;
}
set
{
this.m_GridLinesColor = value;
}
}

#endregion

}

public class CGridLineConverter : ExpandableObjectConverter
{
/// <summary>
/// Check if it the parameter (context) is a string and can convert
it to class type (destinationType)
/// </summary>
/// <param name="context">string that holds the class type
information</param>
/// <param name="destinationType">class type to which the context
must be converted</param>
/// <returns>true if it's possible, or false in case of impossible
conversion</returns>

public override bool CanConvertTo(ITypeDescriptorContext
context,Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
else
{
return base.CanConvertTo(context, destinationType);
}
}

/// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <param name="culture"></param>
/// <param name="value"></param>
/// <param name="destinationType"></param>
/// <returns></returns>

public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ToString(value);
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
}

/// <summary>
/// ConverToString whole subproperties
/// </summary>
/// <param name="value">value holds by CGridLine property</param>
/// <returns>Formatted string that holds the CGridLine property
converted into text</returns>
private string ToString(object value)
{
CGridLine m_GridLine = (CGridLine)value;
ColorConverter ColConverter = new ColorConverter();
StringConverter StrConverter = new StringConverter();

return String.Format("{0}, {1}, {2}",
m_GridLine.Lines.ToString(),
m_GridLine.Style.ToString(),
ColConverter.ConvertToString(m_GridLine.Color));
}

public override bool CanConvertFrom(ITypeDescriptorContext
context,Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
else
{
return base.CanConvertFrom(context, sourceType);
}
}

public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo culture, object value)
{
if (value is string)
{
return FromString(value);
}
else
{
return base.ConvertFrom(context, culture, value);
}
}

private CGridLine FromString(object value)
{
string[] values = ((string)value).Split(',');
if (values.Length != 3)
throw new ArgumentException("Could not convert the value !");
try
{
CGridLine my_GridLine = new CGridLine();
ColorConverter ColConverter = new ColorConverter();
StringConverter StrConverter = new StringConverter();

my_GridLine.Lines = (GridLines)Enum.Parse(typeof(GridLines),
values[0], true);
my_GridLine.Style =
(GridLineStyle)Enum.Parse(typeof(GridLineStyle), values[1], true);
my_GridLine.Color =
(Color)ColConverter.ConvertFromString(values[2]);

return my_GridLine;
}
catch (Exception err)
{
String ErrorMsg = "Could not convert the value \n\n Error
Message : " + err.Message;
throw new ArgumentException(ErrorMsg);
}
}
}
}

You can cut and paste into a brand new usercontrol and check what is the
behavior based on my previous post regarding test process.

Alain.
 
O

Oliver Sturm

Hello,
Anyway, as i told you my component works great once it is compiled and
used on some forms...so i believe you ;-)

my problem was that when i test it with "TestContainer" window, the
property was not correctly displayed.

Hm, now you have me confused. I remember reading this part of your
original post, but I assumed you were talking about "a test container", as
opposed to something called TestContainer (yes, I ignored your suggestive
capitalization). You're probably going to find this funny, but with all
I've done I've never heard of anything called the TestContainer and even
Google is not able to help me find out what you're talking about. Please
enlighten me?
Based on this experience, the question is : can we trust the TestContainer
?

My first reaction would be to say who cares?! If it works in VS itself,
that's all I would be interested in. And if the TestContainer, whatever it
is, obviously doesn't work the same way the VS designer does, then it's
either not intended to work the same way or it's broken.


Oliver Sturm
 
O

Oliver Sturm

Hello Alain,

Amazing, you learn something new every day. One of the reasons I never saw
this before may be that apparently it works only for "Windows Control
Library" type projects, and I don't remember ever creating one of these
either. Google finds enough for your search string "visual studio 2005
user control test container", but is pretty helpless with "testcontainer"
alone. That's search machines for you...

Now, whatever - interesting to learn about this, but my position isn't
really changing. Your example shows - and I understand your post was
partly to get somebody's confirmation on this - that the test container
doesn't behave exactly like the VS designer in all cases. That will be
enough for me to stay ignorant of it in the future, and as it is really
easy (in VS 2005) to test user controls directly in VS by dropping them on
forms, I would advise everybody else to skip a testing container that
doesn't give reliable results.

My mind is still on this and I also just had the idea that this container
wouldn't be very helpful in many cases where I've created controls in the
past... very regularly it happens that a control has some relation to
other controls or components on a form, and I don't see how the test
container would cover those scenarios.


Oliver Sturm
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top