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

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

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

Re[5]: ピクチャーボックス→リストボックスに追加


(過去ログ 101 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■60646 / inTopicNo.1)  ピクチャーボックス→リストボックスに追加
  
□投稿者/ やんまー (48回)-(2011/07/13(Wed) 15:14:19)

分類:[VB.NET/VB2005 以降] 

おそれいります。


ピクチャーボックスとリストボックスを用意しておいて、
ピクチャーボックスからリストボックスに画像をドラッグアンドドロップしたいです。

こちら
http://dobon.net/vb/dotnet/control/draganddrop.html
を参考にしたところ、上手くできたと思ったのですが、追加できない状態です。

---
Public Partial Class MainForm

Dim mouseDownPoint as Point

Sub ListBox2DragEnter(sender As Object, e As DragEventArgs)
'ドラッグされているデータがpicturebox型か調べ、
'そうであればドロップ効果をCopyにする
If e.Data.GetDataPresent(GetType(PictureBox)) Then
e.Effect = DragDropEffects.Copy
Debug.Print("enter")
Else
'picturebox型でなければ受け入れない
e.Effect = DragDropEffects.None
End If
End Sub


Sub ListBox2DragDrop(sender As Object, e As DragEventArgs)
'ドロップされたデータがPictureBox型か調べる
If e.Data.GetDataPresent(GetType(PictureBox)) Then
Dim target As ListBox = CType(sender, ListBox)
Dim pic As PictureBox = DirectCast(e.Data.GetData(GetType(PictureBox)), PictureBox)
'ドロップされたデータをリストボックスに追加する ★
target.Items.Add(pic)
End If
End Sub


Sub PictureBox1MouseDown(sender As Object, e As MouseEventArgs)
'マウスの左ボタンだけが押されている時のみドラッグできるようにする
If e.Button = MouseButtons.Left Then
'ドラッグの準備
Dim pic As PictureBox = DirectCast(sender, PictureBox)
'マウスの押された位置を記憶
mouseDownPoint = New Point(e.X, e.Y)
Else
mouseDownPoint = Point.Empty
End If
End Sub


Sub PictureBox1MouseMove(sender As Object, e As MouseEventArgs)
If mouseDownPoint <> Point.Empty Then
'ドラッグとしないマウスの移動範囲を取得する
Dim moveRect As New Rectangle(mouseDownPoint.X - SystemInformation.DragSize.Width / 2, mouseDownPoint.Y - SystemInformation.DragSize.Height / 2, SystemInformation.DragSize.Width, SystemInformation.DragSize.Height)
'ドラッグとする移動範囲を超えたか調べる
If Not moveRect.Contains(e.X, e.Y) Then
'ドラッグの準備
Dim pic As PictureBox = DirectCast(sender, PictureBox)

'ドラッグ&ドロップ処理を開始する
Dim dde As DragDropEffects = pic.DoDragDrop(Me.pictureBox1, DragDropEffects.Copy)

mouseDownPoint = Point.Empty
End If
End If
End Sub
End Class
---


'ドロップされたデータをリストボックスに追加する ★
のところがいけないような気がするのですが・・・


引用返信 編集キー/
■60649 / inTopicNo.2)  Re[1]: ピクチャーボックス→リストボックスに追加
□投稿者/ GHQ (1回)-(2011/07/13(Wed) 15:25:42)
No60646 (やんまー さん) に返信

> target.Items.Add(pic)

ですが、リストボックスにに追加するアイテムの型は何ですか?
(イメージ?ピクチャーボックスそのものではないですよね?)
引用返信 編集キー/
■60650 / inTopicNo.3)  Re[1]: ピクチャーボックス→リストボックスに追加
□投稿者/ shu (848回)-(2011/07/13(Wed) 15:26:54)
No60646 (やんまー さん) に返信

リストボックスに表示できるのは文字列ですが、何を表示したいのですか?


引用返信 編集キー/
■60656 / inTopicNo.4)  Re[2]: ピクチャーボックス→リストボックスに追加
□投稿者/ やんまー (49回)-(2011/07/13(Wed) 16:43:07)
shu さん

ありがとうございます!

画像をセットしたいです。
引用返信 編集キー/
■60657 / inTopicNo.5)  Re[2]: ピクチャーボックス→リストボックスに追加
□投稿者/ やんまー (50回)-(2011/07/13(Wed) 16:44:08)
GHQ さん ありがとうございます


> ですが、リストボックスにに追加するアイテムの型は何ですか?
> (イメージ?ピクチャーボックスそのものではないですよね?)

そうです!
イメージです。
引用返信 編集キー/
■60658 / inTopicNo.6)  Re[3]: ピクチャーボックス→リストボックスに追加
□投稿者/ shu (850回)-(2011/07/13(Wed) 16:53:33)
No60656 (やんまー さん) に返信
> shu さん
>
> ありがとうございます!
>
> 画像をセットしたいです。
Owner Drawで描画するということですか?
=>DrawModeをOwnerDrawFixedかOwnerDrawVariableにして
MeasureItemイベント、DrawItemイベントを記述する必要があります。

DropについてはPictureBoxではなくImageを取得するほうがよいかと思います。
PictureBoxへの描画をPaintイベントで処理している場合、表示されている画像を直接
取得することは出来ないのでそのロジックをListBoxのDrawItemイベントの処理と共有化すると処理しやすいかと思います。
引用返信 編集キー/
■60690 / inTopicNo.7)  Re[3]: ピクチャーボックス→リストボックスに追加
□投稿者/ shu (852回)-(2011/07/14(Thu) 22:56:58)
2011/07/14(Thu) 22:57:10 編集(投稿者)
No60657 (やんまー さん) に返信

Imageプロパティから読み取るサンプルです
ListBox1:DrawMode = OwnerDrawVariable, AllowDrop = True

Button1はTextBox1に入力されたFullPathよりFileStream経由でイメージを読み込む。
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim fl As New FileInfo(TextBox1.Text)
        If Not fl.Exists Then Exit Sub
        Dim stm As FileStream = fl.OpenRead

        PictureBox1.Image = Image.FromStream(stm)
        stm.Close()
    End Sub

PictureBox1からのドラッグ開始、細かいチェックは省略
    Private m_blnDown As Boolean = False
    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        m_blnDown = True
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        m_blnDown = False
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        PictureBox1.DoDragDrop(PictureBox1, DragDropEffects.Copy)
    End Sub

ListBox1へのドロップ(PictureBox1.Imageのクローンを取得)
    Private Sub ListBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter
        If e.Data.GetData(GetType(PictureBox)) Is PictureBox1 Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop
        If e.Data.GetData(GetType(PictureBox)) Is PictureBox1 Then
            ListBox1.Items.Add(PictureBox1.Image.Clone)
        End If
    End Sub

ListBox1のItemをオーナードロー(4:3のイメージで試したためHeigth = Width*3\4としてあります。16:9ならそのように計算する。
    Private Sub ListBox1_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) Handles ListBox1.MeasureItem
        e.ItemWidth = ListBox1.Width
        e.ItemHeight = e.ItemWidth * 3 \ 4
    End Sub

    Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem
        Dim grp = e.Graphics
        e.DrawBackground()
        Dim bmp = DirectCast(ListBox1.Items(e.Index), Bitmap)

        grp.DrawImage(bmp, e.Bounds)
    End Sub

引用返信 編集キー/
■60691 / inTopicNo.8)  Re[4]: ピクチャーボックス→リストボックスに追加
□投稿者/ やんまー (51回)-(2011/07/15(Fri) 00:29:04)
shu さん

ありがとうございます!

実は僕なりにも教えていただいたことを考えてみて作ってみました。
ただ、僕のやった方法だと、何故か、一回しかD&Dできませんでした。。。


多分「'ドロップされたデータをリストボックスに追加する ★」のあたりに問題がありそうな事はわかるのですが・・・

で、実際にファイル名を渡してしまえば・・と思って

pic.ImageLocation 

などとやってみましたが、何故かファイル名は取れませんでした。。



教えていただいたコードも試してみます!




----

Public Partial Class MainForm
	
	Dim mouseDownPoint as Point
	Const spacing As Integer = 3 ' 画像の周りのスペース
	Const MaxItemHeight As Integer = 255 ' ItemHeightの最大値
	
	Sub ListBox2DragEnter(sender As Object, e As DragEventArgs)
		'ドラッグされているデータがpicturebox型か調べ、
		'そうであればドロップ効果をCopyにする
		If e.Data.GetDataPresent(GetType(PictureBox)) Then
			e.Effect = DragDropEffects.Copy
			Debug.Print("enter")
		Else
			'picturebox型でなければ受け入れない
			e.Effect = DragDropEffects.None
		End If
	End Sub
	
	
	Sub ListBox2DragDrop(sender As Object, e As DragEventArgs)
		'ドロップされたデータがPictureBox型か調べる
		If e.Data.GetDataPresent(GetType(PictureBox)) Then
			Dim target As ListBox = CType(sender, ListBox)
			Dim pic As PictureBox = DirectCast(e.Data.GetData(GetType(PictureBox)), PictureBox)
			'ドロップされたデータをリストボックスに追加する ★
			Dim original As Image = pic.image
			Dim thumbnail = createThumbnail(original, _
			ListBox2.ClientSize.Width - spacing * 2, _
			MaxItemHeight - spacing * 2)
			ListBox2.Items.Add(thumbnail) ' 画像の追加
			
			original.Dispose()
		End If
	End Sub
	
	
	Sub PictureBox1MouseDown(sender As Object, e As MouseEventArgs)
		'マウスの左ボタンだけが押されている時のみドラッグできるようにする
		If e.Button = MouseButtons.Left Then
			'ドラッグの準備
			Dim pic As PictureBox = DirectCast(sender, PictureBox)
			'マウスの押された位置を記憶
			mouseDownPoint = New Point(e.X, e.Y)
		Else
			mouseDownPoint = Point.Empty
		End If
	End Sub
	
	
	Sub PictureBox1MouseMove(sender As Object, e As MouseEventArgs)
		If mouseDownPoint <> Point.Empty Then
			'ドラッグとしないマウスの移動範囲を取得する
			Dim moveRect As New Rectangle(mouseDownPoint.X - SystemInformation.DragSize.Width / 2, mouseDownPoint.Y - SystemInformation.DragSize.Height / 2, SystemInformation.DragSize.Width, SystemInformation.DragSize.Height)
			'ドラッグとする移動範囲を超えたか調べる
			If Not moveRect.Contains(e.X, e.Y) Then
				'ドラッグの準備
				Dim pic As PictureBox = DirectCast(sender, PictureBox)
				
				'ドラッグ&ドロップ処理を開始する
				Dim dde As DragDropEffects = pic.DoDragDrop(Me.pictureBox1, DragDropEffects.Copy)
				
				mouseDownPoint = Point.Empty
			End If
		End If
	End Sub
	
	Sub ListBox2DrawItem(sender As Object, e As DrawItemEventArgs)
		If e.Index = -1 Then ' 項目がない場合にも呼び出される
			Return
		End If
		
		e.DrawBackground()
		
		Dim thumbnail As Image = CType(ListBox2.Items(e.Index), Image)
		' 画像を中央に表示
		e.Graphics.DrawImage(thumbnail, _
			e.Bounds.X + (e.Bounds.Width - thumbnail.Width) \ 2, _
			e.Bounds.Y + (e.Bounds.Height - thumbnail.Height) \ 2)
		
		e.DrawFocusRectangle()
	End Sub

	Sub ListBox2MeasureItem(sender As Object, e As MeasureItemEventArgs)
		Dim thumbnail As Image = CType(ListBox1.Items(e.Index), Image)
		e.ItemHeight = thumbnail.Height + spacing * 2
	End Sub
	
	' 幅w、高さh内に収まるようなImageオブジェクトを作成
	Function createThumbnail(ByVal image As Image, ByVal w As Integer, ByVal h As Integer) As Image
		Dim fw As Double = CDbl(w) / CDbl(image.Width)
		Dim fh As Double = CDbl(h) / CDbl(image.Height)
		
		Dim scale As Double = Math.Min(fw, fh)
		Dim nw As Integer = CInt(image.Width * scale /2)
		Dim nh As Integer = CInt(image.Height * scale /2)
		
		Return New Bitmap(image, nw, nh)
	End Function
	
End Class

引用返信 編集キー/
■60692 / inTopicNo.9)  Re[4]: ピクチャーボックス→リストボックスに追加
□投稿者/ やんまー (52回)-(2011/07/15(Fri) 00:57:01)
shu さん



教えていただいたコードの方では、上手くいきました!

ありがとうございます!!!
引用返信 編集キー/
■60693 / inTopicNo.10)  Re[5]: ピクチャーボックス→リストボックスに追加
□投稿者/ すぎさん (1回)-(2011/07/15(Fri) 05:08:40)
No60692 (やんまー さん) に返信

> Dim original As Image = pic.image

> original.Dispose()

originalにpic.imageそのものを割り当てたからうまくいかなかったのではないでしょうか。
これではpic.imageそのものがDisposeされてしまいますよ。
引用返信 編集キー/
■60696 / inTopicNo.11)  Re[5]: ピクチャーボックス→リストボックスに追加
□投稿者/ shu (853回)-(2011/07/15(Fri) 07:54:43)
2011/07/15(Fri) 07:55:15 編集(投稿者)
2011/07/15(Fri) 07:54:54 編集(投稿者)

No60691 (やんまー さん) に返信

> ただ、僕のやった方法だと、何故か、一回しかD&Dできませんでした。。。

・・・
・・・

> 'ドロップされたデータをリストボックスに追加する ★
> Dim original As Image = pic.image
> Dim thumbnail = createThumbnail(original, _
> ListBox2.ClientSize.Width - spacing * 2, _
> MaxItemHeight - spacing * 2)
> ListBox2.Items.Add(thumbnail) ' 画像の追加
>
> original.Dispose()
original.DisposeでPictureBoxのImageを破棄しているからだと思います。
引用返信 編集キー/
■60702 / inTopicNo.12)  Re[6]: ピクチャーボックス→リストボックスに追加
□投稿者/ やんまー (53回)-(2011/07/15(Fri) 13:15:06)
shu さん すぎさん


ありがとうございます。

Disposeを除去したら再追加できるようになりました!

(でも、pic.ImageLocation は相変わらず取得できないです・・・)

もう一つListBoxについて疑問が出てきてしまったのですが、
おかげさまで表題の件は実現できたので一旦解決とさせていただいて、再書き込みさせてください。

ありがとうございました!
解決済み
引用返信 編集キー/
■60711 / inTopicNo.13)  Re[7]: ピクチャーボックス→リストボックスに追加
□投稿者/ shu (855回)-(2011/07/15(Fri) 21:53:50)
No60702 (やんまー さん) に返信
> shu さん すぎさん
>
>
> ありがとうございます。
>
> Disposeを除去したら再追加できるようになりました!
>
> (でも、pic.ImageLocation は相変わらず取得できないです・・・)


PictureBox1.Load("〜")

または

PictureBox1.ImageLocation = "〜"

としなければImageLocationは設定されないです。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -