Home All Groups Group Topic Archive Search About
Author
12 Feb 2007 7:33 PM
--== 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.
Author
13 Feb 2007 6:00 PM
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
Are all your drivers up to date? click for free checkup

Author
13 Feb 2007 7:53 PM
--== 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.



Oliver Sturm wrote:
Show quoteHide quote
> 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
Author
13 Feb 2007 9:15 PM
Oliver Sturm
Author
14 Feb 2007 7:17 AM
--== Alain ==--
Hi Oliver,

I just wrote that "sorry for other people who dislike it" because the
code was quite long. In such case, some people in newsgroups dislike it
and wrote it.

I agree that this is the basic step and goal of such newsgroups, but it
seems that some guy do not share this idea ;-)

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.

this was my problem.

So i just wanted to know if there is a reason for that. I restarted
several times VS 2005 but it did not change anything unfortunately.

Based on this experience, the question is : can we trust the TestContainer ?

To illustrate my problem i attached 3 small screenshots.
I hope that my situation will be clearer with those screenshots.

Al.

Oliver Sturm wrote:
Show quoteHide quote
> Hello ,
>
>> Ok, so sorry for those who dislike this...here is the code.
>
> Why would anybody dislike this? It's the way to results...
>
>> You can cut and paste into a brand new usercontrol and check what is the
>> behavior based on my previous post regarding test process.
>
> Yep, done that. Your component works very nicely for me... with one single
> change: I commented the line
>
>    [TypeConverter(typeof(CGridLineConverter))]
>
> on the Frame.GridLines property BUT I left the same line in place for the
> CGridLine class. Originally you had the line active in both places at
> once, which apparently creates a problem for some reason. I'm attaching a
> screen shot of the property grid to this post, in case you don't believe
> me :-) I don't know if image attachments are allowed here, but I'll just
> risk it.
>
> Another hint: VS doesn't always seem to re-initialize the designer
> correctly, after changes have been made and the project recompiled. I
> believe one reason for this is that I have the component and the type
> converter and everything in one assembly - things may be better when using
> a separate assembly for this. But the general hint is: when you see
> something really inexplicable, like a change you made that doesn't seem to
> be reflected in the designer, try restarting VS.
>
>
>                 Oliver Sturm
Author
14 Feb 2007 8:41 AM
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
Author
14 Feb 2007 11:33 AM
--== Alain ==--
in fact i wrote in capital letter just to make aware people about what
it is.

As you can see in screenshots, the "test container window" is a similar
tool as the one you can find via "Tools-> Active X control test
container" (except that it is now for .NET control).

It helps you to test you custom control showing you :
- your custom control
- its properties via a propertyGrid object.

It also allows you to change properties and check the impact on your
control.

to use it, just "set as startup project" (right click on your custom
control project), your control project and press F5.

the big advantage of "test container" , it's that it allow you to debug
and test custom control without placing your control on some form.

by placing a control on some form, will generate a window form error
messages in case of your control is not well design. Which generally,
finish by deleting your control from window forms, as also its relative
code in the designer code file....

so you waste no time to clear your form, you waste no time to replace
you window form in the correct and functional status, in case your
custom control is badly design.

this is the main topic for me of this "test container" tool.

Alain
Author
14 Feb 2007 12:39 PM
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
Author
14 Feb 2007 11:35 AM
--== Alain ==--
Here is the research in Google for "user control test container"
http://www.google.com/search?hl=en&q=%22visual+studio+2005%22+%22user+control+test+container%22&btnG=Search

;-)

Oliver Sturm wrote:
Show quoteHide quote
> 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

Bookmark and Share