```
class Sample
{
public StringDictionary StringMapping
{
get
{
return _stringMapping;
}
set
{
if (_stringMapping == value)
return;
_stringMapping = value;
OnPropertyChanged();
}
}
}
[TypeConverter(typeof(StringDictionaryConverter))]
[Serializable]
public class StringDictionary : Dictionary<string, string>
{
public StringDictionary()
{
}
protected StringDictionary(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
public class StringDictionaryConverter : SimpleDictionaryConverter<string, string, StringDictionary>
{
// convert dict to "key1=value1 key2=value2 ..." and vice versa
}
```
A text box will let me edit the values, while the property grid only shows "somenamespace.StringDictionary"
Comments: ** Comment from web user: BoucherS **
That is true. When a TypeConverter is used, the only thing done in PropertyGridUtilities.CreateDefaultEditor() is :
typeConverter.CanConvertFrom( typeof( string ) )
and if yes, a TextBoxEditor is created. The Typeconverter should be used.
Here is a complete sample :
```
<StackPanel>
<xctk:PropertyGrid x:Name="_propertyGrid"
SelectedObject="{Binding}"
AutoGenerateProperties="False">
<xctk:PropertyGrid.PropertyDefinitions>
<xctk:PropertyDefinition Name="StringMapping" />
</xctk:PropertyGrid.PropertyDefinitions>
</xctk:PropertyGrid>
<TextBox x:Name="_textBox"
Text="{Binding StringMapping}" />
</StackPanel>
```
and in code-behind :
```
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
Xceed.Wpf.Toolkit.Licenser.LicenseKey = "XXXXX-XXXXX-XXXXX-XXXX";
InitializeComponent();
_textBox.DataContext = this;
_propertyGrid.DataContext = this;
StringDictionary test = new StringDictionary();
test.Add( "abc", "ABC" );
test.Add( "def", "DEF" );
test.Add( "ghi", "GHI" );
test.Add( "jkl", "JKL" );
this.StringMapping = test;
}
public StringDictionary StringMapping
{
get
{
return _stringMapping;
}
set
{
if( _stringMapping == value )
return;
_stringMapping = value;
this.OnPropertyChanged( new PropertyChangedEventArgs( "StringMapping" ) );
}
}
private StringDictionary _stringMapping;
protected virtual void OnPropertyChanged( PropertyChangedEventArgs e )
{
if( PropertyChanged != null )
{
PropertyChanged( this, e );
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
[TypeConverter( typeof( StringDictionaryConverter ) )]
[Serializable]
public class StringDictionary : Dictionary<string, string>
{
public StringDictionary()
{
}
protected StringDictionary( SerializationInfo info, StreamingContext context )
: base( info, context )
{
}
}
public class StringDictionaryConverter : TypeConverter
{
public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )
{
if( sourceType == typeof( string ) )
{
return true;
}
return base.CanConvertFrom( context, sourceType );
}
public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value )
{
if( value is string )
{
StringDictionary dict = new StringDictionary();
string[] v = ( ( string )value ).Split( new char[] { ' ' } );
foreach( string s in v)
{
string[] r = ( ( string )s ).Split( new char[] { '=' } );
if( r.Count() == 2 )
dict.Add( r[ 0 ], r[ 1 ] );
}
return dict;
}
return base.ConvertFrom( context, culture, value );
}
public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType )
{
if( destinationType == typeof( string ) )
{
StringDictionary dict = ( StringDictionary )value;
string result = "";
foreach( string key in dict.Keys )
{
string newString = key;
newString += "=";
newString += dict[ key ];
newString += " ";
result += newString;
}
return result;
}
return base.ConvertTo( context, culture, value, destinationType );
}
}
```