Implementing type converter for specific type dropdown items












0














The usercontrol that will use the type converter



Public Class MYControl : Usercotrol 
{

private ListItem _Language;
[TypeConverter(typeof(LanguageEditor))]
public ListItem Language
{
get
{
return _Language;
}
set
{
_Language= value;
}
}
}


The type to list in the dropdown property window



public class ListItem
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
}
}
public ListItem(string Name, string value)
{
_Value = value;
_Name = Name;
}

public override string ToString()
{
return this._Name;
}
}


How do i implement the type converter for this, this is what i tried without success



public class LangEditor : TypeConverter
{
private ArrayList values;

public LangEditor()
{
// Initializes the standard values list with defaults.
values = new ArrayList();
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

values.Add(new ListItem(ci.DisplayName, ci.Name));
} // New

// Indicates this type converter provides a list of standard values.
public new override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
} // GetStandardValuesSupported

// Returns a StandardValuesCollection of standard value objects.
public new override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local value array.
StandardValuesCollection svc = new StandardValuesCollection(values);
return svc;
}

public new override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
var propItem = context.Instance as ListItem;
return propItem != null && TypeDescriptor.GetConverter(typeof(ListItem)).CanConvertFrom(context, sourceType) || base.CanConvertFrom(context, sourceType);
} // CanConvertFrom

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var propItem = context.Instance as ListItem;

if (propItem != null)
return TypeDescriptor.GetConverter(typeof(ListItem)).ConvertFrom(context, culture, value);
else
return base.ConvertFrom(context, culture, value, ListItem);
}
}









share|improve this question






















  • So, Language is a ListItem. What are you trying to convert it to?
    – Gabriel Luci
    Nov 12 at 1:36










  • The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
    – WelcomeOverflow
    Nov 13 at 0:19












  • @Disaffected1070452 yes, this is the problem, what is the fix for this ?
    – Smith
    Nov 13 at 9:17
















0














The usercontrol that will use the type converter



Public Class MYControl : Usercotrol 
{

private ListItem _Language;
[TypeConverter(typeof(LanguageEditor))]
public ListItem Language
{
get
{
return _Language;
}
set
{
_Language= value;
}
}
}


The type to list in the dropdown property window



public class ListItem
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
}
}
public ListItem(string Name, string value)
{
_Value = value;
_Name = Name;
}

public override string ToString()
{
return this._Name;
}
}


How do i implement the type converter for this, this is what i tried without success



public class LangEditor : TypeConverter
{
private ArrayList values;

public LangEditor()
{
// Initializes the standard values list with defaults.
values = new ArrayList();
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

values.Add(new ListItem(ci.DisplayName, ci.Name));
} // New

// Indicates this type converter provides a list of standard values.
public new override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
} // GetStandardValuesSupported

// Returns a StandardValuesCollection of standard value objects.
public new override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local value array.
StandardValuesCollection svc = new StandardValuesCollection(values);
return svc;
}

public new override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
var propItem = context.Instance as ListItem;
return propItem != null && TypeDescriptor.GetConverter(typeof(ListItem)).CanConvertFrom(context, sourceType) || base.CanConvertFrom(context, sourceType);
} // CanConvertFrom

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var propItem = context.Instance as ListItem;

if (propItem != null)
return TypeDescriptor.GetConverter(typeof(ListItem)).ConvertFrom(context, culture, value);
else
return base.ConvertFrom(context, culture, value, ListItem);
}
}









share|improve this question






















  • So, Language is a ListItem. What are you trying to convert it to?
    – Gabriel Luci
    Nov 12 at 1:36










  • The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
    – WelcomeOverflow
    Nov 13 at 0:19












  • @Disaffected1070452 yes, this is the problem, what is the fix for this ?
    – Smith
    Nov 13 at 9:17














0












0








0







The usercontrol that will use the type converter



Public Class MYControl : Usercotrol 
{

private ListItem _Language;
[TypeConverter(typeof(LanguageEditor))]
public ListItem Language
{
get
{
return _Language;
}
set
{
_Language= value;
}
}
}


The type to list in the dropdown property window



public class ListItem
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
}
}
public ListItem(string Name, string value)
{
_Value = value;
_Name = Name;
}

public override string ToString()
{
return this._Name;
}
}


How do i implement the type converter for this, this is what i tried without success



public class LangEditor : TypeConverter
{
private ArrayList values;

public LangEditor()
{
// Initializes the standard values list with defaults.
values = new ArrayList();
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

values.Add(new ListItem(ci.DisplayName, ci.Name));
} // New

// Indicates this type converter provides a list of standard values.
public new override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
} // GetStandardValuesSupported

// Returns a StandardValuesCollection of standard value objects.
public new override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local value array.
StandardValuesCollection svc = new StandardValuesCollection(values);
return svc;
}

public new override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
var propItem = context.Instance as ListItem;
return propItem != null && TypeDescriptor.GetConverter(typeof(ListItem)).CanConvertFrom(context, sourceType) || base.CanConvertFrom(context, sourceType);
} // CanConvertFrom

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var propItem = context.Instance as ListItem;

if (propItem != null)
return TypeDescriptor.GetConverter(typeof(ListItem)).ConvertFrom(context, culture, value);
else
return base.ConvertFrom(context, culture, value, ListItem);
}
}









share|improve this question













The usercontrol that will use the type converter



Public Class MYControl : Usercotrol 
{

private ListItem _Language;
[TypeConverter(typeof(LanguageEditor))]
public ListItem Language
{
get
{
return _Language;
}
set
{
_Language= value;
}
}
}


The type to list in the dropdown property window



public class ListItem
{
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
private string _Value;
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
}
}
public ListItem(string Name, string value)
{
_Value = value;
_Name = Name;
}

public override string ToString()
{
return this._Name;
}
}


How do i implement the type converter for this, this is what i tried without success



public class LangEditor : TypeConverter
{
private ArrayList values;

public LangEditor()
{
// Initializes the standard values list with defaults.
values = new ArrayList();
foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))

values.Add(new ListItem(ci.DisplayName, ci.Name));
} // New

// Indicates this type converter provides a list of standard values.
public new override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
} // GetStandardValuesSupported

// Returns a StandardValuesCollection of standard value objects.
public new override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local value array.
StandardValuesCollection svc = new StandardValuesCollection(values);
return svc;
}

public new override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
{
var propItem = context.Instance as ListItem;
return propItem != null && TypeDescriptor.GetConverter(typeof(ListItem)).CanConvertFrom(context, sourceType) || base.CanConvertFrom(context, sourceType);
} // CanConvertFrom

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var propItem = context.Instance as ListItem;

if (propItem != null)
return TypeDescriptor.GetConverter(typeof(ListItem)).ConvertFrom(context, culture, value);
else
return base.ConvertFrom(context, culture, value, ListItem);
}
}






c# .net typeconverter






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 23:08









Smith

2,9761277138




2,9761277138












  • So, Language is a ListItem. What are you trying to convert it to?
    – Gabriel Luci
    Nov 12 at 1:36










  • The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
    – WelcomeOverflow
    Nov 13 at 0:19












  • @Disaffected1070452 yes, this is the problem, what is the fix for this ?
    – Smith
    Nov 13 at 9:17


















  • So, Language is a ListItem. What are you trying to convert it to?
    – Gabriel Luci
    Nov 12 at 1:36










  • The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
    – WelcomeOverflow
    Nov 13 at 0:19












  • @Disaffected1070452 yes, this is the problem, what is the fix for this ?
    – Smith
    Nov 13 at 9:17
















So, Language is a ListItem. What are you trying to convert it to?
– Gabriel Luci
Nov 12 at 1:36




So, Language is a ListItem. What are you trying to convert it to?
– Gabriel Luci
Nov 12 at 1:36












The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
– WelcomeOverflow
Nov 13 at 0:19






The designer is going to use the ToString override to get the text which happens to be DisplayName. But it will never send back a ListItem, just that string and you dont handle that.
– WelcomeOverflow
Nov 13 at 0:19














@Disaffected1070452 yes, this is the problem, what is the fix for this ?
– Smith
Nov 13 at 9:17




@Disaffected1070452 yes, this is the problem, what is the fix for this ?
– Smith
Nov 13 at 9:17












1 Answer
1






active

oldest

votes


















1














In addition to some syntax and compiler errors the main issue, as mentioned in a comment, is that your ConvertFrom method expects to get back a ListItem. Even though that is what you provide in the StandardValuesCollection, the designer has no idea about your Type.



The designer needs a string for the drop down list, and in this case will use your ToString() method. But you are going to get back that string to convert/rehydrate.



You also probably want to decorate your Type with the TypeConverter attribute if you want it associated with all uses of it. Decorating only the UserControl property means just that usage has a converter. It makes it hard to debug.



I also used an idiomatic name for the converter.



//Public Class MYControl : Usercotrol 
public class MYControl : UserControl
{
public ListItem Language {get; set;}
}

// Associate the TypeConverter with the Type, not property
[TypeConverter(typeof(ListItemConverter))]
public class ListItem
{
public string Name {get; set;}
public string Value {get; set;}

// serialization will need this
public ListItem()
{ }

public ListItem(string name, string value)
{
Value = value;
Name = name;
}

public override string ToString()
{
return this.Name;
}
}


The main problem is in Can/ConvertFrom:



 var propItem = context.Instance as ListItem;
if (propItem != null)
...


The designer uses the names (strings) for the drop down and string, the user picks a string and that is what you will get back to convert, never a ListItem.



The converter should also override GetStandardValuesExclusive - users cannot make up or type in a new language, those supplied are the only legal ones, no?



Other changes in the TypeConverter code include:




  • Using a List and not ArrayList which is obsolete

  • Remove new from the overrides so it will compile

  • The StandardValuesCollection just needs to be a string collection, so I changed it to get the names from the list.




public class ListItemConverter : TypeConverter
{
private List<ListItem> languages;

public ListItemConverter()
{
// Initializes the standard values list with defaults.
languages = new List<ListItem>();

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
languages.Add(new ListItem(ci.DisplayName, ci.Name));
}
}

// Indicates this type converter provides a list of standard values.
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local array.
StandardValuesCollection svc = new StandardValuesCollection(languages);
return svc;
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
System.Type sourceType)
{
if (sourceType == typeof(string))
{
// where the debug code goes
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}

// ADDED: the list is exclusive - no new entries allowed
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
ListItem item = (ListItem)languages.
FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0));
return item;
}
else
return base.ConvertFrom(context, culture, value);
}
}


In ConvertFrom, you simply need to look up the display name you get back, find the related ListItem in the collection and return it. FirstOrDefault ought never fail and return the Default (null) since you are working from an exclusive StandardValuesCollection.






share|improve this answer























  • users cannot make up or type in a new language? No
    – Smith
    Nov 13 at 17:28











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254157%2fimplementing-type-converter-for-specific-type-dropdown-items%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














In addition to some syntax and compiler errors the main issue, as mentioned in a comment, is that your ConvertFrom method expects to get back a ListItem. Even though that is what you provide in the StandardValuesCollection, the designer has no idea about your Type.



The designer needs a string for the drop down list, and in this case will use your ToString() method. But you are going to get back that string to convert/rehydrate.



You also probably want to decorate your Type with the TypeConverter attribute if you want it associated with all uses of it. Decorating only the UserControl property means just that usage has a converter. It makes it hard to debug.



I also used an idiomatic name for the converter.



//Public Class MYControl : Usercotrol 
public class MYControl : UserControl
{
public ListItem Language {get; set;}
}

// Associate the TypeConverter with the Type, not property
[TypeConverter(typeof(ListItemConverter))]
public class ListItem
{
public string Name {get; set;}
public string Value {get; set;}

// serialization will need this
public ListItem()
{ }

public ListItem(string name, string value)
{
Value = value;
Name = name;
}

public override string ToString()
{
return this.Name;
}
}


The main problem is in Can/ConvertFrom:



 var propItem = context.Instance as ListItem;
if (propItem != null)
...


The designer uses the names (strings) for the drop down and string, the user picks a string and that is what you will get back to convert, never a ListItem.



The converter should also override GetStandardValuesExclusive - users cannot make up or type in a new language, those supplied are the only legal ones, no?



Other changes in the TypeConverter code include:




  • Using a List and not ArrayList which is obsolete

  • Remove new from the overrides so it will compile

  • The StandardValuesCollection just needs to be a string collection, so I changed it to get the names from the list.




public class ListItemConverter : TypeConverter
{
private List<ListItem> languages;

public ListItemConverter()
{
// Initializes the standard values list with defaults.
languages = new List<ListItem>();

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
languages.Add(new ListItem(ci.DisplayName, ci.Name));
}
}

// Indicates this type converter provides a list of standard values.
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local array.
StandardValuesCollection svc = new StandardValuesCollection(languages);
return svc;
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
System.Type sourceType)
{
if (sourceType == typeof(string))
{
// where the debug code goes
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}

// ADDED: the list is exclusive - no new entries allowed
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
ListItem item = (ListItem)languages.
FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0));
return item;
}
else
return base.ConvertFrom(context, culture, value);
}
}


In ConvertFrom, you simply need to look up the display name you get back, find the related ListItem in the collection and return it. FirstOrDefault ought never fail and return the Default (null) since you are working from an exclusive StandardValuesCollection.






share|improve this answer























  • users cannot make up or type in a new language? No
    – Smith
    Nov 13 at 17:28
















1














In addition to some syntax and compiler errors the main issue, as mentioned in a comment, is that your ConvertFrom method expects to get back a ListItem. Even though that is what you provide in the StandardValuesCollection, the designer has no idea about your Type.



The designer needs a string for the drop down list, and in this case will use your ToString() method. But you are going to get back that string to convert/rehydrate.



You also probably want to decorate your Type with the TypeConverter attribute if you want it associated with all uses of it. Decorating only the UserControl property means just that usage has a converter. It makes it hard to debug.



I also used an idiomatic name for the converter.



//Public Class MYControl : Usercotrol 
public class MYControl : UserControl
{
public ListItem Language {get; set;}
}

// Associate the TypeConverter with the Type, not property
[TypeConverter(typeof(ListItemConverter))]
public class ListItem
{
public string Name {get; set;}
public string Value {get; set;}

// serialization will need this
public ListItem()
{ }

public ListItem(string name, string value)
{
Value = value;
Name = name;
}

public override string ToString()
{
return this.Name;
}
}


The main problem is in Can/ConvertFrom:



 var propItem = context.Instance as ListItem;
if (propItem != null)
...


The designer uses the names (strings) for the drop down and string, the user picks a string and that is what you will get back to convert, never a ListItem.



The converter should also override GetStandardValuesExclusive - users cannot make up or type in a new language, those supplied are the only legal ones, no?



Other changes in the TypeConverter code include:




  • Using a List and not ArrayList which is obsolete

  • Remove new from the overrides so it will compile

  • The StandardValuesCollection just needs to be a string collection, so I changed it to get the names from the list.




public class ListItemConverter : TypeConverter
{
private List<ListItem> languages;

public ListItemConverter()
{
// Initializes the standard values list with defaults.
languages = new List<ListItem>();

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
languages.Add(new ListItem(ci.DisplayName, ci.Name));
}
}

// Indicates this type converter provides a list of standard values.
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local array.
StandardValuesCollection svc = new StandardValuesCollection(languages);
return svc;
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
System.Type sourceType)
{
if (sourceType == typeof(string))
{
// where the debug code goes
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}

// ADDED: the list is exclusive - no new entries allowed
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
ListItem item = (ListItem)languages.
FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0));
return item;
}
else
return base.ConvertFrom(context, culture, value);
}
}


In ConvertFrom, you simply need to look up the display name you get back, find the related ListItem in the collection and return it. FirstOrDefault ought never fail and return the Default (null) since you are working from an exclusive StandardValuesCollection.






share|improve this answer























  • users cannot make up or type in a new language? No
    – Smith
    Nov 13 at 17:28














1












1








1






In addition to some syntax and compiler errors the main issue, as mentioned in a comment, is that your ConvertFrom method expects to get back a ListItem. Even though that is what you provide in the StandardValuesCollection, the designer has no idea about your Type.



The designer needs a string for the drop down list, and in this case will use your ToString() method. But you are going to get back that string to convert/rehydrate.



You also probably want to decorate your Type with the TypeConverter attribute if you want it associated with all uses of it. Decorating only the UserControl property means just that usage has a converter. It makes it hard to debug.



I also used an idiomatic name for the converter.



//Public Class MYControl : Usercotrol 
public class MYControl : UserControl
{
public ListItem Language {get; set;}
}

// Associate the TypeConverter with the Type, not property
[TypeConverter(typeof(ListItemConverter))]
public class ListItem
{
public string Name {get; set;}
public string Value {get; set;}

// serialization will need this
public ListItem()
{ }

public ListItem(string name, string value)
{
Value = value;
Name = name;
}

public override string ToString()
{
return this.Name;
}
}


The main problem is in Can/ConvertFrom:



 var propItem = context.Instance as ListItem;
if (propItem != null)
...


The designer uses the names (strings) for the drop down and string, the user picks a string and that is what you will get back to convert, never a ListItem.



The converter should also override GetStandardValuesExclusive - users cannot make up or type in a new language, those supplied are the only legal ones, no?



Other changes in the TypeConverter code include:




  • Using a List and not ArrayList which is obsolete

  • Remove new from the overrides so it will compile

  • The StandardValuesCollection just needs to be a string collection, so I changed it to get the names from the list.




public class ListItemConverter : TypeConverter
{
private List<ListItem> languages;

public ListItemConverter()
{
// Initializes the standard values list with defaults.
languages = new List<ListItem>();

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
languages.Add(new ListItem(ci.DisplayName, ci.Name));
}
}

// Indicates this type converter provides a list of standard values.
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local array.
StandardValuesCollection svc = new StandardValuesCollection(languages);
return svc;
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
System.Type sourceType)
{
if (sourceType == typeof(string))
{
// where the debug code goes
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}

// ADDED: the list is exclusive - no new entries allowed
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
ListItem item = (ListItem)languages.
FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0));
return item;
}
else
return base.ConvertFrom(context, culture, value);
}
}


In ConvertFrom, you simply need to look up the display name you get back, find the related ListItem in the collection and return it. FirstOrDefault ought never fail and return the Default (null) since you are working from an exclusive StandardValuesCollection.






share|improve this answer














In addition to some syntax and compiler errors the main issue, as mentioned in a comment, is that your ConvertFrom method expects to get back a ListItem. Even though that is what you provide in the StandardValuesCollection, the designer has no idea about your Type.



The designer needs a string for the drop down list, and in this case will use your ToString() method. But you are going to get back that string to convert/rehydrate.



You also probably want to decorate your Type with the TypeConverter attribute if you want it associated with all uses of it. Decorating only the UserControl property means just that usage has a converter. It makes it hard to debug.



I also used an idiomatic name for the converter.



//Public Class MYControl : Usercotrol 
public class MYControl : UserControl
{
public ListItem Language {get; set;}
}

// Associate the TypeConverter with the Type, not property
[TypeConverter(typeof(ListItemConverter))]
public class ListItem
{
public string Name {get; set;}
public string Value {get; set;}

// serialization will need this
public ListItem()
{ }

public ListItem(string name, string value)
{
Value = value;
Name = name;
}

public override string ToString()
{
return this.Name;
}
}


The main problem is in Can/ConvertFrom:



 var propItem = context.Instance as ListItem;
if (propItem != null)
...


The designer uses the names (strings) for the drop down and string, the user picks a string and that is what you will get back to convert, never a ListItem.



The converter should also override GetStandardValuesExclusive - users cannot make up or type in a new language, those supplied are the only legal ones, no?



Other changes in the TypeConverter code include:




  • Using a List and not ArrayList which is obsolete

  • Remove new from the overrides so it will compile

  • The StandardValuesCollection just needs to be a string collection, so I changed it to get the names from the list.




public class ListItemConverter : TypeConverter
{
private List<ListItem> languages;

public ListItemConverter()
{
// Initializes the standard values list with defaults.
languages = new List<ListItem>();

foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
languages.Add(new ListItem(ci.DisplayName, ci.Name));
}
}

// Indicates this type converter provides a list of standard values.
public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}

public override StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
{
// Passes the local array.
StandardValuesCollection svc = new StandardValuesCollection(languages);
return svc;
}

public override bool CanConvertFrom(ITypeDescriptorContext context,
System.Type sourceType)
{
if (sourceType == typeof(string))
{
// where the debug code goes
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}

// ADDED: the list is exclusive - no new entries allowed
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if(value is string)
{
ListItem item = (ListItem)languages.
FirstOrDefault( q => (string.Compare(q.Name, value.ToString(),true) == 0));
return item;
}
else
return base.ConvertFrom(context, culture, value);
}
}


In ConvertFrom, you simply need to look up the display name you get back, find the related ListItem in the collection and return it. FirstOrDefault ought never fail and return the Default (null) since you are working from an exclusive StandardValuesCollection.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 at 19:12

























answered Nov 13 at 17:04









WelcomeOverflow

35.2k113794




35.2k113794












  • users cannot make up or type in a new language? No
    – Smith
    Nov 13 at 17:28


















  • users cannot make up or type in a new language? No
    – Smith
    Nov 13 at 17:28
















users cannot make up or type in a new language? No
– Smith
Nov 13 at 17:28




users cannot make up or type in a new language? No
– Smith
Nov 13 at 17:28


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254157%2fimplementing-type-converter-for-specific-type-dropdown-items%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini