65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C# 的 Web 浏览器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (14投票s)

2010年3月21日

CPOL

9分钟阅读

viewsIcon

67111

downloadIcon

4189

面向初学者设计的 Web 浏览器新功能。

引言

在我第二篇文章中,我介绍了更多内容。随着我学习 C#,一切都进展得很顺利。我希望我的代码能对您有所帮助,您可以在一些修改后将其应用到您自己的解决方案中。毕竟,当你修改别人的代码时,你会学得更快(我相信)。

这个程序叫做“WebPlus-V01”。我知道市面上有很多功能齐全的 Web 浏览器,但我希望添加一些我以前没见过的新功能……我会尽可能深入 C# 代码,并告诉您程序的大部分功能。请随时下载并试用代码。我非常好奇,如果您选择对其进行增强,您们还会做些什么(我非常想知道)。

WebPlus 的功能

  • 闹钟计时器:您是否曾经在浏览 Internet 时遇到过问题,不知道自己已经上网多久了,忘记了重要的会议或其他事情?嗯……再也不会了。使用 WebPlus 的计时器,最多可设置 2 小时,提醒自己重要的会议,在阅读喜欢的博客时不必担心时间的流逝:)
  • 黑屏:我总是厌烦一些人偷看我的肩膀,想知道我在做什么或在网上做什么。所以,如果你想让那些烦人的眼睛远离你的网站,只需将你的页面和地址栏黑屏,然后转过身说:“你想问我点什么吗?”而无需关闭浏览器。
  • 您最喜欢的网站记事本:每个书签还可以包含笔记。这是可选的。如果你看到什么有趣的东西,你可以随时记下笔记。
  • 转换工具:下次当您浏览网站时,想知道 45 公里相当于多少英里,可以使用浏览器附带的工具。
  • 书签文件夹:您随时可以创建单独的书签文件夹,并在列表中仅显示选定的收藏夹。再也不用点击树形结构了;)

尽情享受 :)

背景

我的第一篇文章的主题是一个名为“代码数据库”的小程序。我每天都使用它。我只想要程序的一个功能,就是保存我的代码。我使用 XML 文件作为数据库,因为我在使用 MS Jet 引擎时遇到了一些问题。我还提到我曾尝试为该程序使用 SQL Express,但最终还是选择了 XML。这次我使用的是 SQL Express 数据库。此代码中的所有内容都是动态的,没有任何内容绑定到数据库。这是我的一个旧习惯,我不喜欢通过绑定工具自动化事物。原因?因为这样我就可以更好地控制事物;否则,如果出现故障,代码会走向一个方向,数据库走向另一个方向,彼此撕裂。

使用代码

此程序包含两个窗体文件和一个自定义文件。自定义文件包含两个类。它们之间没有继承关系,并且具有单独的类和职责。我有时会对我的类进行一些工作,使其更紧凑。例如,使用多功能构造函数 :)

  • Form1(主窗体)
  • 窗体设置
  • work.cs(包含 ETWork 类和 DBConn 类。正如您将在代码中看到的,ETWork 类根据传递的参数执行两个不同的操作。)

SQL Express 数据库包含三个表

  • 文件夹
  • 设置
  • UrlPath

Folder 存储书签的文件夹名称。Settings 存储浏览器选项和其他有用信息。UrlPath 存储带有额外数据(笔记)的书签。

让我们从一些我非常想分享的东西开始。我的代码缩进!是的,这不是本文的重点,尽管这是我想首先告诉大家的内容。

以下代码示例是相同的。我使用看起来更紧凑的代码。这样我的行数就会大大减少,而且在查看花括号时也不会伤眼。

try { Conn1.Open();
    MyCommand.ExecuteNonQuery();
    Conn1.Close(); }
catch (Exception exc) {
    throw exc; }
finally {
    Conn1.Close(); }

-----------------------------------

try
{
    Conn1.Open();
    MyCommand.ExecuteNonQuery();
    Conn1.Close();
}
catch (Exception exc)
{
    throw exc;
}
finally
{
    Conn1.Close();
}

我不会要求每个人都这样编码,这需要练习和自律。即使 VS 为我缩进代码,当我有时间时,我也会组织它们(对我来说,这是一种很好的通过代码一次的工作练习)。

好了,我想现在与您分享一些其他代码。您随时可以下载并自行查看完整代码。

以下代码是我 Web 浏览器中使用的搜索引擎的代码。您可以看到如何使用一个带有多个“case”语句的“switch”语句来实现一个解决方案,以及 Text 类的 ToLower 属性。“ToLower”在 VB 中与“LCase”相同,它将文本中的每个字符转换为“小写”。

switch (clsDB.SEARCH_ENGINE)
{
    case "Yahoo":
        CurrentSearchEngine = "search." + 
          clsDB.SEARCH_ENGINE.ToLower() + ".com//search?p=";
        break;
    case "Google":
    case "Search":
    case "Bing":
        CurrentSearchEngine = "www." + 
          clsDB.SEARCH_ENGINE.ToLower() + ".com//search?q=";
        break;
    case "Lycos":
        CurrentSearchEngine = "search." + 
          clsDB.SEARCH_ENGINE.ToLower() + ".com/?tab=web&query=";
        break;
}

C# 不允许我们使用数字作为变量的起始字符。所以我使用下划线,这实际上看起来更好 ;)

private void ClearAlarmCheckBoxes()
{
    _5min.Checked = false;
    _15min.Checked = false;
    _30min.Checked = false;
    _1hr.Checked = false;
    _1nHalfHr.Checked = false;
    _2hr.Checked = false;
}

这是格式化数字的示例。我使用它来格式化转换实用程序的返回结果“lblResult.Text = String.Format("{0:0,0.0}"

我创建的转换实用程序转换三种系统。千克到磅、摄氏度到华氏度、公里到英里(反之亦然)。

switch (XSelection)
{
    case 1:
        ResY = ConversionNumber * 1609.344;
        break;
    case 2:
        ResY = ConversionNumber * 0.621;
        break;
    case 3:
        ResY = (5.00 / 9.00) * (ConversionNumber - 32);
        break;
    case 4:
        ResY = (9.00 / 5.00) * ConversionNumber + 32;
        break;
    case 5:
        ResY = ConversionNumber * 0.4535;
        break;
    case 6:
        ResY = ConversionNumber * 2.2046;
        break;
}
_ConvertedNumber = ResY; // Set the result

您可以看到“_ConvertedNumber”也有一个下划线。因为这段代码位于一个类中,而它是一个字段。我(尽量)用下划线开头命名我所有的字段,以便更好地识别它们。情况 1 和 2 用于长度,3 和 4 用于温度,最后两个用于重量。

有很多像这样的注释:"clsDB = new DBConn(); // 创建 'DBConn' 类的实例",我想强调理解“OOP”的“概念”有多么重要。这一切都是关于创建一个可用的代码副本(对象)。

让我们看一些数据库代码。

我希望我的数据库代码完成四项主要任务。输入新数据:“INSERT INTO table (...) VALUES(..)”。第二,修改数据:“UPDATE table SET field = value, ...”,然后删除数据:“DELETE FROM table..”,最后,请求数据:“SELECT fields FROM table”。

虽然这些是四大主要功能,但还有其他您可能需要处理的事情,例如“将表和/或数据库连接成一个字符串”、“创建数据库和表”等等。它们并不容易,但熟能生巧。在这个代码中我没有使用“JOIN”,但我过去曾多次使用过它们。在大多数数据库情况下,查询看起来都一样,只是从一个到另一个有一些小的调整。

输入新数据

public void NewBookmark(int FolderID, string BookMarkName, string BookMarkUrl)
{
    // Create new bookmark
    CommaCheck(BookMarkName); // Cleanup commas
    Conn1 = new SqlConnection(connStr); // Create an instance of 'SqlConnection' class

    SqlCommand MyCommand = Conn1.CreateCommand(); // Create an instance of 'SqlCommand' class
    MyCommand.CommandText = "INSERT INTO UrlPath (FolderID, CustomName, FullUrlPath) VALUES ("
                         + FolderID + ", '" + BookMarkName + 
                         "', '" + BookMarkUrl + "')";
    try {
        Conn1.Open(); MyCommand.ExecuteNonQuery();
        Conn1.Close(); }
    catch (Exception exc) {
        throw exc; }
    finally {
        Conn1.Close(); }
}

修改数据

public void SaveSettings()
{
    // Save settings when click 'Save/Exit' button
    // on the Settings form
    Conn1 = new SqlConnection(connStr);
    // Create an instance of 'SqlConnection' class

    SqlCommand MyCommand = Conn1.CreateCommand();
    // Create an instance of 'SqlCommand' class

    MyCommand.CommandText = "UPDATE settings SET SearchEngine = '" +
        _SearchEngine + "', StartMax = " + BoolBitConversion(_StartMax) + 
        ", ShowToolTips = " + BoolBitConversion(_ShowToolTips) + 
        ", RememberRefresh = " + BoolBitConversion(_RememberRefresh) + 
        ", SaveHistory = " + BoolBitConversion(_SaveHistory);

    try {
        Conn1.Open(); MyCommand.ExecuteNonQuery();
        Conn1.Close(); }
    catch (Exception exc) {
        throw exc; }
    finally {
        Conn1.Close(); }
}

删除数据

public void DeleteSelectedBookmark(string BookMarkID)
{
    // Delete bookmark
    int ConvertID;
    ConvertID = Convert.ToInt32(BookMarkID);
    Conn1 = new SqlConnection(connStr);
    // Create an instance of 'SqlConnection' class

    // Create an instance of 'SqlCommand' class
    SqlCommand MyCommand = Conn1.CreateCommand();
    MyCommand.CommandText = 
            "DELETE FROM UrlPath WHERE ID = " + ConvertID;
    try {
        Conn1.Open(); MyCommand.ExecuteNonQuery();
        Conn1.Close(); }
    catch (Exception exc) {
        throw exc; }
    finally {
        Conn1.Close(); }
}

请求数据

public List<string> FillBookMarks(int SelectedFolderID)
{
    // Fill the bookmark list from selected boomark folder
    List<string> BookMarkList = new List<string>();
    // Create an instance of 'List<t>' array class

    Conn1 = new SqlConnection(connStr);

    SqlCommand MyCommand = Conn1.CreateCommand();
    char Splitchr = (char)8;

    try { Conn1.Open();
        MyCommand.CommandText = 
          "SELECT ID, CustomName, FullUrlPath " + 
          "FROM UrlPath WHERE FolderID = " + 
          SelectedFolderID; // set query
        SqlDataReader Rs1 = MyCommand.ExecuteReader();
        while (Rs1.Read()) {
            BookMarkList.Add(Convert.ToString(Rs1.GetInt32(0)) +
                                    Splitchr + Rs1.GetString(1).Trim() + 
                                    Splitchr + Rs1.GetString(2).Trim()); } }
    catch (Exception exc) {
        throw exc; }
    finally {
        Conn1.Close(); Conn1.Dispose(); Conn1 = null; 
        MyCommand.Dispose(); MyCommand = null;
    }

    return BookMarkList;
}

我研究并找到了这段代码。如果我没有谷歌搜索,我根本不会知道它。这些是我在找到解决方案时最欣赏的主要内容。这段代码会删除 Internet Explorer 的历史记录文件。

public void DeleteIEHistory()
{
    string[] theFiles = Directory.GetFiles(
       Environment.GetFolderPath(Environment.SpecialFolder.History),
       "*", SearchOption.AllDirectories);
    foreach (string DelThis in theFiles)
    {
        try { File.Delete(DelThis); }
        catch
        {
            // Do Nothing 
        }
    }
}

我为这个程序使用了两个计时器控件。一个用于倒计时闹钟,另一个用于刷新网页。还有一些其他选项可以创建我自己的类并使用“.NET”的“Timer”类而不是使用控件,但我太懒了。这是其中之一。

#region Alarm / Countdaown stuff // ***************************************

private void tmrCountDown_Tick(object sender, EventArgs e)
// Alarm timer count down
{
    // This is the code counts the time until is up and flashes the frame
    // after that until it is stopped by the 'button' or 'cancel menu item'.
    if (TickCount > 0) {
        TickCount -= 1; }
    else {
        btnStopAlarm.Visible = true;
        if (FlashingRed == true) {
            FlashingRed = false;
            pnlColor.BackColor = Color.White; }
        else {
            FlashingRed = true;
            pnlColor.BackColor = Color.Red; }
    }
}

private void btnStopAlarm_Click(object sender, EventArgs e)
{
    StopCancelAlarm(); // Stop 'flashing frame' and stop the timer
}

private void StartCountDown(int AddingTime)
{
    // Set some variables before start the timer
    ClearAlarmCheckBoxes();
    TickCount = AddingTime;
    btnStopAlarm.Visible = false;
    pnlColor.BackColor = Color.Green;
    tmrCountDown.Start();
}

........

private void StopCancelAlarm()
{
    // Stop the timer and set the
    // variables back to defaults
    ClearAlarmCheckBoxes();
    pnlColor.BackColor = Color.LightGray;
    btnStopAlarm.Visible = false;
    FlashingRed = true;
    tmrCountDown.Stop();
    tmrCountDown.Dispose();
}
#endregion

我还使用我自己的注释分隔符来更容易地跟踪我的代码。“#region”在我需要隐藏一些代码进行痛苦调试时很有帮助。我知道我重复了上一篇文章中的一些技巧,但我认为让您知道“#region”可用很重要 :)

关注点

这段代码是为 C# 初学者准备的。我做了很多研究来学习很多东西。请尽可能使用我在这里发布的任何代码。我也想看看您的作品。如果您有兴趣进行一些增强,我将非常感激您教会我如何更好地“钓鱼” ;)

(顺便说一句,我的代码有一些遗漏,例如错误处理程序。我将在以后修复所有处理程序。虽然我正在使用异常,但我没有处理它们。还有一些我可能没有在这里提到的其他内容,例如如何删除书签,点击哪里进行黑屏……所以,它们也可能对您来说是很好的学习材料 :))

********* 附加功能 *********

我想向那些来这里看 .NET 自带“WebBrowser”工具代码的人道歉。我在我的浏览器代码中确实使用了那个工具

webbrowser.jpg

WebBrowser 工具是一个非常易于使用的组件,基本上是自解释的。我在这里列出几行代码,这样如果您不想下载整个代码,就不必下载了。

Web Browser 的 _DocumentCompleted 方法仅在页面下载完成后触发。我添加了一些功能,例如设置“后退”按钮、“前进”按钮、“加载中”指示器等。您也可以在其他地方看到 Web1.CanGoBackWeb1.CanGoForwardWeb1.Url 属性的使用。

private void Web1_DocumentCompleted(object sender, 
             WebBrowserDocumentCompletedEventArgs e)
{
    // Set some variables here at the end
    // of DocumentComplete (End of webpage load)
    txtURL.Text = Web1.Url.ToString();
    TSBack.Enabled = Web1.CanGoBack;
    TSForward.Enabled = Web1.CanGoForward;
    TSLoading.ForeColor = Color.Green;
    TSLoading.Text = "Ready...";
}

以下代码显示了一个在浏览器开始离开当前页面导航时调用的方法。此方法还设置了“忙碌”指示器。

private void Web1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
    // Show 'red text' while page busy and loading items
    TSLoading.ForeColor = Color.Red;
    TSLoading.Text = "Busy...";
}

Web1.Navigate(HomePageURL);:使用此代码设置 Web 浏览器的 URL。您可以在任何需要更改页面的时候使用此行。在此示例中,‘HomePageURL’是从 SQL 服务器获取值的变量。

Web1.Refresh():这只会刷新 Web 浏览器中的当前页面。

正如您所见,浏览器部分的代码没有什么特别之处。我的目标是学习和分享其他对我们的程序更有用的组件,例如数据库。WebBrowser 部分是我应用程序中很有趣的部分,它给了我一个借口来创建这个使用 SQL Express 的应用程序。在我之前的文章中,我创建了一个基于 XML 的数据库,但该应用程序一点也不吸引人。我下次一定会给我的文章起个恰当的名字。

变更

新版本上传于 2010/4/25。已修复许多 bug。还有一个 关于 WebPlus 运行的最新视频片段

© . All rights reserved.