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

为Windows Mobile 6(SmartPhone)设备创建打开文件对话框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (15投票s)

2007 年 7 月 25 日

CPOL

3分钟阅读

viewsIcon

56708

为 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

在上面的代码中:

  1. 首先,获取当前所在的文件夹: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
    

  2. 然后,使用 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
    

  3. 文件夹“以更好的方式”排序后,我们可以将它们添加到 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 文章

© . All rights reserved.