简单的 WPF XML 文档查看器控件
本文介绍了一个简单的 XML 文档查看器控件,用于 WPF 应用程序以美观的方式显示 XML 文档。
引言
本文介绍了一个简单的 XML 文档查看器控件,用于 WPF 应用程序以美观的方式显示 XML 文档。
背景
在我最近的一个 WPF 项目中,我需要以类似于 Internet Explorer 的方式显示一些 XML 文档。我的第一个选择是使用 WPF "WebBrowser
" 控件。当我在硬盘上导航“WebBrowser
”控件到一个 XML 文件,或在网上导航一些 XML 内容时,它显示得很好。但是当我尝试将“WebBrowser
”控件导航到内存中的 XML 字符串时,该控件无法识别该内容是 XML,并且显示格式完全错误。然后我将需要一些其他替代方案。
我需要一个 XML 文档查看器控件,它以格式化的方式显示 XML 内容,并且我需要该控件从“System.Xml.XmlDocument”对象中获取 XML 内容,这样我就可以动态生成 XML 内容并显示它。
本文介绍的 XML 文档查看器控件的灵感来自于 Marco Zhou 的 博客。我所做的只是将这个想法变成一个更容易使用的用户控件,并提供一个演示应用程序来展示如何使用该控件。
本文附带的演示 Visual Studio 解决方案有两个 .NET 项目。一个是用户控件类库,另一个是一个简单的 WPF 应用程序,用于演示如何使用该控件。Visual Studio 解决方案是在 Visual Studio 2008 中开发的。
简单 Visual Studio 解决方案概述
Visual Studio 解决方案 "XMLViewerDomo
" 有两个 .NET 项目。

"XMLViewer
" 项目是一个创建 XML 文档查看器控件的类库,而 "DemoApplication
" 项目是一个 WPF 应用程序,用于演示如何使用该控件。
XML 文档查看器控件
XML 文档查看器控件在 "Viewer.xaml" 中实现
<UserControl x:Class="XMLViewer.Viewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:xmlstack="clr-namespace:System.Xml;assembly=System.Xml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<SolidColorBrush Color="Blue" x:Key="xmlValueBrush"/>
<SolidColorBrush Color="Red" x:Key="xmAttributeBrush"/>
<SolidColorBrush Color="DarkMagenta" x:Key="xmlTagBrush"/>
<SolidColorBrush Color="Blue" x:Key="xmlMarkBrush"/>
<DataTemplate x:Key="attributeTemplate">
<StackPanel Orientation="Horizontal"
Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Name}"
Foreground="{StaticResource xmAttributeBrush}"/>
<TextBlock Text="=""
Foreground="{StaticResource xmlMarkBrush}"/>
<TextBlock Text="{Binding Path=Value}"
Foreground="{StaticResource xmlValueBrush}"/>
<TextBlock Text="""
Foreground="{StaticResource xmlMarkBrush}"/>
</StackPanel>
</DataTemplate>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
<HierarchicalDataTemplate x:Key="treeViewTemplate"
ItemsSource="{Binding XPath=child::node()}">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0"
HorizontalAlignment="Center">
<TextBlock Text="<" HorizontalAlignment="Center"
Foreground="{StaticResource xmlMarkBrush}"
x:Name="startTag"/>
<TextBlock Text="{Binding Path=Name}"
Margin="0"
HorizontalAlignment="Center"
x:Name="xmlTag"
Foreground="{StaticResource xmlTagBrush}"/>
<ItemsControl
ItemTemplate="{StaticResource attributeTemplate}"
ItemsSource="{Binding Path=Attributes}"
HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBlock Text=">" HorizontalAlignment="Center"
Foreground="{StaticResource xmlMarkBrush}"
x:Name="endTag"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding NodeType}">
<DataTrigger.Value>
<xmlstack:XmlNodeType>Text</xmlstack:XmlNodeType>
</DataTrigger.Value>
<Setter Property="Text" Value="{Binding InnerText}"
TargetName="xmlTag"/>
<Setter Property="Foreground" Value="Blue"
TargetName="xmlTag"/>
<Setter Property="Visibility" Value="Collapsed"
TargetName="startTag"/>
<Setter Property="Visibility" Value="Collapsed"
TargetName="endTag"/>
</DataTrigger>
<DataTrigger Binding="{Binding HasChildNodes}" Value="False">
<Setter Property="Text" Value="/>" TargetName="endTag"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</UserControl.Resources>
<Grid>
<TreeView Grid.Row="2" Grid.ColumnSpan="2" Name="xmlTree"
ItemTemplate="{StaticResource treeViewTemplate}"/>
</Grid>
</UserControl>
"Viewer.xaml" 的代码隐藏文件如下
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml;
namespace XMLViewer
{
/// <summary>
/// Interaction logic for Viewer.xaml
/// </summary>
public partial class Viewer : UserControl
{
private XmlDocument _xmldocument;
public Viewer()
{
InitializeComponent();
}
public XmlDocument xmlDocument
{
get { return _xmldocument; }
set
{
_xmldocument = value;
BindXMLDocument();
}
}
private void BindXMLDocument()
{
if (_xmldocument == null)
{
xmlTree.ItemsSource = null;
return;
}
XmlDataProvider provider = new XmlDataProvider();
provider.Document = _xmldocument;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::node()";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);
}
}
}
演示 WPF 应用程序 "DemoApplication"
演示 WPF 应用程序的主应用程序窗口在 "XMLViewerDemoApplication.xaml" 中实现
<Window x:Class="DemoApplication.XMLViewerDemoApplication"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:XMLViewer="clr-namespace:XMLViewer;assembly=XMLViewer"
FontFamily="Verdana" Icon="Images\icon_music.ico"
Title="XMLViewer User Control Demonstration Application">
<Grid Margin="10, 10, 10, 10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<TextBox Name="txtFilePath" IsReadOnly="True"
Grid.Column="0" HorizontalAlignment="Stretch" />
<Button Margin="3, 0, 0, 0" Content="Browse..."
Click="BrowseXmlFile" Grid.Column="1"/>
<Button Margin="3, 0, 0, 0" Content="Clear"
Click="ClearXmlFile" Grid.Column="2"/>
</Grid>
<XMLViewer:Viewer x:Name="vXMLViwer" Grid.Row="2" />
</Grid>
</Window>
"XMLViewerDemoApplication.xaml" 的代码隐藏文件如下
using System.Windows;
using System.Xml;
namespace DemoApplication
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class XMLViewerDemoApplication : Window
{
public XMLViewerDemoApplication()
{
InitializeComponent();
}
private void BrowseXmlFile(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.CheckFileExists = true;
dlg.Filter = "XML Files (*.xml)|*.xml|All Files(*.*)|*.*";
dlg.Multiselect = false;
if (dlg.ShowDialog() != true) { return; }
XmlDocument XMLdoc = new XmlDocument();
try
{
XMLdoc.Load(dlg.FileName);
}
catch (XmlException)
{
MessageBox.Show("The XML file is invalid");
return;
}
txtFilePath.Text = dlg.FileName;
vXMLViwer.xmlDocument = XMLdoc;
}
private void ClearXmlFile(object sender, RoutedEventArgs e)
{
txtFilePath.Text = string.Empty;
vXMLViwer.xmlDocument = null;
}
}
}
为了演示如何使用用户控件,这个 WPF 应用程序首先让用户浏览一个 XML 文件,并将该 XML 文件加载到 "System.Xml.XmlDocument" 对象中。加载 "XMLDodument
" 对象后,它被分配给用户控件的 "xmlDocument
" 属性。如果我们想从用户控件中清除 XML 显示,我们可以简单地将 "null
" 分配给 "xmlDocument
" 属性。
运行演示应用程序
将 "DemoApplication
" 项目设置为 "启动" 项目,您可以调试启动演示应用程序。浏览一个 XML 文件,应用程序将以一种漂亮的格式显示 XML 文件。

上图显示了控件如何显示 Web 应用程序的 "Web.config" 文件。我将此 "Web.config" 文件包含在本文附带的 zip 文件中,但您可以使用此应用程序中您拥有的任何有效 XML 文件进行测试。XML 文档中的每个节点都可以独立展开和折叠,并且 XML 的内容被正确着色。
关注点
本文介绍了一个格式化的 XML 文档查看器 WPF 控件。该控件将 "System.Xml.XmlDocument" 对象作为 XML 内容。它简单、灵活且易于使用。
历史
这是本文的第一个修订版。