C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

ファイル選択用コントロールはない? /としぞー (19/03/05(Tue) 16:08) #90379
Re[1]: ファイル選択用コントロールはない? /魔界の仮面弁士 (19/03/05(Tue) 17:21) #90381
Re[1]: ファイル選択用コントロールはない? /とっちゃん (19/03/05(Tue) 16:55) #90380
Re[1]: ファイル選択用コントロールはない? /PANG2 (19/03/05(Tue) 17:27) #90382
  └ Re[2]: ファイル選択用コントロールはない? /としぞー (19/03/06(Wed) 11:06) #90389
    └ Re[3]: ファイル選択用コントロールはない? /魔界の仮面弁士 (19/03/06(Wed) 14:13) #90390
      └ Re[4]: ファイル選択用コントロールはない? /としぞー (19/03/07(Thu) 10:45) #90393
        └ Re[5]: ファイル選択用コントロールはない? /としぞー (19/03/12(Tue) 13:01) #90449 解決済み


親記事 / ▼[ 90381 ] ▼[ 90380 ] ▼[ 90382 ]
■90379 / 親階層)  ファイル選択用コントロールはない?
□投稿者/ としぞー (1回)-(2019/03/05(Tue) 16:08:21)

分類:[C#] 

初めまして。DelphiからC#へ移行しつつある者です。
Delphiでは、
 TDriveComboBox
 TDirectoryListBox
 TFileListBox
というコンポーネントがあり、これらをフォームに配置しますと、
ドライブ、フォルダを指定後、選択したファイルの名前をフルパスで取得できます。
(エクスプローラと似た感じです)
これと同じようなコントロールがC#に見当たらないのですが、何か手立てはないでしょうか。
(ダイアログボックスのようではなく、常にファイルがフォーム上に見えている状態のものが欲しいのです)

色々検索して、以下のサイトを参考にしてエクスプローラ風の表示はできたのですが、
選択したファイル名を取得する方法が分からず・・・
https://www.ipentec.com/document/csharp-shell-namespace-create-explorer-tree-view-control-and-linked-list-view

以上、宜しくお願い致します。
[ □ Tree ] 返信 編集キー/

▲[ 90379 ] / 返信無し
■90381 / 1階層)  Re[1]: ファイル選択用コントロールはない?
□投稿者/ 魔界の仮面弁士 (2085回)-(2019/03/05(Tue) 17:21:32)
2019/03/05(Tue) 17:36:33 編集(投稿者)

No90379 (としぞー さん) に返信
> 初めまして。DelphiからC#へ移行しつつある者です。
> Delphiでは、
>  TDriveComboBox
>  TDirectoryListBox
>  TFileListBox
> というコンポーネントがあり、これらをフォームに配置しますと、
> ドライブ、フォルダを指定後、選択したファイルの名前をフルパスで取得できます。
> (エクスプローラと似た感じです)

Windows 3.1 時代のコモンダイアログが、そんなインターフェイスでしたね。

Delphi アプリが手元に無いので確認できませんが、
この場合 UNC パスのもの、たとえば
 @"\\server\shared\folder1\folder2\fileName.txt"
のようなファイル指定は行えないのでしょうか?


> これと同じようなコントロールがC#に見当たらないのですが、何か手立てはないでしょうか。

参照設定で「Microsoft.VisualBasic.Compatibility」アセンブリを加えれば、
Microsoft.VisualBasic.Compatibility.VB6 名前空間にある
 DriveListBox
 DirListBox
 FileListBox
のコントロールをフォームに貼って使うことができます。
(設計の古い Obsolete なクラスなので、非推奨ではありますが)


> 色々検索して、以下のサイトを参考にしてエクスプローラ風の表示はできたのですが、
> 選択したファイル名を取得する方法が分からず・・・
Windows API CodePack の
Microsoft.WindowsAPICodePack.Controls.WindowsForms.ExplorerBrowser クラスでも良ければ:


// using Microsoft.WindowsAPICodePack.Shell;
private void Form1_Load(object sender, EventArgs e)
{
  explorerBrowser1.Navigate(ShellObject.FromParsingName(@"C:\"));
}

private void explorerBrowser1_SelectionChanged(object sender, EventArgs e)
{
  List<ShellObject> items = explorerBrowser1.SelectedItems.ToList();
  string[] pathList = items.Where(x => x.IsFileSystemObject).Select(x => x.GetDisplayName(DisplayNameType.FileSystemPath)).ToArray();

  listBox1.DataSource = pathList;
}
[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90379 ] / 返信無し
■90380 / 1階層)  Re[1]: ファイル選択用コントロールはない?
□投稿者/ とっちゃん (577回)-(2019/03/05(Tue) 16:55:13)
No90379 (としぞー さん) に返信
> 初めまして。DelphiからC#へ移行しつつある者です。
> Delphiでは、
>  TDriveComboBox
>  TDirectoryListBox
>  TFileListBox
> というコンポーネントがあり、これらをフォームに配置しますと、
> ドライブ、フォルダを指定後、選択したファイルの名前をフルパスで取得できます。
> (エクスプローラと似た感じです)

この3つのコントロールを使ったウィンドウというと、3.1 のファイルダイアログが一番近い気がします。
というか、その当時から用意されているものでそのまんま残っているものですし。

> これと同じようなコントロールがC#に見当たらないのですが、何か手立てはないでしょうか。
> (ダイアログボックスのようではなく、常にファイルがフォーム上に見えている状態のものが欲しいのです)
>
ファイルダイアログなど賄うのではなく。。。となると、現状では用意されていません。
TDriveComboBox などの互換コントロールが必要なら、自作するしかありません。

もしかしたらそういうコンポーネントを出しているところがあるかも。。。と一瞬思いましたが DriveListBox があるので、多分用意されていないでしょう(今どきとも違っているのでわざわざ作るメリットもない)。

TDriveComboBox は、ドライブを列挙するコンボボックスなので、DriveInfo.GetDrives() とかでリストアップできます。
選択が変更されたら、連携設定した TDirectoryListBox/TFileListBox にルートフォルダをセットしてやれば、リストアップをリセットできます。
TDirectoryListBox は、Directory.GetDirectories() でディレクトリを列挙できます。変更したら、自分自身をリストアップしなおしつつ、TFileListBox を更新します。
TFileListBox は、 や Directory.GetFiles() でファイルを列挙できます。

パスの取り出しをどうするかは、TFileListBox からたどるか、TFileListBox の個々のアイテムにフルパスを格納しておくかで対応できます。
どうするかは作りて次第なのでお好きな形で実装すればよいと思います。



> 色々検索して、以下のサイトを参考にしてエクスプローラ風の表示はできたのですが、
> 選択したファイル名を取得する方法が分からず・・・
> https://www.ipentec.com/document/csharp-shell-namespace-create-explorer-tree-view-control-and-linked-list-view
>

こちらは、見てくれも内容もエクスプローラとほとんど同じかたちで実現しています。
今何が選択されているかは、リストビューの選択アイテムを見ればOKです。

具体的には、ShellItemがセットされています。詳しくは、FillItem あたりをみてください。

選択されたアイテムの処理については、 OnDoubleClick がわかりやすいと思います。
var si = (ShellItem)SelectedItems[0].Tag;
または、
var si = SelectedItems[0].Tag as ShellItem;
でいいと思います。

ファイルかどうかの判定は

if( si.IsFileSystem && !si.IsFolder )
{
// ファイル(もしかしたらショートカット)
if( si.IsLink )
{
// ショートカットファイル
}
else
{
// 普通のファイル
}
}
とします。
IsFileSystem が true なら、si.Path でフルパスが取得できます。
そうじゃない場合、ファイルパスは取り出せません(GUIDが取れる場合もあるが空文字列の場合もある)。


リストアップの条件を色々変えたいという場合は、GetSubItems を加工します。
このサンプルでは、zipを展開するかどうかだけフラグを持っていますね。

システム属性や隠し属性をどうするかとか、あれは?これは?などなど。。。通常のファイルの列挙なんかとは異なるレベルでいろいろあります。

[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90379 ] / ▼[ 90389 ]
■90382 / 1階層)  Re[1]: ファイル選択用コントロールはない?
□投稿者/ PANG2 (264回)-(2019/03/05(Tue) 17:27:41)
No90379 (としぞー さん) に返信
> これと同じようなコントロールがC#に見当たらないのですが、何か手立てはないでしょうか。

VB6からVB.NETへのアップグレード用のクラスですが、C#でも使えるはずです。

Microsoft.VisualBasic.Compatibility.VB6
DriveListBox
DirListBox
FileListBox

https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.compatibility.vb6.filelistbox
[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90382 ] / ▼[ 90390 ]
■90389 / 2階層)  Re[2]: ファイル選択用コントロールはない?
□投稿者/ としぞー (2回)-(2019/03/06(Wed) 11:06:09)
とっちゃんさん、ありがとうございます。
まだ初めて一週間くらいですので何が正解か分からず、
とりあえずエラーが出ないのでOKと判断しているレベルですが、
ExplorerListView.csに以下を追加し、

    public string sFilePath;

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
      if (SelectedItems.Count > 0)
      {
        var si = (ShellItem)SelectedItems[0].Tag;
        if (si.IsFileSystem) {
          sFilePath = si.Path;
          if (si.IsFolder) {
            //フォルダ
          }
          else {
            if (si.IsLink) {
              //ショートカットファイル
            }
            else {
              //普通のファイル
            }
          }
        }
        else {
          //フォルダ・ファイル以外
        }
      }
      base.OnSelectedIndexChanged(e);
    }

フォームのほうに以下を追加すると、無事フルパスを取得できました。

    private void explorerListView1_SelectedIndexChanged(object sender, EventArgs e)
    {
      label1.Text = explorerListView1.sFilePath;
    }

ただ、ExplorerTreeViewの方でフォルダを変更するとそれに追従して
ExplorerListViewもフォルダが変更されるので問題ないのですが、
その逆ではExplorerTreeViewのフォルダが変更されないので
使い勝手がいまいちでした・・・。
この辺りも対応できればいいのですが、今のレベルではさっぱりです^^;


魔界の仮面弁士さん、 PANG2さん、ありがとうございます。
DriveListBox
DirListBox
FileListBox
を使うことができました。これで(見た目寂しいですが・・)なんとかできそうです。

Windows API CodePack はネットがつながった環境でしかインストールできないのですかね?
スタンドアロンPCなのでこれは断念しました・・・。

[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90389 ] / ▼[ 90393 ]
■90390 / 3階層)  Re[3]: ファイル選択用コントロールはない?
□投稿者/ 魔界の仮面弁士 (2089回)-(2019/03/06(Wed) 14:13:03)
No90389 (としぞー さん) に返信
> Windows API CodePack はネットがつながった環境でしかインストールできないのですかね?

ファイルの入手のために、オンラインの端末は必要ですが、
開発環境についてはオフラインでも大丈夫ですよ。

https://www.nuget.org/packages/WindowsAPICodePack-Shell/
https://www.nuget.org/packages/WindowsAPICodePack-Core/

上記NuGet ページのサイドバーにある "Download package" から入手した
.nupkg をオフライン端末のローカルにコピーしてやれば OK です。


> スタンドアロンPCなのでこれは断念しました・・・。
まずは Visual Studio のパッケージマネージャの設定に、
.nuget ファイルのあるディレクトリを指定します。

Visual Studio のバージョンによって多少の違いはありますが、[ツール]-[オプション]の中に
"パッケージ マネージャー" または "NuGet パッケージ マネージャー" があって、
その下に「パッケージ ソース」ノードがあるはず。

オフラインとのことなので、初期設定にある https://www.nuget.org/api/v2/ のチェックを外し、
代わりに、先ほどのローカルディレクトリを追加して、チェックを入れておきます。


あとはオンライン時と同様に、"WindowsAPICodePack-Shell" を NuGet すれば
必要なライブラリがプロジェクトに取り込まれます。



別案としては、GitHub ページの [Clone or download] - [Download Zip] から
  Microsoft.WindowsAPICodePack.dll
  Microsoft.WindowsAPICodePack.ShellExtensions.dll
のバイナリ(あるいはそれを生成するためのソースコード)を入手する方法もありますが、
通常は NuGet パッケージを用いた方が管理しやすいかと。
[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90390 ] / ▼[ 90449 ]
■90393 / 4階層)  Re[4]: ファイル選択用コントロールはない?
□投稿者/ としぞー (3回)-(2019/03/07(Thu) 10:45:43)
No90390 (魔界の仮面弁士 さん) に返信

ダウンロードはできたのですが、パッケージマネージャが何のことかわからず調べていますと、
VS2010の場合は Express Edition はダメなようでした(↓)。残念です。
http://yohshiy.blog.fc2.com/blog-entry-236.html

春になったらVS2012を会社のシステム部門からもらえるようなので、それまで待ってみます。
そのときまたお世話になるかもしれませんが、宜しくお願い致します。

[ 親 90379 / □ Tree ] 返信 編集キー/

▲[ 90393 ] / 返信無し
■90449 / 5階層)  Re[5]: ファイル選択用コントロールはない?
□投稿者/ としぞー (5回)-(2019/03/12(Tue) 13:01:44)
解決済みとします。
解決済み
[ 親 90379 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -