问题描述
如何在保持该控件的所有其他属性可用的情况下仅覆盖控件的一个EditValue函数?当我将单个控件分配给PropertyGrid的Selectedobject属性时,我将获得控件的所有属性。为了覆盖一个属性,我想创建一个属性包装器类,该类将向我展示所有控件,包括自定义EditValue函数。但是我发现必须在包装类中定义所有属性,否则只能通过自定义EditValue函数查看该属性。这似乎非常不切实际,必须有一种更简单的方法。 我需要这样做,因为我想捕获用户可以指定的BackgroundImage的文件名。 捕获名称的代码很好用,在这里是很好的措施:
const mockSendEmail = jest.fn(() => {
return {
promise() {
return Promise.resolve('mock response');
}
};
});
jest.mock('aws-sdk',() => {
return {
SES: jest.fn(() => ({
sendEmail: mockSendEmail
})),config: {
update: jest.fn()
}
};
});
_Form在包装类FormPropertiesWrapper中声明为Form
解决方法
PropertyGrid使用组件的TypeDescriptor来确定通过TypeDescriptor.GetProperties Method在网格中显示的内容。您可以创建一个派生自CustomTypeDescriptor Class的包装类,并重写GetProperties方法以提供一个新的PropertyDescriptor,其中包括指向您的CatchFileName
类的EditorAttribute。
我修改了您的CatchFileName
类,使其与需要在包装控件中实现的名为IBackgroundImageName
的接口配合工作。该包装器将与实现BackgroundImageProxyWrapper.IBackgroundImageName
的任何控件一起使用。这样,图像名称将存储在控件中而不是包装器中。
Imports System.ComponentModel
Imports System.Drawing.Design
Imports System.IO
Friend Class BackgroundImageProxyWrapper : Inherits CustomTypeDescriptor
Private Sub New(source As IBackgroundImageName)
MyBase.New(TypeDescriptor.GetProvider(source).GetTypeDescriptor(source))
SourceControl = source
End Sub
Public Shared Function Wrap(Of T As {Control,IBackgroundImageName})(source As T) As BackgroundImageProxyWrapper
Return New BackgroundImageProxyWrapper(source)
End Function
Public ReadOnly Property SourceControl As IBackgroundImageName
Public Overrides Function GetProperties() As PropertyDescriptorCollection
Return GetProperties(Nothing)
End Function
Public Overrides Function GetProperties(attributes() As Attribute) As PropertyDescriptorCollection
Dim ret As PropertyDescriptorCollection
ret = New PropertyDescriptorCollection(New PropertyDescriptor() {},False)
For Each pd As PropertyDescriptor In MyBase.GetProperties(attributes)
If pd.Name.Equals("BackgroundImage") Then
' substitute a PropertyDescriptor that includes the EditorAttribute
Dim attribs As New List(Of Attribute)(pd.Attributes.Count + 1)
Dim editorType As Type = GetType(EditorAttribute)
' 1st remove any previous editor attribute
For Each attrib As Attribute In pd.Attributes
If attrib.GetType IsNot editorType Then
attribs.Add(attrib)
End If
Next
attribs.Add(New EditorAttribute(GetType(CatchFileName),GetType(UITypeEditor)))
pd = TypeDescriptor.CreateProperty(pd.ComponentType,pd,attribs.ToArray())
End If
ret.Add(pd)
Next
Return ret
End Function
Private Class CatchFileName : Inherits UITypeEditor
Public Overrides Function GetEditStyle(context As ITypeDescriptorContext) As UITypeEditorEditStyle
Return UITypeEditorEditStyle.Modal
End Function
Public Overrides Function EditValue(context As ITypeDescriptorContext,provider As IServiceProvider,value As Object) As Object
Dim ofd As New OpenFileDialog() With {.Filter = "Image Files|*.bmp;*.jpg;*.jpeg,*.gif;*.png;*.ewf;*.wmf;*.ico"}
If (ofd.ShowDialog() = DialogResult.OK) Then
DirectCast(context.Instance,BackgroundImageProxyWrapper).SourceControl.BackgroundImageName =
Path.GetFileName(ofd.FileName) ' Strip path
Return Image.FromFile(ofd.FileName)
End If
Return MyBase.EditValue(context,provider,value)
End Function
End Class
Public Interface IBackgroundImageName
Property BackgroundImageName As String
End Interface
End Class
示例用法:
Public Class Form1
Implements BackgroundImageProxyWrapper.IBackgroundImageName
Private Property BackgroundImageName As String Implements BackgroundImageProxyWrapper.IBackgroundImageName.BackgroundImageName
Private Sub BtnSetForm_Click(sender As Object,e As EventArgs) Handles BtnSetForm.Click
PropertyGrid1.SelectedObject = BackgroundImageProxyWrapper.Wrap(Me)
End Sub
End Class
编辑::适用于任何控件的更通用的版本。文件名存储在控件的Tag属性中。
Friend Class BackgroundImageProxyWrapper : Inherits CustomTypeDescriptor
Public Sub New(source As Control)
MyBase.New(TypeDescriptor.GetProvider(source).GetTypeDescriptor(source))
SourceControl = source
End Sub
Public ReadOnly Property SourceControl As Control
Public Overrides Function GetProperties() As PropertyDescriptorCollection
Return GetProperties(Nothing)
End Function
Public Overrides Function GetProperties(attributes() As Attribute) As PropertyDescriptorCollection
Dim ret As PropertyDescriptorCollection
ret = New PropertyDescriptorCollection(New PropertyDescriptor() {},BackgroundImageProxyWrapper).SourceControl.Tag =
Path.GetFileName(ofd.FileName) ' Strip path
Return Image.FromFile(ofd.FileName)
End If
Return MyBase.EditValue(context,value)
End Function
End Class
End Class