35465

Custom editors in a property grid that uses Dictionary

Question:

I am using a property grid that uses a dictionary using the adapter found <a href="http://www.differentpla.net/content/2005/02/using-propertygrid-with-dictionary" rel="nofollow">here</a>.

I now need the ability to use a custom editor. More specifically a file chooser. If the object in the dictionary is a string it just uses the default string editor.

Could I implement a new class called FilePath or something that would just act as a wrapper for string but would cause the property grid to use the OpenFileDialog, and display the result as a string in the PropertyGrid once chosen?

Is this possible? And if so how?

Answer1:

If you want to have the file path editor in the property grid using the dictionary adapter you have referenced, I would make the FilePath class like you suggest. You will need to also implement two additional classes to make this all work with the property grid: An editor and a type converter.

Let's assume your FilePath object is a simple one:

class FilePath { public FilePath(string inPath) { Path = inPath; } public string Path { get; set; } }

Your property grid will display the class name in light gray, not very useful. Let's write a TypeConverter to display the string that this class really wraps around

class FilePathConverter : 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, System.Globalization.CultureInfo culture, object value) { if (IsValid(context, value)) return new FilePath((string)value); return base.ConvertFrom(context, culture, value); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) return destinationType == typeof(string); return base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) return ((FilePath)value).Path; return base.ConvertTo(context, culture, value, destinationType); } public override bool IsValid(ITypeDescriptorContext context, object value) { if (value.GetType() == typeof(string)) return true; return base.IsValid(context, value); } }

Add the TypeConverter attribute to our FilePath class to convert to and from a string.

[TypeConverter(typeof(FilePathConverter))] class FilePath { ... }

Now the property grid will display the string and not the type name, but you want the ellipsis to bring up a file selection dialog, so we make a UITypeEditor:

class FilePathEditor : UITypeEditor { public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return System.Drawing.Design.UITypeEditorEditStyle.Modal; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { FilePath path = (FilePath)value; OpenFileDialog openFile = new OpenFileDialog(); openFile.FileName = path.Path; if (openFile.ShowDialog() == DialogResult.OK) path.Path = openFile.FileName; return path; } }

Add the Editor attribute to our FilePath class to use the new class:

[TypeConverter(typeof(FilePathConverter))] [Editor(typeof(FilePathEditor), typeof(UITypeEditor))] class FilePath { ... }

Now you can add FilePath objects to your IDictionary and have them editable through the property grid

IDictionary d = new Dictionary<string, object>(); d["Path"] = new FilePath("C:/");

Recommend

  • How to load data to Hive table and make it also accessible in Impala
  • Click on line in canvas
  • HIVE Query returning null values after import data from local stored file
  • Python3 openpyxl Copying data from row that contains certain value to new sheet in existing workbook
  • FAILURE: Gradle Build failed with an exception
  • How do I know what reference to include to import a specific .NET namespace?
  • Google Player Game Service Error: Can't build the sample game
  • Return null in boolean to checkbox state converter in XAML
  • Gstreamer1.0 : link a decodebin to videoconvert
  • cordova is not defined - cordova.js has already been loaded :: Ionic
  • jQuery: add elements until a particular height is reached
  • Redshift Querying: error xx000 disk full redshift
  • Convert SQLite database to XML
  • Combining two different ActiveRecord collections into one
  • How to revert to previous XCode version?
  • Unable to install Git-core+svn by MacPorts
  • Django simple Captcha “No module named fields” error
  • How to use carriage return with multiple line?
  • Rails Find when some params will be blank
  • Could not find rake using whenever rails
  • Deselecting radio buttons while keeping the View Model in synch
  • script to move all files from one location to another location
  • ILMerge & Keep Assembly Name
  • Symfony2: How to get request parameter
  • How can I estimate amount of memory left with calling System.gc()?
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Run Powershell script from inside other Powershell script with dynamic redirection to file
  • Comma separated Values
  • Error creating VM instance in Google Compute Engine
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • JTable with a ScrollPane misbehaving
  • How do I configure my settings file to work with unit tests?
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • unknown Exception android
  • Binding checkboxes to object values in AngularJs
  • failed to connect to specific WiFi in android programmatically
  • How can I use threading to 'tick' a timer to be accessed by other threads?
  • How to load view controller without button in storyboard?