SilverLight - Usando OpenFileDialog


Aplicações SilverLight para navegador não podem acessar arquivos no disco rígido do usuário. Embora o Silverlight contenha o namespace System.IO e classes como Files e Directory, não podemos escrever um código que leia um arquivo que resida no disco do usuário por questão de segurança.

Se o usuário permitir ao Silverlight acessar um arquivo, o aplicativo tem acesso somente leitura para o arquivo. O usuário pode permitir que um aplicativo acessar um arquivo através do uso do OpenFileDialog. Esta classe existe no Silverlight e é muito semelhante a classe de mesmo nome usada no WPF e no Windows Forms. Podemos especificar se o usuário pode selecionar um único arquivo, especificar os tipos de arquivos permitidos, etc.

Neste artigo vamos dar uma olhada no uso da classe no SilverLight.

Eu estou usando o Visual Web Developer 2010 Express Edition nos exemplos citados neste artigo.

Lendo um arquivo usando o OpenFileDialog

Vamos supor que que queremos ler um arquivo de texto, atualmente localizado no desktop. Por padrão, o Silverlight não pode ler esse arquivo por isso precisamos de entrada do usuário para permitir acesso ao arquivo. A localização do arquivo é de fato irrelevante.

Para abrir o arquivo em Silverlight, precisamos usar a caixa de diálogo OpenFileDialog.

Vamos abrir então o Visual Web Developer 2010 Express Edition e criar um novo projeto(File-> New Project) usando a linguagem C# e o template SilverLight Application com o nome UsandoOpenFileDialog;

Na janela - New SilverLight Application - vamos marcar a opção - Host the SilverLight Application in a new Web Site e usar o SilverLight 3;

Será criado uma solução contendo dois projetos:

1- Projeto SilverLight - UsandoOpenFileDialog

2- Projeto Web - UsandoOpenFileDialog.Web

Selecione o projeto SilverLight e no menu Project -> Add Existing Item...
Inclua um arquivo de imagem chamado folder.png que iremos exibir na
aplicação SilverLight;

Selecione e abra o arquivo MainPage.xaml e inclua neste arquivo os seguintes controles:

Definindo o seguinte leiaute nesta janela:

Na janela temos dois botões :

  1. O primeiro botão permite o usuário abrir um arquivo texto exibindo o seu conteúdo no controle TextBox = FileTextBox ;
  2. O segundo botão permite selecionar mais de um arquivo texto exibindo o conteúdo de cada um deles no controle TextBox = FileTextBox ;

O código XAML usado no arquivo MainPage.xaml é dado a seguir:


<UserControl x:Class="UsandoOpenFileDialog.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="500">

    <Grid x:Name="LayoutRoot" Background="White" Width="400" Height="400">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"></RowDefinition>
            <RowDefinition Height="3*"></RowDefinition>
            <RowDefinition Height="7*"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="OpenFileDialog Exemplo" Grid.ColumnSpan="2" FontSize="22" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
        <Image Source="folder.png" Width="100" Height="100" Grid.Row="1" Grid.RowSpan="2" Margin="3"></Image>
        <StackPanel Grid.Row="1" Margin="173,3,3,3" Grid.ColumnSpan="2">
            <TextBlock Text="Selecione um arquivo texto"></TextBlock>
            <Button Content="Procurar..." Width="100" Height="30" Name="OpenFileButton" Click="OpenFileButton_Click"></Button>
            <TextBlock Text="Selecione mais de um arquivo texto"></TextBlock>
            <Button Content="Procurar..." Width="100" Height="30" Name="OpenMultipleFileButton"  Click="OpenMultipleFileButton_Click"></Button>
        </StackPanel>
        <TextBox Grid.Row="2" IsReadOnly="True" Margin="173,5,5,0" TextWrapping="Wrap" Name="FileTextBox" VerticalScrollBarVisibility="Visible" Grid.ColumnSpan="2"></TextBox>
    </Grid>
</UserControl>

No code-behind do arquivo MainPage.xaml.cs vamos definir o código nos eventos Click de cada um dos botões onde vamos usar a classe OpenFileDialog;

Os namespaces definidos no arquivo são:

using System.Windows;
using System.Windows.Controls;
using System.IO;

No início do arquivo, após a declaração da classe, vamos definir a variável objeto do tipo OpenFileDialog:

private OpenFileDialog _openFileDialog;

Na classe MainPage() defina o código abaixo onde criamos uma instância da classe OpenFileDialog() que iremos usar no projeto:

 public MainPage()
 {
        InitializeComponent();
      _openFileDialog = new OpenFileDialog();
}

1- Código do evento OpenFileButton_Click - Abre um arquivo texto (MultiSelect=false)

        /// <summary>
        /// Lê um único arquivo texto
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenFileButton_Click(object sender, RoutedEventArgs e)
        {
    
       //define o filtro para arquivo texto e desabilita a seleção múltipla
            _openFileDialog.Filter =
"Text Files (.txt)|*.txt|All Files (*.*)|*.*";
            _openFileDialog.Multiselect = false;

            bool? dialogResultado = _openFileDialog.ShowDialog();

            if (dialogResultado.HasValue
&& dialogResultado.Value)
            {
                Stream fileStream = _openFileDialog.File.OpenRead();
                using (StreamReader reader = new StreamReader(fileStream))
                {
                    FileTextBox.Text = reader.ReadToEnd();
                }
                fileStream.Close();
            }
        }

2- Código do evento OpenMultipleFileButton_Click - Abre mais de um arquivo texto (MultiSelect=true)

        /// <summary>
        /// Le multiplos arquivos textos
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void OpenMultipleFileButton_Click(object sender, RoutedEventArgs e)
        {
            _openFileDialog.Filter =
"Text Files (.txt)|*.txt|All Files (*.*)|*.*";
            _openFileDialog.Multiselect = true;

            bool? dialogResult = _openFileDialog.ShowDialog();

            if (dialogResult.HasValue
&& dialogResult.Value)
            {
                FileTextBox.Text = string.Empty;
                foreach (var file in _openFileDialog.Files)
                {
                    Stream fileStream = file.OpenRead();
                    using (StreamReader reader = new StreamReader(fileStream))
                    {
                        FileTextBox.Text += reader.ReadToEnd();
                    }
                    fileStream.Close();
                }
            }
        }

O código usado em ambos os eventos é similar.

Usamos o método ShowDialog() da classe OpenFileDialog() que retorna um valor Booleano Nullable que indica a seleção do usuário.

Se foi feita uma seleção , a caixa de diálogo retorna true; quando o usuário clica em OK a caixa de diálogo retorna true; Se o usuário cancela a seleção é retornado false;

Para a permissão com uma seleção única fazemos o acesso ao arquivo usando o File.OpenRead ().

A propriedade do arquivo é do tipo FileInfo e normalmente um FileInfo também contém informações sobre a localização do arquivo. No entanto, esta informação não está disponível para o aplicativo Silverlight. (Recebemos uma SecurityException se tentarmos acessar o arquivo)

O arquivo é aberto somente para leitura.

No código que permite a seleção de mais de um arquivo o diálogo preenche sua propriedade Files, um IEnumerable de instâncias FileInfo e para acessar os arquivos usamos um laço foreach para ler cada arquivo selecionado usando um stream e o método ReadToEnd();

Executando o projeto iremos obter:

1- A apresentação da página ao usuário:

2- O usuário clique em um dos botões e a janela OpenFileDialog (Abrir) é aberta para seleção do arquivo(s);

3- Após a seleção o arquivo tem o seu conteúdo exibido na janela;

Como a abertura de um arquivo tem implicações de segurança, você não pode simplesmente colocar esse código onde quiser. A interação do usuário com a aplicação é necessária antes que o OpenFileDialog possa ser chamado. Isto essencialmente significa que podemos usar o código a partir de um evento de clique de botão, mas não no construtor de um UserControl.

Pegue o projeto completo aqui:  UsandoOpenFileDialogSVL.zip

Jesus dizia pois aos judeus que criam nele: Se vós permanecerdes na minha palavra, verdadeiramente sereis meus discípulos. E conhecereis a verdade e a verdade os libertará.(João 8:31-32)

Referências:


José Carlos Macoratti