【WPF】フォルダ選択ダイアログを表示して複数のCSVファイルを読み込む

公開日:2019-06-14
最終更新:2019-06-14
※この記事は外部サイト(https://www.doraxdora.com/blog/2017/07/13/...)からのクロス投稿です

おはようございます。

WPFでは、Windowsフォームと違いデフォルトでフォルダ選択のコントロールがないようです。

いくつか方法はあるようですが、
今回は 「Microsoft.WindowsAPICodePack」というライブラリを使って実装してみたいと思います。

いつも通り、前回までのプログラムを流用します。
【WPF】DataGridの内容をCSVファイルに出力する

画面の変更

画面にフォルダ参照ボタンを追加します。
<Button x:Name="fld_button" Content="フォルダ参照" HorizontalAlignment="Left" Margin="410,273,0,0" VerticalAlignment="Top" Width="97" Height="30" Click="fld_button_Click"/>  
</pre>  
MainWindow.xaml  
<pre class="lang:xhtml decode:true"><Window x:Class="WpfApp1.MainWindow"  
        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"  
        xmlns:local="clr-namespace:WpfApp1"  
        mc:Ignorable="d"  
        Title="一覧" Height="350" Width="530">  
    <Window.Resources>  
        <ResourceDictionary Source="/Style/StyleDic.xaml"/>  
    </Window.Resources>  

    <Grid>  
        <Grid.Resources>  
            <local:KindConverter x:Key="KindConv"/>  
        </Grid.Resources>  
        <Label Content="名前:" Margin="10,10,0,0" Style="{StaticResource lb-normal}"/>  
        <TextBox x:Name="search_name" Margin="56,12,0,0" Style="{StaticResource tx-normal}"/>  
        <Label Content="種別:" Margin="201,10,0,0" Style="{StaticResource lb-normal}"/>  
        <ComboBox x:Name="search_kind" Margin="252,12,0,0" Style="{StaticResource cb-normal}"/>  
        <Button x:Name="search_button" Content="検索" Margin="432,12,0,0" Style="{StaticResource btn-normal}" Click="search_button_Click"/>  

        <DataGrid Name="dataGrid" HorizontalAlignment="Left" Margin="10,43,0,0" Width="497" Height="225" Style="{StaticResource grid-normal}" >  
            <DataGrid.Columns>  
                <DataGridTextColumn Binding="{Binding No}" ClipboardContentBinding="{x:Null}" Header="No" IsReadOnly="True" Width="50"/>  
                <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="名前" IsReadOnly="True" Width="100"/>  
                <DataGridTextColumn Binding="{Binding Sex}" ClipboardContentBinding="{x:Null}" Header="性別" IsReadOnly="True" Width="40"/>  
                <DataGridTextColumn Binding="{Binding Age}" ClipboardContentBinding="{x:Null}" Header="年齢" IsReadOnly="True" Width="40"/>  
                <DataGridTextColumn Binding="{Binding Kind, Converter={StaticResource KindConv}}" ClipboardContentBinding="{x:Null}" Header="種別" IsReadOnly="True" Width="120"/>  
                <DataGridTextColumn Binding="{Binding Favorite}" ClipboardContentBinding="{x:Null}" Header="好物" IsReadOnly="True" Width="*"/>  
            </DataGrid.Columns>  
        </DataGrid>  
        <Button x:Name="add_button" Content="追加" HorizontalAlignment="Left" Margin="10,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="add_button_Click"/>  
        <Button x:Name="upd_button" Content="更新" HorizontalAlignment="Left" Margin="90,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="upd_button_Click"/>  
        <Button x:Name="del_button" Content="削除" HorizontalAlignment="Left" Margin="170,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="del_button_Click"/>  
        <Button x:Name="imp_button" Content="CSV読込" HorizontalAlignment="Left" Margin="250,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="imp_button_Click"/>  
        <Button x:Name="exp_button" Content="CSV出力" HorizontalAlignment="Left" Margin="330,273,0,0" VerticalAlignment="Top" Width="75" Height="30" Click="exp_button_Click"/>  
        <Button x:Name="fld_button" Content="フォルダ参照" HorizontalAlignment="Left" Margin="410,273,0,0" VerticalAlignment="Top" Width="97" Height="30" Click="fld_button_Click"/>  
    </Grid>  
</Window></pre>  
<h2>追加ライブラリ</h2>  
Nugetで次のライブラリを参照に追加します。  
<pre class="lang:default decode:true">    Microsoft.WindowsAPICodePack.Core  
    Microsoft.WindowsAPICodePack.Shell  

Coreパッケージ

ソリューションエクスプローラーから「参照」>「NuGet パッケージの管理」を選択します。

WindowsAPICodePack と入力しパッケージを絞り込み、
表示されたリストから「Microsoft.WIndowsAPICodePack.Core」を選択、
「インストール」ボタンをクリックします。

プレビュー画面が表示された場合は、「OK」ボタンをクリックします。

出力ビューに「終了」が出力されれば完了。

Shellパッケージ

Coreパッケージと同様、NuGet パッケージの管理画面にて
絞込表示されたリストから「Microsoft.WindowsAPICodePack.Shell」を選択
「インストール」ボタンをクリックします。

プレビュー画面が表示された場合は「OK」ボタンをクリックします。

出力ビューに「終了」が出力されれば完了です。

ライブラリ使用宣言の追加

インストールしたライブラリを使用するための宣言を追記します。

MainWindow.xaml.cs

using Microsoft.WindowsAPICodePack.Dialogs;  

 

処理の追加

複数ファイル読み込み処理

MainWindow.xaml.cs
/// <summary>  
        /// ディレクトリ内のCSVファイルを全て読み込む  
        /// </summary>  
        /// <param name="sourceDir"></param>  
        private List<Cat> readFiles(String sourceDir)  
        {  
            string[] files = Directory.GetFiles(sourceDir, "*.csv");  
            List<Cat> list = new List<Cat>();  
            // リストを走査してコピー  
            for (int fileCount = 0; fileCount < files.Length; fileCount++)  
            {  
                List<Cat> catList = readFile(files[fileCount]) as List<Cat>;  
                list.AddRange(catList);  
            }  

            return list;  
        }  

 

ボタンクリックイベント処理

MainWindow.xaml.cs
/// <summary>  
        /// フォルダ参照ボタンクリックイベント.  
        /// </summary>  
        /// <param name="sender"></param>  
        /// <param name="e"></param>  
        private void fld_button_Click(object sender, RoutedEventArgs e)  
        {  
            // ダイアログ生成  
            CommonOpenFileDialog dlg = new CommonOpenFileDialog();  

            // パラメタ設定  

            // タイトル  
            dlg.Title = "フォルダ選択";  
            // フォルダ選択かどうか  
            dlg.IsFolderPicker = true;  
            // 初期ディレクトリ  
            dlg.InitialDirectory = @"c:\";  
            // ファイルが存在するか確認する  
            //dlg.EnsureFileExists = false;  
            // パスが存在するか確認する  
            //dlg.EnsurePathExists = false;  
            // 読み取り専用フォルダは指定させない  
            //dlg.EnsureReadOnly = false;  
            // コンパネは指定させない  
            //dlg.AllowNonFileSystemItems = false;  

            //ダイアログ表示  
            var Path = dlg.ShowDialog();  
            if (Path == CommonFileDialogResult.Ok)  
            {  
                // 選択されたフォルダ名を取得、格納されているCSVを読み込む  
                List<Cat> list = readFiles(dlg.FileName);  

                // 接続  
                int count = 0;  
                using (var conn = new SQLiteConnection("Data Source=SampleDb.sqlite"))  
                {  
                    conn.Open();  

                    // データを追加する  
                    using (DataContext context = new DataContext(conn))  
                    {  
                        foreach (Cat cat in list)  
                        {  
                            // 対象のテーブルオブジェクトを取得  
                            var table = context.GetTable<Cat>();  
                            // データが存在するかどうか判定  
                            if (table.SingleOrDefault(x => x.No == cat.No) == null)  
                            {  
                                // データ追加  
                                table.InsertOnSubmit(cat);  
                                // DBの変更を確定  
                                context.SubmitChanges();  
                                count++;  
                            }  
                        }  
                    }  
                    conn.Close();  
                }  

                MessageBox.Show(count + " / " + list.Count + " 件 のデータを取り込みました。");  

                // データ再検索  
                searchData();  
            }  
        }  

 

CSVファイルの作成

cat1.csv
1,そら,♂,6,01,犬の人形  
2,りく,♂,5,02,人間  
3,うみ,♀,4,03,高級ウェットフード  
4,こうめ,♀,2,04,横取り  
5,こなつ,♀,7,01,布団  

cat2.csv

6,なな,♀,19,01,こたつ  

実行してみる

アプリケーションを起動し、「フォルダ選択」ボタンをクリックします。

フォルダ選択ダイアログが表示されるので、
作成したCSVが格納されているフォルダ―を選択し、「フォルダ―の選択」ボタンをクリックします。

読込が無事に終了しました。

追加したデータが画面に表示されることを確認。

まとめ

今回紹介した「WindowsAPICodePack」は、 他にもいろいろなことが出来るようなのでそのうち試してみたいと思います。

ソースはこちら

GitHub

ではでは。

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
@doraxdoraの技術ブログ 主に Java, C#, Python, Javascript の記事を載せていく予定。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする