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>