【问题标题】:Error open "Edit Columns" when click property in UserControl在用户控件中单击属性时打开“编辑列”时出错
【发布时间】:2020-05-23 08:37:16
【问题描述】:

VB.Net

我有一个带有 Dgv1(DataGridView) 的 UserControl

我想用“编辑列”表单编辑设计中的列

鳕鱼用户控制:

Public Class MyUserControl
    Inherits UserControl


    <Editor(GetType(MyColumnEditor), GetType(UITypeEditor))> _
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    Public ReadOnly Property Columns() As DataGridViewColumnCollection
        Get
            Return Me.Dgv1.Columns

        End Get
    End Property


End Class

MyColumnEditor:

Public Class MyColumnEditor
    Inherits System.Drawing.Design.UITypeEditor

    Public Overrides Function GetEditStyle(context As ITypeDescriptorContext) As UITypeEditorEditStyle
        Return UITypeEditorEditStyle.Modal
    End Function

    Public Overloads Overrides Function EditValue(context As ITypeDescriptorContext, provider As IServiceProvider, value As Object) As Object

        Dim field As Object = context.Instance.[GetType]().GetField("Dgv1", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)

        Dim dataGridView1 = CType(field.GetValue(context.Instance), DataGridView)
        dataGridView1.Site = CType(context.Instance, Control).Site
        Dim columnsProperty As Object = TypeDescriptor.GetProperties(dataGridView1)("Columns")
        Dim tdc As Object = New TypeDescriptionContext(dataGridView1, columnsProperty)
        Dim editor = CType(columnsProperty.GetEditor(GetType(UITypeEditor)), UITypeEditor)
        Dim result As Object = editor.EditValue(tdc, provider, value)
        dataGridView1.Site = Nothing
        Return result

    End Function
End Class

TypeDescriptionContext:

Public Class TypeDescriptionContext
    Implements ITypeDescriptorContext

    Public editingObject As Control
    Public editingProperty As PropertyDescriptor
    Public Sub New(obj As Control, property1 As PropertyDescriptor)
        editingObject = obj
        editingProperty = property1
    End Sub

    Public ReadOnly Property Container As IContainer Implements ITypeDescriptorContext.Container
        Get
            Return editingObject.Container
        End Get
    End Property

    Public ReadOnly Property Instance As Object Implements ITypeDescriptorContext.Instance
        Get
            Return editingObject

        End Get
    End Property

    Public Sub OnComponentChanged() Implements ITypeDescriptorContext.OnComponentChanged

    End Sub

    Public Function OnComponentChanging() As Boolean Implements ITypeDescriptorContext.OnComponentChanging
        Return True

    End Function

    Public ReadOnly Property PropertyDescriptor As PropertyDescriptor Implements ITypeDescriptorContext.PropertyDescriptor
        Get
            Return editingProperty
        End Get
    End Property

    Public Function GetService(serviceType As Type) As Object Implements IServiceProvider.GetService
        Return editingObject.Site.GetService(serviceType)
    End Function
End Class

但是当单击列属性进行编辑时显示错误: 未设置对象变量或 With 块变量。

https://i.stack.imgur.com/rkeua.jpg

C#中相同的代码:,运行正常

用户控制:

public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
        }

        [Editor(typeof(MyColumnEditor), typeof(UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public DataGridViewColumnCollection Columns
        {
            get { return this.Dgv1.Columns; }
        }
    }

MyColumnEditor:

public class MyColumnEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
        public override object EditValue(ITypeDescriptorContext context,
                                         IServiceProvider provider, object value)
        {
            var field = context.Instance.GetType().GetField("Dgv1",
                           System.Reflection.BindingFlags.NonPublic |
                           System.Reflection.BindingFlags.Instance);

            var dataGridView1 = (DataGridView)field.GetValue(context.Instance);
            dataGridView1.Site = ((Control)context.Instance).Site;
            var columnsProperty = TypeDescriptor.GetProperties(dataGridView1)["Columns"];
            var tdc = new TypeDescriptionContext(dataGridView1, columnsProperty);
            var editor = (UITypeEditor)columnsProperty.GetEditor(typeof(UITypeEditor));
            var result = editor.EditValue(tdc, provider, value);
            dataGridView1.Site = null;
            return result;
        }
    }

TypeDescriptionContext:

public class TypeDescriptionContext : ITypeDescriptorContext
    {
        private Control editingObject;
        private PropertyDescriptor editingProperty;
        public TypeDescriptionContext(Control obj, PropertyDescriptor property)
        {
            editingObject = obj;
            editingProperty = property;
        }
        public IContainer Container
        {
            get { return editingObject.Container; }
        }
        public object Instance
        {
            get { return editingObject; }
        }
        public void OnComponentChanged()
        {
        }
        public bool OnComponentChanging()
        {
            return true;
        }
        public PropertyDescriptor PropertyDescriptor
        {
            get { return editingProperty; }
        }
        public object GetService(Type serviceType)
        {
            return editingObject.Site.GetService(serviceType);
        }
    }

我知道 Vb.net 而不是专业人士 并将此代码 C# 转换为 VB.net

问题出在哪里? 提前感谢您的帮助

【问题讨论】:

  • 为什么需要转换它?绝大多数 .NET Framework 都是用 C# 编写的,您对此没有任何问题。为什么不直接将 C# 代码编译成 DLL 并像使用任何其他库一样使用它?
  • 将所有... As Object 替换为Dim tdc = New TypeDescriptionContext(dataGridView1, columnsProperty)。这些不是(所有)对象类型,例如,tdcTypeDescriptionContext。有些转换器,当找到var something = somethingelse;时,转换为Dim something As Object = somethingelse,这是错误的。无论如何,我会考虑 @jmcilhinney 告诉你的内容。

标签: vb.net datagridview uitypeeditor


【解决方案1】:

我发现了问题

在 VB.Net 中将 Datagridview 添加到 Designer Cod 中的 UserControl 时定义有:

Friend WithEvents Dgv1 As System.Windows.Forms.DataGridView

没错

Private Dgv1 As System.Windows.Forms.DataGridView

不应该是这样的

Private WithEvents Dgv1 As System.Windows.Forms.DataGridView

太惨了

我决定转向 C#

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2013-01-22
    相关资源
    最近更新 更多