Windows 2008Windows VistaWindows 7Windows 2003Visual Studio 2008LINQ高级Windows XP.NET 3.5Windows FormsC# 3.0中级开发Visual StudioWindows.NETC#
文档预览应用程序
一个可以预览你的文档和文件的应用程序,例如 PDF、Doc、JPG、PPT、XSL。
引言
文档预览是一个应用程序,它允许用户在浏览时预览文件,例如 PDF、Doc、XLS、JPG、MP3、AVI,界面类似于 Windows 资源管理器,但无需打开额外的应用程序。它还允许用户移动、复制和删除文件夹或文件。
开发这个软件的想法来自于我试图找到一个包含特定信息的 PDF 文档。我的目标是使用抽象类、继承、接口和 LINQ 等技术来开发这个应用程序,并提供关于这些技术用法的社区示例。
背景
这里有一些我用来提供预览功能的控件。
预览类型 | 文件类型 | 使用的组件和控件 | 执行原理 |
Excel 预览 | *.Xlsx, *.Xls | WebBrowser 和 Excel 互操作性 |
原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。 |
HTML 预览 | *.Html, *.Htm | WebBrowser |
原理是将路径分配给 WebBrowser 控件的 URL 属性。 |
图像预览 | *.Jpeg, *.Jpg, *.Tif, *.Gif, *.Bmp, *.Png | PictureBox |
原理是将一个 Image 分配给 PictureBox 控件的 Image 属性。 |
媒体预览 | *.Mp3, *.Wav, *.Wma, *.Mid, *.Avi, *.Mpg, *.Wmv | AxWMPLib.AxWindowsMediaPlayer |
原理是将文件的路径添加到播放列表中,并执行 WindowsMediaPlayer 控件的 Play 命令。 |
PDF 预览 | AxAcroPDFLib.AxAcroPDF |
原理是将文件的路径分配给控件的 src 属性。 |
|
Power Point 预览 | *.Pptx, *.Ppt, *.Ppsx, *.Pps | WebBrowser 和 PowerPoint 互操作性 |
原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。 |
文本预览 | *.Txt, *.Rtf | RichTextBox |
原理是简单地使用 StreamReader 读取文本文件的内容,然后将内容分配给 RichTextBox 的 Text 属性。 |
Word 预览 | *.Docx, *.Doc | WebBrowser 和 Word 互操作性 |
原理是使用互操作性打开文档,并将其作为 HTML 保存在Temporary Internet Files下,然后使用 WebBrowser 控件显示该 HTML。 |
Using the Code
正如我所提到的,所有操作都应该派生自 Action
抽象类。 可以在下面找到 Action
类的代码。 最重要的一点是,每个子类都应该以不同的方式实现 DoAction
方法。 动作的代码应该写在这个方法中。
public abstract class Action
{
public abstract void DoAction(string path, FileType parFileType, frmMain frm);
public void ShowError(string errorMessage)
{
MessageBox.Show(errorMessage,"Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
public bool FileExists(string path)
{
if (File.Exists(path))
{
return true;
}
else
{
ShowError("File is not accessable");
return false;
}
}
public bool DirectoryExists(string path)
{
if (Directory.Exists(path))
{
return true;
}
else
{
ShowError("Directory is not accessable");
return false;
}
}
}
所有预览控件都应该实现 IPreview
接口; 这个接口包含应该实现的 Preview
方法。 预览控件的执行原理代码应该写在这个方法中。
public interface IPreview
{
void Preview(string path);
}
在这里,我提供了一个继承了 Action
类的 Preview
Action 类的示例。
[ActionAttributes(ActionName ="Preview", IsDefaultAction =true,
ActionsGroupTypes =new GroupTypes[] { GroupTypes.File })]
public class Preview : DocExp.AbstractClasses.Action
{
public override void DoAction(string path, FileType parFileType, frmMain frm)
{
try
{
if (FileExists(path))
{
if (parFileType.PreviewType ==null)
{
ShowError("Preview not available");
}
else
{
Type t = parFileType.PreviewType;
SplitContainer sc=(SplitContainer)frm.Controls.Find("sc",true)[0];
Panel pnl=(Panel)sc.Panel2.Controls.Find("pnlPreview",true)[0];
if (pnl.Controls.Count > 0)
{
Control pOld = pnl.Controls[0];
pOld.Dispose();
}
pnl.Controls.Clear();
sc.Panel2Collapsed = false;
IPreview p = (IPreview)Activator.CreateInstance(t);
pnl.Controls.Add((Control)p);
((Control)p).Dock =DockStyle.Fill;
p.Preview(path);
frm.SetPreviewPanelButtonsVisibility();
}
}
}
catch (Exception ex)
{
ShowError("An error occured while loading preview control");
frm.SetPreviewPanelButtonsVisibility();
}
}
}
这是我用来添加文件类型作为搜索条件,并将动作作为上下文菜单项的代码
fileTypes.Add(new FileType("PDF Files", "*.Pdf",
typeof(PdfPreview), pdfFileTypeGroup));
fileTypes.Add(new FileType("JPG Files", "*.Jpg",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("JPEG Files", "*.Jpeg",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("TIFF Files", "*.Tif",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("GIF Files", "*.Gif",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("BMP Files", "*.Bmp",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("PNG Files", "*.Png",
typeof(ImagePreview), imageFileTypeGroup));
fileTypes.Add(new FileType("MP3 Files", "*.Mp3",
typeof(MediaPreview), musicFileTypeGroup));
......
foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
{
if (t.BaseType == typeof(DocExp.AbstractClasses.Action))
{
string actionName = ((ActionAttributes)
t.GetCustomAttributes(typeof(ActionAttributes), true)[0]).ActionName;
bool isDefault = ((ActionAttributes)
t.GetCustomAttributes(typeof(ActionAttributes),true)[0]).IsDefaultAction;
GroupTypes[] gt = ((ActionAttributes)
t.GetCustomAttributes(typeof(ActionAttributes),true)[0]).ActionsGroupTypes;
ActionType at = new ActionType(actionName, t, isDefault);
foreach (GroupTypes g in gt)
{
at.ActionsGroupTypes.Add(g);
}
actionTypes.Add(at);
}
}
联系方式
有关错误报告和建议,请随时通过 oztamer@hotmail.com 与我联系。