Help! custom TypeConverter/Persistence problems...

Discussion in 'ASP .Net Web Controls' started by Sky Sigal, Jul 13, 2004.

  1. Sky Sigal

    Sky Sigal Guest

    My goal is to keep public properties of a custom Control neatly tied
    together -- rather than all over the IDE.

    One such set of values that will rarely be changed, so should have little
    priority in the IDE Properties panel, is maybe Captions that are used
    through the text.

    So assuming that I made the following class

    class MyControl : WebControl {
    ....

    public class cCaptions {
    public string _Btn_Submit = "Login";
    public string _Btn_NewUser = "Register";
    public string Btn_Submit {get{return _Btn_Submit;}set{_Btn_Submit=value;}}
    public string Btn_NewUser {get{return
    _Btn_NewUser;}set{_Btn_NewUser=value;}}
    }//Subclass:End
    ....

    private cCaptions _Captions = new cCaptions;
    ....
    [TypeConverter(typeof(TestConverter)),
    PersistenceMode(PersistenceMode.Attribute )]
    public cCaptions {get {return _Captions;}set {_Captions = value;}
    ....
    }//Control:End


    As you can see the public property now requires a custom TypeConverter so
    that it can be seen in the IDE -- and deal with persistence as an attribute.

    I originally thought/tried using the standard ExpandableObject one -- but I
    needed a way to persist it in one string -- just like how style="" attribute
    is done, with : and ; as sep chars between key and value...


    Well.
    The TypeConverter I wrote works atleast for converting between object and
    string, and now in the IDE's Property panel I get the expandableObject look
    (+/- tree) as well as a means of reading it as one string which looks like

    <MyControl CAPTIONS="Btn_Submit:Login;Btn_NewUser:Register"></MyControl>


    My problem with this is that it all LOOKS right -- but its not acting
    right...


    Problems/Observations:
    a) When I edit the string directly in the Properties panel -- eg change it
    to "Btn_Submit:HELLO;Btn_NewUser:Come on in!" it ---well...doesn't do it.
    The moment I hit Save -- it reverts back to to the default values. :-(
    b) When I click + to expand the Expandable options, and edit the Btn_Submit
    value directly -- it updates the summary string line/title to the new
    values -- AND updates the interface's actual label (I have to hit save to
    get this to trigger)-- but when I check the Html of the control -- its not
    been notified of the changes and still shows default values...
    c) If I edit the Html of the Control to another value. Nothing happens.


    In other words -- total disconnection between the values of the property --
    and what is persisted.

    Anybody have an idea?


    I attach the TypeConverter that I wrote in case it is the cause -- or if
    not, that it may be the starting point for someone else...





    using System;
    using System.Web.UI.Design;
    using System.Web;
    using System.ComponentModel;
    using System.Globalization;
    using System.Reflection;
    using System.Collections;

    namespace XAct.Web.Controls {

    public class TestConverter : ExpandableObjectConverter {
    System.Type _Type = typeof(XAct.Web.Controls.LoginPanel.cCaptions);

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

    public override object ConvertFrom(ITypeDescriptorContext context,
    CultureInfo info,object value) {
    if (value is string) {
    string[] tParts;
    tParts = SplitPlus((string) value, ";");
    object o = _Type.Assembly.CreateInstance(_Type.ToString());
    string tKey = string.Empty;
    string tValue = string.Empty;
    int tPos = 0;
    foreach (string tPart in tParts){
    if (tPart == string.Empty){continue;}
    tPos = tPart.IndexOf(':');
    if (tPos == -1){
    tPos = tPart.Length;
    tKey = tPart;
    tValue = string.Empty;
    }else{
    tKey = tPart.Substring(0,tPos);
    tValue = tPart.Substring(tPos+1);
    System.Reflection.PropertyInfo oPI =
    _Type.GetProperty(tKey,System.Reflection.BindingFlags.SetProperty |
    System.Reflection.BindingFlags.Public
    |System.Reflection.BindingFlags.IgnoreCase);
    if (oPI != null){
    oPI.SetValue(o,tValue,null);
    }
    }
    }
    return o;
    }
    return base.ConvertFrom(context, info, value);
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo
    culture, object value, Type destType) {
    object o=null;
    try {
    o = System.Convert.ChangeType(value,_Type);
    }catch{}
    if ((o !=null) && (destType == typeof(string))) {
    string tResult = string.Empty;
    string tDivChar = string.Empty;
    PropertyInfo[] oPIs = _Type.GetProperties();
    foreach(PropertyInfo oPI in oPIs){
    string tKey = oPI.Name;
    object oVal = oPI.GetValue(o,null);
    string tValue = string.Empty;
    if (oVal != null){
    tValue = oVal.ToString();
    if (tValue != string.Empty){tResult += tDivChar + tKey + ":" + tValue;}
    if (tDivChar == string.Empty){tDivChar = ";";}
    }
    }
    return tResult;
    }
    return base.ConvertTo(context, culture, value, destType);
    }

    /// <summary>
    /// Split function that only splits if not within brackets or quotes.
    /// </summary>
    /// <param name="qString"></param>
    /// <param name="qDivChar"></param>
    /// <returns></returns>
    public static string[] SplitPlus(string qString, string qDivChar) {
    if (qDivChar== String.Empty){qDivChar = ",";}
    ArrayList tResults = new ArrayList();
    string tChar="";
    string tWord = "";
    bool tEscaped=false;
    string tLastChar = "";
    System.Collections.Stack tQuotes=new System.Collections.Stack();
    for (int i=0;i<qString.Length;i++) {
    tChar = qString.ToString();
    if (tQuotes.Count == 0) {
    //We are outside of quotes, so look for quote beginnings...
    if ((tChar == "(") ||
    (tChar == "{") ||
    (tChar == "[") ||
    (tChar == "'") ||
    (tChar == "\"")) {
    tQuotes.Push(tChar);
    tLastChar=tChar;
    }
    if ((tChar == qDivChar)) {
    tResults.Add(tWord);
    tWord="";
    tChar = "";
    }
    }
    else {
    //We are within quotes...need to look for close chars:
    if (tEscaped ==false) {
    if (tChar == "\\") {tEscaped=true;}
    else {
    tLastChar =(string)tQuotes.Peek();
    if ((tChar == "\"") && (tChar == tLastChar)) {
    tQuotes.Pop();
    }
    else if ((tChar == "\'") && (tChar == tLastChar)) {
    tQuotes.Pop();
    }
    else if ((tChar == "]") && (tLastChar == "[")) {
    tQuotes.Pop();
    }
    else if ((tChar == "}") && (tLastChar == "{")) {
    tQuotes.Pop();
    }
    if ((tChar == ")") && (tLastChar == "(")) {
    tQuotes.Pop();
    }
    }
    }
    else {
    tEscaped = false;
    }
    }
    tWord = tWord+tChar;
    }
    if (tWord!= String.Empty) {tResults.Add(tWord);}
    return (string[])tResults.ToArray(typeof(string));
    }
    }//Class:End
    }
     
    Sky Sigal, Jul 13, 2004
    #1
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christian
    Replies:
    1
    Views:
    479
    Gary Varga
    Jul 18, 2003
  2. Sky Sigal
    Replies:
    1
    Views:
    503
    Sky Sigal
    Jul 14, 2004
  3. javaguy44
    Replies:
    10
    Views:
    1,010
    Michael Berg
    May 18, 2004
  4. Kenneth P. Turvey

    Java Persistence API and persistence.xml

    Kenneth P. Turvey, Mar 15, 2008, in forum: Java
    Replies:
    2
    Views:
    17,506
    Kenneth P. Turvey
    Mar 16, 2008
  5. Jim
    Replies:
    4
    Views:
    217
    Steven Cheng[MSFT]
    Oct 25, 2005
Loading...

Share This Page