0

[Issue description] After an object is selected for PropertyGrid control to display and if user attempts to click and edit any of its Byte[] property, error message shown like below and supposed BinaryEditor not brought up:

Could not find the resource 'System.ComponentModel.Design.BinaryEditorresources" among the resources "System.Windows.Forms.Design.BorderSidesEditorresources" System.ComponentMode.Design.CollectionEditor.resources" System.Windows.Forms.Design.FormatControl.resources" System.Windows.Forms.Desiqn.LinkAreaEditorresources", System.Wingows.Forms.Desian.MaskDesignerDialog.resources" System.Wingows.Forms.Desian.ShortcutKevsEditorresources". System.SR.resources" System.Wingows.Forms.DesignStringCo ectionEditorresources". System.Windows.Forms.Design.Resources.System.ComponentMode.De sign.BinaryEditor.resources" 'System.Windows.Forms.Design.colordlg.data"... embedded in the assembly "System.Windows.Forms.Design nor among the resources in any satellite assemblies for the specified culture. Perhaps the resources were embedded with anincorrect name enter image description here

[Steps to reproduce] Add a PropertyGrid control to ur WinForm. Set the PropertyGrid.SelectedObject to an object with Byte[] type properties. Run the Form, and click on the Byte[] type property in the PropertyGrid, u see the error message.

[.NET version Info] Version: 6.0.400-preview.22301.10 Commit: 25580ffe7a

Host (useful for support): Version: 6.0.6 Commit: 7cca709db2

.NET SDKs installed: 6.0.301 [C:\Program Files\dotnet\sdk] 6.0.400-preview.22301.10 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

13
  • I see you have posted an issue related to the missing parts in the UITypeEditor implementation. Not all UITypeEditors / Editors are yet fully implemented (most notable, the Application Property Binding editors and interfaces). - You could present the byte[] content with a ByteViewer object. This class is used as the presenter in the BinaryViewer editor when the Hexadecimal view is selected. -- You have to create it in code, since the class is decorated with [ToolboxItem(false)] Commented Jun 27, 2022 at 19:27
  • but how can i make any already implemented editors(including custom editors coded myself) work with the PropertyGrid control? as the default editor for byte[] property,when user clicks? Commented Jun 28, 2022 at 2:56
  • Now I get it, EditorAttribute(), a usable workaround... Commented Jun 28, 2022 at 3:12
  • 1
    Exactly. You have to build your own UITypeEditor, override GetEditStyle() to return UITypeEditorEditStyle.Modal, override EditValue(), check first whether the Type of value is the Type you're expecting, then cast the IServiceProvider object to the desired service: e.g., var service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));. if service is not null, create a new Form that contains your interface, including the ByteViewer, pass value (cast to the Type you're handling) to its Constructor, show it as Modal Dialog and get the result Commented Jun 28, 2022 at 3:15
  • Well, the example of a custom UITypeEditor Class shown in the Docs, which uses a custom Form, is a decent one, you can us it as blueprint. Commented Jun 28, 2022 at 3:21

1 Answer 1

0

Workaround Explained

First Step, mark the property with either TypeConverterAttribute or EditorAttribute, or both.

    [TypeConverter(typeof(Hex2BinConverter)), Editor("MyWinFormApp.ByteArrayEditor, MyWinFormApp","System.Drawing.Design.UITypeEditor, System.Windows.Forms")]

Workaround 1: A simple solution by TypeConverter:

   public class Hex2BinConverter : 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 s && Utils.TryHex2Bytes(s, out byte[] bs)) return bs;  //TryHex2Bytes might be any method u wrote to convert hexstring to byte[]

            object r = null;
            try { r = base.ConvertFrom(context, culture, value); }
            catch { }
            return r;
        }

        public override object ConvertTo(ITypeDescriptorContext context,
           CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value is byte[] bs) return bs.ToHexString();  //ToHexString might be any method u wrote to convert byte[] to hexstring.
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

Workaround 2: A simple solution by custom UITypeEditor:

public class ByteArrayEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;

    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        TextBox txtBox = new TextBox();

        if (value is byte[] bs) txtBox.Text = bs.ToHexString();

        service.DropDownControl(txtBox);

        if (Utils.TryHex2Bytes(txtBox.Text, out byte[] bs1)) value = bs1;


        return value;

    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.