如何:更改托管 HTML 文档对象模型中元素的样式

可以使用 HTML 中的样式来控制文档及其元素的外观。 HtmlDocumentHtmlElement支持Style属性,其样式字符串采用以下格式:

name1:value1;...;nameN:valueN;

下面是一个 DIV 样式字符串,用于将字体设置为 Arial,并将所有文本设置为粗体:

<DIV style="font-face:arial;font-weight:bold;">
Hello, world!
</DIV>

使用 Style 属性操控样式的问题在于,向字符串中添加或删除具体的样式设置可能会显得麻烦。 例如,用户将光标置于DIV时,会触发一个复杂的过程,将前一个文本呈现为斜体;当光标离开DIV时,斜体格式将取消。 如果需要以这种方式处理大量样式,时间可能会成为一个问题。

以下步骤包含可用于轻松处理 HTML 文档和元素样式的代码。 该过程要求你知道如何在 Windows 窗体中执行基本任务,例如创建新项目并将控件添加到窗体。

处理 Windows 窗体应用程序中的样式更改

  1. 创建新的 Windows 窗体项目。

  2. 创建以适合编程语言的扩展结尾的新类文件。

  3. StyleGenerator 本主题的“示例”部分中的类代码复制到类文件中,并保存代码。

  4. 将以下 HTML 保存到名为 Test.htm的文件。

    <HTML>
        <BODY>
    
            <DIV style="font-face:arial;font-weight:bold;">
                Hello, world!
            </DIV><P>
    
            <DIV>
                Hello again, world!
            </DIV><P>
    
        </BODY>
    </HTML>
    
  5. 在您的项目主窗体中添加一个名为WebBrowserwebBrowser1的控件。

  6. 将以下代码添加到项目的代码文件中。

    重要

    确保 webBrowser1_DocumentCompleted 事件处理程序配置为 DocumentCompleted 事件的侦听器。 在 Visual Studio 中,双击控件 WebBrowser ;在文本编辑器中,以编程方式配置侦听器。

    StyleGenerator sg = null;
    HtmlElement elem = null;
    
    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        sg = new StyleGenerator();
    
        webBrowser1.Document.MouseOver += new HtmlElementEventHandler(Document_MouseOver);
        webBrowser1.Document.MouseLeave += new HtmlElementEventHandler(Document_MouseLeave);
    }
    
    void Document_MouseOver(object sender, HtmlElementEventArgs e)
    {
        elem = webBrowser1.Document.GetElementFromPoint(e.MousePosition);
        if (elem.TagName.Equals("DIV"))
        {
            sg.ParseStyleString(elem.Style);
            sg.SetStyle("font-style", "italic");
            elem.Style = sg.GetStyleString();
        }
    }
    
    void Document_MouseLeave(object sender, HtmlElementEventArgs e)
    {
        if (elem != null)
        {
            sg.RemoveStyle("font-style");
            elem.Style = sg.GetStyleString();
            // Reset, since we may mouse over a new DIV element next time.
            sg.Clear();
        }
    }
    
    Public Class Form1
    
        Dim SG As StyleGenerator = Nothing
        Dim Elem As HtmlElement = Nothing
        Dim WithEvents DocumentEvents As HtmlDocument
    
        Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
            SG = New StyleGenerator()
            DocumentEvents = WebBrowser1.Document
        End Sub
    
        Private Sub Document_MouseOver(ByVal sender As Object, ByVal e As HtmlElementEventArgs) Handles DocumentEvents.MouseOver
            Elem = WebBrowser1.Document.GetElementFromPoint(e.MousePosition)
            If Elem.TagName.Equals("DIV") Then
                SG.ParseStyleString(Elem.Style)
                SG.SetStyle("font-style", "italic")
                Elem.Style = SG.GetStyleString()
            End If
        End Sub
    
        Private Sub Document_MouseLeave(ByVal sender As Object, ByVal e As HtmlElementEventArgs) Handles DocumentEvents.MouseLeave
            If (Elem IsNot Nothing) Then
                SG.RemoveStyle("font-style")
                Elem.Style = SG.GetStyleString()
                ' Reset, since we may mouse over a new DIV element next time.
                SG.Clear()
            End If
        End Sub
    End Class
    
  7. 启动项目。 在第一个 DIV 上方运行光标,观察代码的效果。

示例:

下面的代码示例演示了该类的完整代码 StyleGenerator ,该类分析现有样式值,支持添加、更改和删除样式,并返回具有所请求更改的新样式值。

using System;
using System.Collections.Generic;
using System.Text;

namespace ManagedDOMStyles
{
    public class StyleGenerator
    {
        private Dictionary<string, string> styleDB;

        public StyleGenerator()
        {
            styleDB = new Dictionary<string, string>();
        }

        public bool ContainsStyle(string name)
        {
            return(styleDB.ContainsKey(name));
        }

        public string SetStyle(string name, string value)
        {
            string oldValue = "";

            if (!(name.Length > 0))
            {
                throw (new ArgumentException("Parameter name cannot be zero-length."));
            }
            if (!(value.Length > 0))
            {
                throw (new ArgumentException("Parameter value cannot be zero-length."));
            }

            if (styleDB.ContainsKey(name))
            {
                oldValue = styleDB[name];
            }

            styleDB[name] = value;

            return (oldValue);
        }

        public string GetStyle(string name)
        {
            if (!(name.Length > 0))
            {
                throw (new ArgumentException("Parameter name cannot be zero-length."));
            }

            if (styleDB.ContainsKey(name))
            {
                return (styleDB[name]);
            }
            else
            {
                return ("");
            }
        }

        public void RemoveStyle(string name)
        {
            if (styleDB.ContainsKey(name))
            {
                styleDB.Remove(name);
            }
        }

        public string GetStyleString()
        {
            if (styleDB.Count > 0)
            {
                StringBuilder styleString = new StringBuilder("");
                foreach (string key in styleDB.Keys)
                {
                    styleString.Append(String.Format("{0}:{1};", (object)key, (object)styleDB[key]));
                }

                return (styleString.ToString());
            }
            else
            {
                return ("");
            }
        }

        public void ParseStyleString(string styles)
        {
            if (styles.Length > 0)
            {
                string[] stylePairs = styles.Split(new char[] { ';' });
                foreach(string stylePair in stylePairs)
                {
                    if (stylePairs.Length > 0)
                    {
                        string[] styleNameValue = stylePair.Split(new char[] { ':' });
                        if (styleNameValue.Length == 2)
                        {
                            styleDB[styleNameValue[0]] = styleNameValue[1];
                        }
                    }
                }
            }
        }

        public void Clear()
        {
            styleDB.Clear();
        }
    }
}
Imports System.Collections.Generic
Imports System.Text

Public Class StyleGenerator
    Dim styleDB As Dictionary(Of String, String)

    Public Sub New()
        styleDB = New Dictionary(Of String, String)()
    End Sub


    Public Function ContainsStyle(ByVal name As String) As Boolean
        Return styleDB.ContainsKey(name)
    End Function


    Public Function SetStyle(ByVal name As String, ByVal value As String) As String
        Dim oldValue As String = ""

        If (Not name.Length > 0) Then
            Throw New ArgumentException("Parameter name cannot be zero-length.")
        End If
        If (Not value.Length > 0) Then
            Throw New ArgumentException("Parameter value cannot be zero-length.")
        End If

        If (styleDB.ContainsKey(name)) Then
            oldValue = styleDB(name)
        End If

        styleDB(name) = value

        Return oldValue
    End Function

    Public Function GetStyle(ByVal name As String) As String
        If (Not name.Length > 0) Then
            Throw New ArgumentException("Parameter name cannot be zero-length.")
        End If

        If (styleDB.ContainsKey(name)) Then
            Return styleDB(name)
        Else
            Return ""
        End If
    End Function

    Public Sub RemoveStyle(ByVal name As String)
        If (styleDB.ContainsKey(name)) Then
            styleDB.Remove(name)
        End If
    End Sub

    Public Function GetStyleString() As String
        If (styleDB.Count > 0) Then
            Dim styleString As New StringBuilder("")
            Dim key As String
            For Each key In styleDB.Keys
                styleString.Append(String.Format("{0}:{1};", CType(key, Object), CType(styleDB(key), Object)))
            Next key

            Return styleString.ToString()
        Else
            Return ""
        End If
    End Function

    Public Sub ParseStyleString(ByVal styles As String)
        If (styles.Length) > 0 Then
            Dim stylePairs As String() = styles.Split(New Char() {";"c})
            Dim stylePair As String
            For Each stylePair In stylePairs
                If (stylePairs.Length > 0) Then
                    Dim styleNameValue As String() = stylePair.Split(New Char() {":"c})
                    If (styleNameValue.Length = 2) Then
                        styleDB(styleNameValue(0)) = styleNameValue(1)
                    End If
                End If
            Next stylePair
        End If
    End Sub


    Public Sub Clear()
        styleDB.Clear()
    End Sub
End Class

另请参阅