Implementing type converter for specific type dropdown items
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
add a comment |
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
So,Language
is aListItem
. 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
add a comment |
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
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
c# .net typeconverter
asked Nov 11 at 23:08
Smith
2,9761277138
2,9761277138
So,Language
is aListItem
. 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
add a comment |
So,Language
is aListItem
. 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
add a comment |
1 Answer
1
active
oldest
votes
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 notArrayList
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
.
users cannot make up or type in a new language?
No
– Smith
Nov 13 at 17:28
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 notArrayList
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
.
users cannot make up or type in a new language?
No
– Smith
Nov 13 at 17:28
add a comment |
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 notArrayList
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
.
users cannot make up or type in a new language?
No
– Smith
Nov 13 at 17:28
add a comment |
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 notArrayList
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
.
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 notArrayList
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
.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
So,
Language
is aListItem
. 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