用WPF做一个简易浏览器

简介: 微软的WPF(Windows Presentation Foundation)是目前Windows平台上最好用的图形界面框架了。如果想在Windows平台上编写图形界面程序,而且没有跨平台且性能需求比较高,而且对C#语言比较熟悉,那么WPF就是最适合你的了。

微软的WPF(Windows Presentation Foundation)是目前Windows平台上最好用的图形界面框架了。如果想在Windows平台上编写图形界面程序,而且没有跨平台且性能需求比较高,而且对C#语言比较熟悉,那么WPF就是最适合你的了。

WPF虽然出来也有大概十来年了,但是它的很多设计思想还是非常先进的,配合C#这门语言的话更加顺手。WPF的界面设计和程序功能完全解耦,也就是说设计界面和编写程序功能可以互不干扰的同时进行。

好了,废话不多说,下面直接开始吧。当然需要说明,这篇文章不是讲如何实现浏览器的,而是利用WPF的一个浏览器控件,让大家了解一下WPF的一些简单功能。由于WPF组件庞大,没办法在一篇文章中详细介绍。所以如果大家通过这篇文章对WPF有了一些兴趣,那么这篇文章的目的就达到了。

先来看看效果图吧。当然功能比较简陋,只有前进、后退、刷新几个功能。当然如果太复杂,就没办法在一篇文章中说完了。

img_64c1fc108b1ebd626a50f0287c984c7a.png
效果图

界面设计

布局

不管是什么图形界面框架,首先讨论的都是界面布局了。布局负责组织界面元素如何排列和显示。合适的界面布局可以降低我们程序界面的复杂度。如果需要了解布局的话,可以看看这篇英文文章,或者查找其他中文文章。

这里简单说一下常用的几种布局:

  • StackPanel。将部件按照垂直或水平顺序依次排列。
  • WrapPanel。和前者差不多,不过如果部件太多,会自动安排到下一行显示。
  • DockPanel。可以指定上下左右中五个方位的组件。
  • Grid。网格布局,可以按照网格形式排列组件。

现在返回来看看这个浏览器的布局。首先第一行是按钮和地址栏,第二行就是浏览器控件了。所以在这里我使用了DockPanel,第一行我指定为Top;第二行不指定,也就是充满整个剩余空间。

然后来看看第一行的布局,这里我希望前三个按钮按顺序排列,最后的地址栏充满整个剩余空间。所以第一行本身也需要使用DockPanel来实现。

最后来看看相应的XAML代码,虽然说得比较多,但是代码倒是很少。

<DockPanel>
    <DockPanel DockPanel.Dock="Top">
        <Button Name="ForwardButton" Content="前进" Click="ForwardButton_Click" />
        <Button Name="BackButton" Content="后退" Click="BackButton_Click" />
        <Button Name="RefreshButton" Content="刷新" Click="RefreshButton_Click" />
        <TextBox Name="UrlTextBox" KeyDown="UrlTextBox_KeyDown" />
    </DockPanel>
    <WebBrowser Name="BrowserControl" />
</DockPanel>

控件

其实关于控件我倒是没什么说的。不管是哪种图形界面,反正控件总是按钮、文本域、标签那些东西。这里我用到的就是按钮和文本框,当然最重要的是WPF提供的浏览器控件WebBrowser,它封装了浏览器的操作以便我们直接使用。

当然WPF还有一个非常重要的特点就是代码可以无缝引用界面控件,这一点将在后面体现。这个特点可是很多图形界面框架不提供的,比方说安卓的代码要引用界面元素的话就得使用getElementById方法。

样式

最后要说的就是样式了。WPF的样式和HTML的样式在语法上很相似,我们既可以直接在界面元素上指定它的样式,也可以在其他地方统一管理。当然如果要符合软件设计的最佳实践,样式当然需要在一个地方统一指定比较好。

当然,WPF的样式非常丰富,可以对一个控件进行深度定制,让它“重新做人”。所以我就不做介绍了,等到需要的时候在查阅就行了。这里只设置了按钮和文本框的宽度和外边距,外边距的4个值分别代表上、左、右、下外边距。如果不在这里统一设置,那么就要针对每个按钮设置一次外边距,这是件很麻烦的事情。

<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="Width" Value="45" />
        <Setter Property="Margin" Value="10,10,0,10" />
    </Style>
    <Style TargetType="TextBox">
        <Setter Property="Margin" Value="10,10,10,10" />
    </Style>
</Window.Resources>

功能编写

事件处理

说完了界面的部分,下面来说说如何编写程序功能。利用强大的XAML,我们可以非常方便的将界面组件和功能代码对应起来。C#有一个特性叫做事件,WPF也利用了事件来处理程序响应。WPF的控件都包含了大量事件,可以处理鼠标、键盘、触屏等等各种事件,而且仅需要在XAML代码中添加一点代码就可以将事件和处理程序绑定起来。下面代码中的ClickKeyDown就是两个事件,用于处理单击鼠标和键盘按键。

<DockPanel>
    <DockPanel DockPanel.Dock="Top">
        <Button Name="ForwardButton" Content="前进" Click="ForwardButton_Click" />
        <Button Name="BackButton" Content="后退" Click="BackButton_Click" />
        <Button Name="RefreshButton" Content="刷新" Click="RefreshButton_Click" />
        <TextBox Name="UrlTextBox" KeyDown="UrlTextBox_KeyDown" />
    </DockPanel>
    <WebBrowser Name="BrowserControl" />
</DockPanel>

每个事件的处理函数签名都不相同,比方说单击鼠标的事件签名就是Click(object sender, RoutedEventArgs e),而按下键盘的事件签名是KeyDown(object sender, KeyEventArgs e)。在Visual Studio中我们只需要选择控件,然后点击属性中的相应事件,即可自动生成处理函数,我们只需要编写代码即可。

img_de24785365159dd825c9654c0ae7b54b.png
VS截图

浏览器控件

说完了事件机制,下面我们来看看如何用它来搞点事情。由于WPF提供了方便的浏览器控件,所以这里的代码非常简单,只需要调用浏览器控件的相应方法即可。由于没有单独的处理按下回车的事件,所以这里用的是按下键盘的事件,然后在处理程序中判断按下的是否是回车键,如果是的话再进行下一步处理,也就是让浏览器导航到对应网址。

private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
    BrowserControl.GoForward();
}
private void BackButton_Click(object sender, RoutedEventArgs e)
{
    BrowserControl.GoBack();
}
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
    BrowserControl.Refresh();
}
private void UrlTextBox_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        var url = UrlTextBox.Text;
        BrowserControl.Navigate(url);
    }
}

自动补全URL

上面的代码已经基本可以使用,不过还是有一个小问题。那就是如果输入的不是URL格式(http://www.baidu.com),而是网址(www.baidu.com),那么程序就会崩掉。因为浏览器控件只能接受URL形式的字符串,如果不是合法的URL,那么BrowserControl.Navigate(url)这一句代码就会抛出异常。

那么这个问题该如何解决呢?我在这里直接使用正则表达式做一下测试,如果如果输入的不是有效的URL,那么我就手动在网址前面添加一个 http://。实现方法很简单,直接看代码就行了。

public partial class MainWindow : Window
{
    private readonly Regex _urlPattern = new Regex(@"\w*://\w*(.\w*)+");
    public MainWindow()
    {
        InitializeComponent();
    }
    //省略了那些事件处理程序
    private void UrlTextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Return)
        {
            var url = UrlTextBox.Text;
            if (!_urlPattern.IsMatch(url))
            {
                url = "http://" + url;
            }
            BrowserControl.Navigate(url);
        }
    }
}

如果留心一下前面的XAML就会发现,在下面的代码中直接引用了XAML中浏览器控件的名字BrowserControl,并可以调用它的属性和方法。这也是浏览·WPF一个非常方便的特性。

更改地址栏URL

下面就剩下最后一个问题了。一般浏览器的地址栏,会随着访问网址的变化而变化。但是我们这个浏览器却没有这个功能,地址栏的地址永远是输入的那个地址。现在我们希望不论是前进、后退,还是从浏览器中点击其他链接,地址栏的地址都会跟着更新。

当然实现这个功能也很简单,查阅一下浏览器控件就可以发现,它有一个属性叫做Source,恰好就是当前页面的URL,所以利用这个属性就可以完美的实现我们的功能了。这样,只需要一行代码UrlTextBox.Text = BrowserControl.Source.ToString();就可以搞定了。

当然问题又来了,这行代码应该往哪里加呢?第一种办法是在所有处理程序中添加这行代码, 也就是说,前进、后退的处理程序都需要进行修改。这样并不是一个好办法,万一将来需求发生了变化,有好几处地方都要修改,更容易出错。解决办法还是刚才说的事件。经过一番查找,我发现了WebBrowserNavigated事件,顾名思义,这个事件会在调用了Navigate方法后触发。这样,只需要把这一行代码绑定到这个事件上就行了,代码非常优雅,酷毙了!

public MainWindow()
{
    InitializeComponent();
    BrowserControl.Navigated += BrowserControl_Navigated;
}
private void BrowserControl_Navigated(object sender, NavigationEventArgs e)
{
    UrlTextBox.Text = BrowserControl.Source.ToString();
}

这样,一个简易的浏览器就实现完毕了。代码我放在了Csdn Code,有兴趣的同学可以看看。

相关文章
|
安全 C# 定位技术
WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容
原文:WPF:WebBrowser提示 为帮助保护你的安全,您的Web浏览器已经限制此文件显示可能访问您的计算机的活动内容 版权声明:本文为博主原创文章,未经博主允许可以随意转载 https://blog.
3145 0
|
C# 前端开发 Android开发
WPF 客户端浏览器 添加Loading加载进度
原文:WPF 客户端浏览器 添加Loading加载进度 在windows开发界面时,使用浏览器来请求和显示网页内容,是比较常见的。 但是在请求网页内容时,因网速或者前端功能复杂加载较慢,亦或者加载时遇到各种问题,如空白/黑屏/加载不完整/证书问题等。
1724 0
|
Web App开发 C# Windows
WPF 制作电子相册浏览器
原文:WPF 制作电子相册浏览器    周末的时候,闲着无聊,做了一个电子相册浏览器。比较简单。界面如下: 主要部分代码如下: MainWindow.xaml ...
1015 0
|
Web App开发 JavaScript C#
在WPF中使用CefSharp嵌入浏览器
原文:在WPF中使用CefSharp嵌入浏览器 日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中。下面我们使用CefSharp嵌入浏览器来实现。  首先先介绍一下CefSharp嵌入式浏览器,它是基于Google浏览器的一个组件,我们可以在WPF/WinForm客户端软件中使用它。
2463 0
|
Web App开发 C# Android开发
WPF 使用 Edge 浏览器
原文:WPF 使用 Edge 浏览器 本文告诉大家如何使用 Windows Community Toolkit 的新控件,在 WPF 使用 Edge 浏览器 首先需要通过 VisualStudio 创建 WPF 项目。
1360 0
|
C# 数据可视化 容器
WPF自适应可关闭的TabControl 类似浏览器的标签页
原文:WPF自适应可关闭的TabControl 类似浏览器的标签页 效果如图:   虽然说是自适应可关闭的TabControl,但TabControl并不需要改动,不如叫自适应可关闭的TabItem.
2122 0
|
Web App开发 C# Windows
浏览器扩展系列————在WPF中定制WebBrowser快捷菜单
原文:浏览器扩展系列————在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/books/0764549146_8.aspx?fid=13574&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx 本文主要讲述如何在这篇文章中的ShowContextMenu方法中弹出自己的ContextMenu。
1036 0
|
7月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
398 0
|
7月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
151 1
|
4月前
|
开发框架 缓存 前端开发
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件
循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(11) -- 下拉列表的数据绑定以及自定义系统字典列表控件