为Windows Mobile 6(SmartPhone)设备创建打开文件对话框
为 Windows Mobile 6 (SmartPhone) 设备创建一个打开文件对话框。
引言
在将 Siccolo for Windows Mobile 5 转换为并升级到 Siccolo for Windows Mobile 6 for Smartphones 的项目工作中,我意识到 Windows Mobile 6 for Smartphone 版本缺少 OpenFilDlg
和 SaveFileAsDlg
控件。默认情况下,Smartphone 不包含文件浏览器应用程序,并且没有供开发人员使用的通用文件对话框。
Siccolo 的一些功能包括能够浏览和选择移动设备上的 SQL 脚本,并能够将 SQL 脚本保存在移动设备上的指定文件夹中。
本文介绍如何创建一个表单,允许选择文件进行打开,或进行“另存为”操作。
代码
现在,来看代码部分。在我的情况下,我想创建一个表单,该表单
- 外观和功能类似于 Windows Mobile 6 中的标准文件浏览器
- 允许在“打开文件”和“另存为”对话框模式之间切换 - 允许选择一个文件进行打开,或者选择一个文件夹并输入一个文件名进行保存
- 公开
SelectedFileName
属性 - 允许“过滤”要显示的文件
为了在移动设备上显示文件夹和文件,我使用了 TreeView
控件。为了让一个表单能够同时充当“打开文件对话框”和“另存为对话框”,我添加了一个文本框(在运行时根据选择隐藏/显示)。
Public Enum DialogMode As Integer
OpenFile = 0
SaveFileAs = 1
End Enum
Private m_DialogMode As DialogMode = DialogMode.OpenFile
Public Property Mode() As DialogMode
Get
Return m_DialogMode
End Get
Set(ByVal value As DialogMode)
m_DialogMode = value
If m_DialogMode = DialogMode.SaveFileAs Then
txtFileName.Visible = True
lblFileName.Visible = True
trwFileExplorer.Height = _
trwFileExplorer.Height - txtFileName.Height - 10
End If
End Set
End Property
并显示这样的表单
...
...
Dim dlgOpenFile As New frmOpenFileDialogSP
dlgOpenFile.Filter = "*.sql"
dlgOpenFile.Mode = frmOpenFileDialogSP.DialogMode.OpenFile
If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
...
...
在 TreeView
中,我想只显示“一个级别”,一旦用户选择了一个文件夹,TreeView
就会显示所选文件夹的内容(子文件夹和文件)。
为了用给定文件夹的子文件夹和文件填充 TreeView
,
Private Sub AddSubFolders(ByVal ParentPath As String)
Try
Dim ParentFolder As New DirectoryInfo(stripExtraSlash(ParentPath))
'loop in directories
Dim DirInfoComparer As DirectoryInfoComparer =
New DirectoryInfoComparer()
Dim DirList() As DirectoryInfo = ParentFolder.GetDirectories()
Array.Sort(DirList, DirInfoComparer)
Dim dirInfo As DirectoryInfo
For Each dirInfo In DirList 'ParentFolder.GetDirectories()
Dim DirectoryNode As New TreeNode
DirectoryNode.Text = dirInfo.Name ' name of file or dir
DirectoryNode.Tag = dirInfo.FullName
DirectoryNode.ImageIndex = 0 'folder
trwFileExplorer.Nodes.Add(DirectoryNode)
Next
'loop in files:
Dim FileInfoComparer As FileInfoComparer = New FileInfoComparer()
If m_Filter = "" Then m_Filter = "*.*"
Dim FileList() As FileInfo = ParentFolder.GetFiles(m_Filter)
Array.Sort(FileList, FileInfoComparer)
Dim fileInfo As FileInfo
Dim AddFile As Boolean = True
For Each fileInfo In FileList 'ParentFolder.GetFiles()
Dim FileNode As New TreeNode
FileNode.Text = fileInfo.Name
FileNode.Tag = fileInfo.FullName
FileNode.ImageIndex = 1 'file
FileNode.SelectedImageIndex = 1 'file
trwFileExplorer.Nodes.Add(FileNode)
Next
Catch ex_add_subfolder As Exception
' handle error here....
End Try
End Sub
在上面的代码中:
- 首先,获取当前所在的文件夹:
Dim ParentFolder As New DirectoryInfo(stripExtraSlash(ParentPath))
,其中stripExtraSlash()
函数Private Function stripExtraSlash(ByVal str As String) As String ' —-strip away the extra "\" for ' subdirectories. e.g. \\My documents Dim path As String = str If path.Length > 1 And (Mid(path, 1, 1) = "\") Then path = Mid(path, 2, path.Length - 1) End If Return path End Function
- 然后,使用
ParentFolder.GetDirectories()
获取子文件夹。但由于我想以排序的方式呈现文件夹和文件的列表,我必须添加“自定义”比较器进行排序。... <code>Dim DirInfoComparer As DirectoryInfoComparer = New DirectoryInfoComparer() Dim DirList() As DirectoryInfo = ParentFolder.GetDirectories() Array.Sort(DirList, DirInfoComparer) ...
其中
DirectoryInfoComparer()
和FileInfoComparer()
Imports System.IO Public Class DirectoryInfoComparer _ Implements System.Collections.IComparer Public Function Compare(ByVal objDirInfo1 As Object, _ ByVal objDirInfo2 As Object) As Integer _ Implements IComparer.Compare Dim DirInfo1 As System.IO.DirectoryInfo = _ CType(objDirInfo1, System.IO.DirectoryInfo) Dim DirInfo2 As System.IO.DirectoryInfo = _ CType(objDirInfo2, System.IO.DirectoryInfo) Return String.Compare(DirInfo1.Name, DirInfo2.Name, True) End Function End Class Public Class FileInfoComparer Implements System.Collections.IComparer Public Function Compare(ByVal objFileInfo1 As Object, _ ByVal objFileInfo2 As Object) As Integer _ Implements IComparer.Compare Dim FileInfo1 As System.IO.FileInfo = _ CType(objFileInfo1, System.IO.FileInfo) Dim FileInfo2 As System.IO.FileInfo = _ CType(objFileInfo2, System.IO.FileInfo) Return String.Compare(FileInfo1.Name, FileInfo2.Name, True) End Function End Class
- 文件夹“以更好的方式”排序后,我们可以将它们添加到
TreeView
中。... For Each dirInfo In DirList 'ParentFolder.GetDirectories() Dim DirectoryNode As New TreeNode DirectoryNode.Text = dirInfo.Name ' name of file or dir DirectoryNode.Tag = dirInfo.FullName DirectoryNode.ImageIndex = 0 'folder trwFileExplorer.Nodes.Add(DirectoryNode) Next ...
请注意,当一个文件夹节点被添加到 TreeView
时,节点标签包含正在添加的目录的完整名称。
文件也一样——使用 ParentFolder.GetFiles()
获取它们,使用 FileInfoComparer()
对它们进行排序,使用 Nodes.Add()
将它们添加到 TreeView
中。我们还可以使用 ParentFolder.GetFiles(searchPattern)
提供“过滤”功能。
当用户选择一个文件夹时(在 smartphone 上使用“回车”键),TreeView
将用该文件夹的内容进行填充。
Private Sub frmOpenFileDialogSP_KeyDown(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles MyBase.KeyDown
...
If (e.KeyCode = System.Windows.Forms.Keys.Enter) Then
'Enter:
'do we have file selected?
If trwFileExplorer.SelectedNode Is Nothing Then
Exit Sub
End If
If trwFileExplorer.SelectedNode.ImageIndex <> 1 Then
<code>Dim Path As String = _
System.IO.Path.Combine(trwFileExplorer.Tag, _
trwFileExplorer.SelectedNode.FullPath)
trwFileExplorer.BeginUpdate()
'delete nodes:
trwFileExplorer.Nodes.Clear()
'selected is folder - open it!
AddTopFolder(Path)
'done
trwFileExplorer.EndUpdate()
Exit Sub
End If
...
...
End If
...
...
End Sub
其中 AddTopFolder()
函数
Private Sub AddTopFolder(ByVal InitialPath As String)
Dim strPath As String = IIf(InitialPath = "", "\", InitialPath)
'check if path given is valid:
Try
Dim TopFolder As New DirectoryInfo(stripExtraSlash(strPath))
ChangeTopFolder(TopFolder)
mnuUp.Enabled = Not (TopFolder.Parent Is Nothing)
Catch ex As Exception
MessageBox.Show("Invalid Path [" & InitialPath & "]" & vbCrLf & _
"-----------------------------------" & vbCrLf & _
ex.Message & vbCrLf & _
"-----------------------------------", _
"Siccolo SP", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation, _
MessageBoxDefaultButton.Button1)
Me.DialogResult = Windows.Forms.DialogResult.Cancel
Me.Close()
End Try
'Dim newNode As Windows.Forms.TreeNode = New TreeNode
'newNode = trwFileExplorer.Nodes.Add(strNode)
'newNode.Tag = strNode
'************************************************************
'add sub folders, under root folder:
AddSubFolders(strPath)
'************************************************************
End Sub
以及 ChangeTopFolder()
Private Sub ChangeTopFolder(ByVal Folder As DirectoryInfo)
lblPath.Text = Folder.Name
<code>trwFileExplorer.Tag = Folder.FullName
End Sub
因此,任何时候 ParentFolder
发生更改——TreeView
都会将目录名称保存在 Tag
属性中——要获取 TreeView
中选定文件夹的完整路径,我们只需将 Path.Combine(trwFileExplorer.Tag, trwFileExplorer.SelectedNode.FullPath)
组合起来即可。
然后,我们只需要允许用户向上移动一个级别(就像在标准的 Windows Mobile 文件浏览器中一样)。
Private Sub mnuUp_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles mnuUp.Click
'can we go Up?!:
Try
Dim Path As String = trwFileExplorer.Tag
Dim ParentFolder As DirectoryInfo = New DirectoryInfo(Path)
If ParentFolder.Parent Is Nothing Then Exit Sub
Path = ParentFolder.Parent.FullName
trwFileExplorer.BeginUpdate()
'delete nodes:
trwFileExplorer.Nodes.Clear()
'selected is folder - open it!
AddTopFolder(Path)
'done
trwFileExplorer.EndUpdate()
Catch ex_go_up As Exception
End Try
End Sub
“向上”移动——因为 TreeView.Tag
属性包含当前文件夹的完整目录路径,基于此,我们创建 New DirectoryInfo(Path)
,然后通过引用 ParentFolder.Parent
,我们获得“上一个”文件夹的完整目录路径。
处理“另存为”
txtFileName
被显示... If m_DialogMode = DialogMode.SaveFileAs Then <codetxtFileName.Visible = True lblFileName.Visible = True trwFileExplorer.Height = _ trwFileExplorer.Height - txtFileName.Height - 10 End If ...
- 并允许用户从
TreeView
“跳转”到文本框txtFileName
,以输入“另存为”文件名。Private Sub frmOpenFileDialogSP_KeyDown(ByVal sender As System.Object, _ ByVal e As System.Windows.Forms.KeyEventArgs) _ Handles MyBase.KeyDown <code>If (e.KeyCode = System.Windows.Forms.Keys.Left) Then 'Left If m_DialogMode = DialogMode.SaveFileAs Then 'move focus to text box txtFileName.Focus() End If End If If (e.KeyCode = System.Windows.Forms.Keys.Right) Then 'right If m_DialogMode = DialogMode.SaveFileAs Then 'move focus to text box txtFileName.Focus() End If End If If (e.KeyCode = System.Windows.Forms.Keys.Enter) Then 'Enter: 'do we have file selected? If trwFileExplorer.SelectedNode Is Nothing Then Exit Sub End If If trwFileExplorer.SelectedNode.ImageIndex <> 1 Then Dim Path As String = _ System.IO.Path.Combine(trwFileExplorer.Tag, _ trwFileExplorer.SelectedNode.FullPath) trwFileExplorer.BeginUpdate() 'delete nodes: trwFileExplorer.Nodes.Clear() 'selected is folder - open it! AddTopFolder(Path) 'done trwFileExplorer.EndUpdate() Exit Sub End If 'else - selected is file - exit If m_DialogMode = DialogMode.OpenFile Then 'set properties: m_FullPath = trwFileExplorer.Tag m_SelectedFileName = trwFileExplorer.SelectedNode.Text m_SelectedFullFileName = System.IO.Path.Combine_ (m_FullPath, m_SelectedFileName) Me.DialogResult = Windows.Forms.DialogResult.OK Me.Close() Else 'move focus to text box txtFileName.Focus() End If End If End Sub
最后,当用户“按下”回车键时。
Private Sub frmOpenFileDialogSP_KeyDown(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
...
If m_DialogMode = DialogMode.OpenFile Then
'set properties:
m_FullPath = trwFileExplorer.Tag
m_SelectedFileName = trwFileExplorer.SelectedNode.Text
m_SelectedFullFileName = System.IO.Path.Combine_
(m_FullPath, m_SelectedFileName)
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
Else
'move focus to text box
txtFileName.Focus()
End If
...
end sub
Private Sub txtFileName_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles txtFileName.KeyDown
If (e.KeyCode = System.Windows.Forms.Keys.Enter) Then
If m_DialogMode = DialogMode.SaveFileAs Then
'set properties:
m_FullPath = trwFileExplorer.Tag
m_SelectedFileName = txtFileName.Text
m_SelectedFullFileName = System.IO.Path.Combine_
(m_FullPath, m_SelectedFileName)
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
End If
End If
End Sub
结果
更多关于此主题的内容
关注点
如果您想了解更多关于这个故事的内容——请查看 Siccolo - Free Mobile Management Tool For SQL Server 和更多文章,请访问 Siccolo 文章。