我正在尝试将WebBrowser控件的小扩展设置为HtmlTextBox,格式化的可能性有限。它适用于基本格式(粗体,斜体,下划线)。但我也想在一个单一级别允许缩进,理想情况下以“切换”方式调用它。
我注意到,当我运行Document.ExecCommand("Indent", False, Nothing)
时,它会将<p>
元素转换为<blockquote>
元素,这正是我需要的。但是对同一命令的第二次调用只会增加缩进余量,但是我想这样做,如果游标已经在<blockquote>
元素内,它将执行“outdent”。
为此,我尝试在执行操作之前查询Document.ActiveElement
,但这会返回整个<body>
元素,而不是当时光标所在的特定块元素。
我怎么能做到这一点?
这是我的代码:
Public Class HtmlTextBox
Inherits WebBrowser
Public Sub New()
WebBrowserShortcutsEnabled = False
IsWebBrowserContextMenuEnabled = False
DocumentText = "<html><body></body></html>"
If Document IsNot Nothing Then
Dim doc = Document.DomDocument
If doc IsNot Nothing Then
doc.designMode = "On"
If Me.ContextMenuStrip Is Nothing Then
AddHandler Document.ContextMenuShowing, Sub(sender As Object, e As HtmlElementEventArgs) Application.DoEvents()
End If
End If
End If
End Sub
Private Sub HtmlTextBox_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles Me.PreviewKeyDown
If e.Control Then
If e.KeyData.HasFlag(Keys.B) OrElse e.KeyData.HasFlag(Keys.N) Then BoldToggle()
If e.KeyData.HasFlag(Keys.I) Then ItalicToggle()
If e.KeyData.HasFlag(Keys.S) OrElse e.KeyData.HasFlag(Keys.U) Then UnderlineToggle()
If e.KeyData.HasFlag(Keys.M) Then BlockQuoteToggle()
End If
End Sub
Public Sub BoldToggle()
Document.ExecCommand("Bold", False, Nothing)
End Sub
Public Sub ItalicToggle()
Document.ExecCommand("Italic", False, Nothing)
End Sub
Public Sub UnderlineToggle()
Document.ExecCommand("Underline", False, Nothing)
End Sub
Public Sub BlockQuoteToggle()
If Document.ActiveElement.TagName.ToLower = "blockquote" Then
Document.ExecCommand("Outdent", False, Nothing)
Else
Document.ExecCommand("Indent", False, Nothing)
End If
End Sub
End Class
答案 0 :(得分:1)
方法ElementAtSelectionStart
旨在返回包含当前选择开头的元素。此代码用于编辑模式下的WebBrowser控件。希望它能满足您的需求。
Public Class mshtmlUtilities
Public Enum C_Bool
[False] = 0
[True] = 1
End Enum
Public Shared Function ElementAtSelectionStart(ByVal wb As System.Windows.Forms.WebBrowser) As System.Windows.Forms.HtmlElement
Dim el As System.Windows.Forms.HtmlElement = Nothing
If wb IsNot Nothing AndAlso _
wb.Document IsNot Nothing AndAlso _
DirectCast(wb.Document.DomDocument, mshtml.IHTMLDocument2).designMode.Equals("on", StringComparison.InvariantCultureIgnoreCase) Then
Dim doc As mshtml.IHTMLDocument2 = DirectCast(wb.Document.DomDocument, mshtml.IHTMLDocument2)
Dim sel As mshtml.IHTMLSelectionObject = DirectCast(doc.selection, mshtml.IHTMLSelectionObject)
Select Case sel.type.ToLowerInvariant
Case "text"
Dim rng As mshtml.IHTMLTxtRange = DirectCast(sel.createRange(), mshtml.IHTMLTxtRange)
rng.collapse(True)
el = MakeWinFormHTMLElement(rng.parentElement, wb)
Case "control"
Dim rng As mshtml.IHTMLControlRange = DirectCast(sel.createRange(), mshtml.IHTMLControlRange)
el = MakeWinFormHTMLElement(rng.item(0).parentElement, wb)
Case "none"
Dim ds As mshtml.IDisplayServices = DirectCast(doc, mshtml.IDisplayServices)
Dim caret As mshtml.IHTMLCaret = Nothing
ds.GetCaret(caret)
Dim pt As mshtml.tagPOINT
caret.GetLocation(pt, C_Bool.False)
el = wb.Document.GetElementFromPoint(New Point(pt.x, pt.y))
End Select
End If
Return el
End Function
Private Shared Function MakeWinFormHTMLElement(ByVal el As mshtml.IHTMLElement, ByVal wb As System.Windows.Forms.WebBrowser) As System.Windows.Forms.HtmlElement
Dim shimInfo As Reflection.PropertyInfo = wb.GetType.GetProperty("ShimManager", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
Dim shimManager As Object = shimInfo.GetValue(wb, Nothing)
Dim ciElement As Reflection.ConstructorInfo() _
= wb.Document.Body.GetType().GetConstructors(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
Return CType(ciElement(0).Invoke(New Object() {shimManager, el}), HtmlElement)
End Function
End Class