アプリ版:「スタンプのみでお礼する」機能のリリースについて

プログラミング初心者です。
ファイル管理ソフトを作りたいなと、種々の言語を比較した結果VC#が一番やりやすいかなと思い、基礎知識もなくvisual studioをインストールしてあれこれ試行錯誤しながら、メニューやボタンやリストビューを作るところまでは行きました。ドラッグアンドドロップ機能を付けたいと思い、色々と検索してドラッグアンドドロップでlistView1に特定の拡張子のファイルを入れる下記のコードは見つかりました。さらに、特定の拡張子(ここでは.txt)以外のファイルをドラッグしてlistView1の領域に入った時、カーソルを禁止のマークに変えたいのですがそのコードがわかりません。ご教授いただければと存じます。

// もちろん基礎知識も平行して勉強しているところです。

// 下記のlistView1_DragEnterイベントハンドラ内に
// if(ドラッグしたファイルの拡張子が.txt以外だったら){Cursor.Current = Cursors.No;}
// とすると思い色々試したのですがうまくいきませんでした。(素人の試行錯誤なので提示できません)

private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Link;
}
}

private void listView1_DragDrop(object sender, DragEventArgs e)
{
string[] handles = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string s in handles)
{
if (File.Exists(s))
{
if (string.Compare(Path.GetExtension(s), ".txt", true) == 0)
{
AddFileToListview(s);
}
}
else if (Directory.Exists(s))
{
DirectoryInfo di = new DirectoryInfo(s);
FileInfo[] files = di.GetFiles("*.txt");
foreach (FileInfo file in files)
AddFileToListview(file.FullName);
}
}
}

private void AddFileToListview(string fullFilePath)
{
if (!File.Exists(fullFilePath))
return;
string fileName = Path.GetFileNameWithoutExtension(fullFilePath);
string dirName = Path.GetDirectoryName(fullFilePath);
if (dirName.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))
dirName = dirName.Substring(0, dirName.Length - 1); //hack off the trailing \
ListViewItem itm = listView1.Items.Add(fileName);
itm.SubItems.Add(dirName); //second column = path
}

A 回答 (3件)

惜しいです。


DragEnterではLinkを設定あともループを続けると,最後の物のみが有効になってしまいます。
対策としては,最初に見つかったらそのままreturnのが簡単です。

# 見た目上の対策として,U+0020二つをU+3000に置き換えています。使用時は逆変換して下さい。
private void listView1_DragEnter(object sender, DragEventArgs e)
{
 string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false);
 foreach (string s in fileName)
 {
  if (File.Exists(s))
  {
   if (string.Compare(Path.GetExtension(s), ".txt", true) == 0)
   {
    e.Effect = DragDropEffects.Link;
    return; // 後で処理する物があったらLinkを設定して終わり。
   }
  }
  else if (Directory.Exists(s))
  {
   if (Directory.GetFiles(s, "*.txt").Length > 0) // DirectoryInfoを持ち出さなくてもOKで,条件は「存在すれば」なのでループで回さず,Lengthのみを見ている
   {
    e.Effect = DragDropEffects.Link;
    return; // 後で処理する物があったらLinkを設定して終わり。
   }
  }
 }
 e.Effect = DragDropEffects.None;
}
    • good
    • 0
この回答へのお礼

訂正ありがとうございます。

そうですね、やってて気づきました。こちらの回答に気づかず、自分であれこれと考えておりましたところ奇跡的にdirecotryにある*.txtのファイル数が>0ならばドラッグ可能にすればいいとわかり、こちらの回答とほぼ同じ内容に辿りつけました。

ただ、確かにreturnの処理に困っていたので大変ありがたかったです。

ありがとうございました。

お礼日時:2011/12/15 12:39

根本的な部分は,「受け入れたくないならe.EffectにDragDropEffects.Noneを代入する」ことです。



今回の場合は,DragDropイベントでの走査と同じ事を行い,
AddFileToListViewを呼び出すような状態になればe.EffectにLinkを設定し,
そのような状況に一切ならなければNoneを設定するこことになります。
    • good
    • 0
この回答へのお礼

回答ありがとうございました!無事できたと思います。
一応他の人のためになるかもしれないのでコードを記しておきます。

private void listView1_DragEnter(object sender, DragEventArgs e)
{
string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string s in fileName)
{
if (File.Exists(s))
{
if (string.Compare(Path.GetExtension(s), ".txt", true) == 0)
{
e.Effect = DragDropEffects.Link;
}
else if (Directory.Exists(s))
{
DirectoryInfo di = new DirectoryInfo(s);
FileInfo[] files = di.GetFiles("*.txt");
foreach (FileInfo file in files)
e.Effect = DragDropEffects.Link;
}
else
e.Effect = DragDropEffects.None;


}
}
}



private void listView1_DragDrop(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.None;

string[] handles = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string s in handles)
{
if (File.Exists(s))
{
if (string.Compare(Path.GetExtension(s), ".txt", true) == 0)
{
AddFileToListview(s);
}


}
else if (Directory.Exists(s))
{
DirectoryInfo di = new DirectoryInfo(s);
FileInfo[] files = di.GetFiles("*.txt");
foreach (FileInfo file in files)
AddFileToListview(file.FullName);
}


}


}

private void AddFileToListview(string fullFilePath)
{
if (!File.Exists(fullFilePath))
return;
string fileName = Path.GetFileNameWithoutExtension(fullFilePath);
string dirName = Path.GetDirectoryName(fullFilePath);
if (dirName.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)))

dirName = dirName.Substring(0, dirName.Length - 1); //hack off the trailing \
ListViewItem itm = listView1.Items.Insert(0, fileName);
itm.SubItems.Add(dirName); //second column = path
}

お礼日時:2011/12/14 20:38

e.GetDataPresentでFileDropを確認した後,e.GetDataでファイル名の一覧を取得し,


拡張子が.txtであればe.EffectにDragDropEffects.Linkを設定し,
設定していない場合はe.EffectにDragDropEffects.Noneを設定する,
というので対応できませんか。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

とりあえず、下記のコードをlistView1_DragEnterイベントハンドラに来j通することで.txtでない場合は禁止マークが出るようになりました!

string[] fileName = (string[])e.Data.GetData(DataFormats.FileDrop, false);

if (Path.GetExtension(fileName[0]) == ".txt")
e.Effect = DragDropEffects.Link;

else
e.Effect = DragDropEffects.None;

しかし、これでは複数選択してドラッグしたファイル内に.txtと.txtで無いものが混じっていると全てのファイルが弾かれてしまいます。この場合には.txtだけ入れたいと考えています。どう条件付けすればいいのか加えて教えていただけないでしょうか?よろしくお願い致します。

お礼日時:2011/12/14 18:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!