ElementHost WPF TextBox

这个例子是在我在互联网上找到的一个例子之后建模的。我找不到链接或者我会给作者信用。我拿了我找到的样本并将其修改为我的应用程序。

  1. 添加以下参考:

System.Xaml,PresentationCore,PresentationFramework,WindowsBase 和 WindowsFormsIntegration

  1. 创建一个新类并通过此代码

    Imports System
    Imports System.ComponentModel
    Imports System.ComponentModel.Design.Serialization
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Forms.Integration    
    Imports System.Windows.Forms.Design
    
    <Designer(GetType(ControlDesigner))> _
    Class SpellCheckBox
    Inherits ElementHost
    
    Private box As TextBox
    
    Public Sub New()
        box = New TextBox()
        MyBase.Child = box
        AddHandler box.TextChanged, AddressOf box_TextChanged
        box.SpellCheck.IsEnabled = True
        box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto
        Me.Size = New System.Drawing.Size(100, 20)
    End Sub
    
    Private Sub box_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
        OnTextChanged(EventArgs.Empty)
    End Sub
    
    <DefaultValue("")> _
    Public Overrides Property Text() As String
        Get
            Return box.Text
        End Get
        Set(ByVal value As String)
            box.Text = value
        End Set
    End Property
    
    <DefaultValue(True)> _
    Public Property MultiLine() As Boolean
        Get
            Return box.AcceptsReturn
        End Get
        Set(ByVal value As Boolean)
            box.AcceptsReturn = value
        End Set
    End Property
    
    <DefaultValue(True)> _
    Public Property WordWrap() As Boolean
        Get
            Return box.TextWrapping <> TextWrapping.Wrap
        End Get
        Set(ByVal value As Boolean)
            If value Then
                box.TextWrapping = TextWrapping.Wrap
            Else
                box.TextWrapping = TextWrapping.NoWrap
            End If
        End Set
    End Property
    
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
    Public Shadows Property Child() As System.Windows.UIElement
        Get
            Return MyBase.Child
        End Get
        Set(ByVal value As System.Windows.UIElement)
            '' Do nothing to solve a problem with the serializer !!
        End Set
    End Property
    
    End Class
    
  2. 重建解决方案。

  3. 添加新表单。

  4. 在工具箱中搜索你的类名称。这个例子是拼写检查。它应该列在’YourSoulutionName’组件下。

  5. 将新控件拖到窗体中

  6. 在窗体加载事件中设置任何映射属性

Private Sub form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    spellcheckbox.WordWrap = True
    spellcheckbox.MultiLin = True
    'Add any other property modifiers here...
End Sub
  1. 你需要做的最后一件事是更改应用程序的 DPI 意识。这是因为你使用的是 WinForms 应用程序。默认情况下,所有 WinForms 应用程序都是 DPI UNAWARE。一旦执行具有元素主机(WPF Interop)的控件,应用程序现在将成为 DPI AWARE。这可能会或可能不会弄乱你的 UI 元素。解决方案是强制应用程序成为 DPI UNAWARE。有两种方法可以做到这一点。第一个是通过清单文件,第二个是硬编码到你的程序。如果你使用 OneClick 部署应用程序,则必须对其进行硬编码,而不是使用清单文件或错误将是不可避免的。

以下两个示例都可以在以下示例中找到: WinForms 在大 DPI 设置下进行扩展 - 它是否可能? 感谢 Telerik.com 对 DPI 的精彩解释。

硬编码 DPI Aware 代码示例。这必须在初始化第一个表单之前执行。我总是把它放在 ApplicationEvents.vb 文件中。你可以通过右键单击解决方案资源管理器中的项目名称并选择打开来访问此文件。然后选择左侧的应用程序选项卡,然后单击启动屏幕下拉列表右下角的查看应用程序事件

Namespace My

    ' The following events are available for MyApplication:
    ' 
    ' Startup: Raised when the application starts, before the startup form is created.
    ' Shutdown: Raised after all application forms are closed.  This event is not raised if the application terminates abnormally.
    ' UnhandledException: Raised if the application encounters an unhandled exception.
    ' StartupNextInstance: Raised when launching a single-instance application and the application is already active. 
    ' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
    Partial Friend Class MyApplication
    
    Private Enum PROCESS_DPI_AWARENESS
        Process_DPI_Unaware = 0
        Process_System_DPI_Aware = 1
        Process_Per_Monitor_DPI_Aware = 2
    End Enum

    Private Declare Function SetProcessDpiAwareness Lib "shcore.dll" (ByVal Value As PROCESS_DPI_AWARENESS) As Long

    Private Sub SetDPI()
        'Results from SetProcessDPIAwareness
        'Const S_OK = &H0&
        'Const E_INVALIDARG = &H80070057
        'Const E_ACCESSDENIED = &H80070005

        Dim lngResult As Long

        lngResult = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware)

    End Sub

    Private Sub MyApplication_Startup(sender As Object, e As ApplicationServices.StartupEventArgs) Handles Me.Startup
        SetDPI()
    End Sub

End Namespace

清单示例

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
   <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
             <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
   </asmv3:application>
</assembly>