Xiaoyuvax
Xiaoyuvax

Reputation: 71

BinaryEditor class doesn't work for PropertyGrid control in .net 6 preview

[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]

Upvotes: 0

Views: 338

Answers (1)

Xiaoyuvax
Xiaoyuvax

Reputation: 71

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;

    }
}

Upvotes: 0

Related Questions