DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ドラッグにより等間隔にラベルの配置を変更

環境/言語:[Windows XP C# VisualStudio2010]
分類:[.NET]

2012/02/09(Thu) 15:05:05 編集(投稿者)

カスタムコントロールでPanelを作ってあります。
そこにラベルをおき、
ドラッグによりラベルの配置を変更しています。
それを、等間隔に配置したいです。
簡単に言うと、
デスクトップの【アイコンを等間隔に整列】と同じように、
ラベル(デスクトップだとアイコン)を等間隔に配置変更したいです。

今現在、ラベルを自由に配置変更することは出来ました。
ですが、等間隔に配置する方法がわかりません。
また、ラベルとラベルが重なることも禁止です。
何かうまくやる方法はありますでしょうか?
TableLayoutPanelを使えば出来るかな?とも思ったのですが、
よくわかりませんでした・・・
何かありましたら教えていただければと思います。
カスタムコントロール(Panel)のコードです。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace IconFreeArrangementPanel
{
public partial class FreePanel : Panel
{
/// <summary>移動する Control</summary>
private Control target;
private Control[] targetControls;
private Control topLevelControl;

/// <summary>現在のマウスの位置 (画面座標)</summary>
private Point lastMousePosition;
/// <summary>コントロールの移動開始位置</summary>
private Dictionary<Control, Point> startLocations;
/// <summary>移動中かどうか</summary>
private bool capture;

/// <summary>
/// ControlMover を初期化します。
/// </summary>
/// <param name="target">MouseDown(MouseButtons.Left) している Control</param>
public FreePanel(Control target)
{
this.target = target;
this.lastMousePosition = Control.MousePosition;
this.startLocations = new Dictionary<Control, Point>();
this.capture = true;

this.topLevelControl = this.target.TopLevelControl;

this.targetControls = new Control[] { this.target };
this.startLocations.Add(this.target, this.target.Location);

this.AddEventHandler();
}

/// <summary>
/// ControlMover を初期化します。
/// </summary>
/// <param name="target">MouseDown(MouseButtons.Left) している Control</param>
/// <param name="controls">一緒に移動するコントロール</param>
public FreePanel(Control target, params Control[] controls)
: this(target)
{
// controls 内に親コントロールが含まれているなら、親コントロールだけを移動する
List<Control> l = new List<Control>();
Array.Resize(ref controls, controls.Length + 1);
controls[controls.Length - 1] = target;
foreach (Control t in controls) {
bool p = false;

foreach (Control c in controls) {
if (object.ReferenceEquals(t, c)) {
continue;
}

if (this.IsParentControl(t, c) == true) {
p = true;
break;
}
}

if (p == false && l.Contains(t) == false) {
l.Add(t);
}
}

this.targetControls = l.ToArray();
this.startLocations.Clear();
foreach (Control c in this.targetControls) {
this.startLocations.Add(c, c.Location);
}
}

/// <summary>
/// 指定したコントロールが親コントロールかどうかを取得します。
/// </summary>
/// <param name="t">対象のコントロール</param>
/// <param name="c">親コントロールかどうか</param>
private bool IsParentControl(Control t, Control c) {
if (t == c) {
return true;
}

if (t.Parent == null) {
return false;
}

return this.IsParentControl(t.Parent, c);
}

private void AddEventHandler()
{
this.target.KeyDown += FreePanel_KeyDown;
this.target.MouseCaptureChanged += FreePanel_MouseCaptureChanged;
this.target.MouseMove += FreePanel_MouseMove;
this.target.MouseUp += FreePanel_MouseUp;
}

private void RemoveEventHandler()
{
this.target.KeyDown -= FreePanel_KeyDown;
this.target.MouseCaptureChanged -= FreePanel_MouseCaptureChanged;
this.target.MouseMove -= FreePanel_MouseMove;
this.target.MouseUp -= FreePanel_MouseUp;
}

private void FreePanel_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape) {
// 移動前の位置に戻す
foreach (KeyValuePair<Control, Point> pair in this.startLocations) {
pair.Key.Location = pair.Value;
}

this.target.Capture = false;
}
}

private void FreePanel_MouseCaptureChanged(object sender, EventArgs e)
{
if (this.capture == true && this.target.Capture == false) {
// 終了
this.RemoveEventHandler();
this.capture = false;
}
}

private void FreePanel_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (this.capture == true) {
// コントロールを移動
Point mp = Control.MousePosition;
int offsetX = mp.X - this.lastMousePosition.X;
int offsetY = mp.Y - this.lastMousePosition.Y;

this.topLevelControl.SuspendLayout();
foreach (Control c in this.targetControls) {
c.Location = new Point(c.Left + offsetX, c.Top + offsetY);
}
this.topLevelControl.ResumeLayout();

this.lastMousePosition = mp;
}
}

private void FreePanel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
if (this.capture == true) {
// 終了
this.RemoveEventHandler();
this.capture = false;
}
}
}
}
}
■No29806に返信(麻緒さんの記事)

「デスクトップの【アイコンを等間隔に整列】と同じように」ということですと、ListViewコントロールということになりそうですが、ListViewコントロールではダメですか?

自分で整列させるということになりますと、自分でコントロールの位置を計算するということになりますが、お分かりにならないというのはどの点でしょうか?
■No29815に返信(管理人さんの記事)
ありがとうございます。
> 「デスクトップの【アイコンを等間隔に整列】と同じように」ということですと、ListViewコントロールということになりそうですが、ListViewコントロールではダメですか?
ListViewコントロールで出来るのですか?
調べてみます!
ListViewコントロールを調べてみました。
http://www.crystal-creation.com/software/technical-information/programming/c-sharp/sample/draggable-listview.htm
このページからFreeListViewというカスタムコントロールを作成し、
下記のようにプログラミングしました。
そこで質問ですが、FreeListViewの呼び出し方がわかりません。
Form1にFreeListViewを配置し、
Form1_Loadの中で
FreeListView listview = new FreeListView(@"c:\images");
とやったのですが、ListViewが表示されませんでした。
どのようにやればいいのでしょうか?

namespace IconFreeListView
{
public partial class FreeListView : ListView
{
/// <summary>
/// コンストラクタ
/// </summary>
public FreeListView()
{
InitializeComponent();
this.AllowDrop = true;
}

public FreeListView(string imageDir)
: this()
{
string[] jpgFiles =
System.IO.Directory.GetFiles(imageDir, "*.jpg");

int width = 100;
int height = 80;

imageList1.ImageSize = new Size(width, height);
this.LargeImageList = imageList1;

for (int i = 0; i < jpgFiles.Length; i++)
{
Image original = Bitmap.FromFile(jpgFiles[i]);
Image thumbnail = this.createThumbnail(original, width, height);

imageList1.Images.Add(thumbnail);
this.Items.Add(jpgFiles[i], i);

original.Dispose();
thumbnail.Dispose();
}
}

/// <summary>
/// 幅w、高さhのImageオブジェクトを作成
/// </summary>
/// <param name="image"></param>
/// <param name="w"></param>
/// <param name="h"></param>
/// <returns></returns>
Image createThumbnail(Image image, int w, int h)
{
Bitmap canvas = new Bitmap(w, h);

Graphics g = Graphics.FromImage(canvas);
g.FillRectangle(new SolidBrush(Color.White), 0, 0, w, h);

float fw = (float)w / (float)image.Width;
float fh = (float)h / (float)image.Height;

float scale = Math.Min(fw, fh);
fw = image.Width * scale;
fh = image.Height * scale;

g.DrawImage(image, (w - fw) / 2, (h - fh) / 2, fw, fh);
g.Dispose();

return canvas;
}

/// <summary>
/// ドラッグを開始
/// </summary>
/// <param name="e"></param>
protected override void OnItemDrag(ItemDragEventArgs e)
{
base.OnItemDrag(e);

if (e.Button == MouseButtons.Left)
{
Point mousePosition = this.PointToClient(Control.MousePosition);

// ドラッグするイメージのサイズを求める
Rectangle imageRectangle = new Rectangle();
foreach (ListViewItem item in this.SelectedItems)
{
if (imageRectangle.IsEmpty)
{
imageRectangle = item.Bounds;
}
else
{
imageRectangle = Rectangle.Union(imageRectangle, item.Bounds);
}
}

Rectangle cursorNearRectangle = new Rectangle(mousePosition.X - 128, mousePosition.Y - 128, 256, 256);
imageRectangle.Intersect(cursorNearRectangle);

// ドラッグするイメージを作成する
Bitmap bitmap = new Bitmap(imageRectangle.Width, imageRectangle.Height);
Graphics graphics = Graphics.FromImage(bitmap);

foreach (ListViewItem item in this.SelectedItems)
{
Point itemPosition = item.Position;
itemPosition.Offset(-imageRectangle.X, -imageRectangle.Y);

using (Brush fontBrush = new SolidBrush(item.ForeColor))
{
graphics.DrawString(item.Text, item.Font, fontBrush, itemPosition);
}
}

this.imageList1.Images.Clear();

this.imageList1.ImageSize = bitmap.Size;
this.imageList1.Images.Add(bitmap);

graphics.Dispose();


Point dragPoint = new Point(mousePosition.X - imageRectangle.X, mousePosition.Y - imageRectangle.Y);
Win32ImageList.ImageList_BeginDrag(this.imageList1.Handle, 0, dragPoint.X, dragPoint.Y);


ListViewItem[] dragData = new ListViewItem[this.SelectedItems.Count];
this.SelectedItems.CopyTo(dragData, 0);

DragDropEffects dragDropEffect = DoDragDrop(dragData, DragDropEffects.Move);

// ドラッグ後の処理を行う
if (dragDropEffect == DragDropEffects.Move)
{
BeginUpdate();
foreach (ListViewItem item in dragData)
{
this.Items.Remove(item);
}
EndUpdate();

Win32ImageList.ImageList_EndDrag();
}
}
}

/// <summary>
/// コントロール外でもイメージを表示
/// </summary>
/// <param name="drgevent"></param>
protected override void OnDragEnter(DragEventArgs drgevent)
{
base.OnDragEnter(drgevent);

IntPtr ownerWindow = Win32ImageList.GetDesktopWindow();
Win32ImageList.ImageList_DragEnter(ownerWindow, Cursor.Position.X, Cursor.Position.Y);


if (drgevent.Data.GetDataPresent(typeof(ListViewItem[])))
{
drgevent.Effect = DragDropEffects.Move;
}
else
{
drgevent.Effect = DragDropEffects.None;
}
}

/// <summary>
/// コントロール外へドラッグたときに画実行する
/// </summary>
/// <param name="qcdevent"></param>
protected override void OnQueryContinueDrag(QueryContinueDragEventArgs qcdevent)
{
base.OnQueryContinueDrag(qcdevent);

Win32ImageList.ImageList_DragMove(Cursor.Position.X, Cursor.Position.Y);


const int MouseRightButton = 2;
if ((qcdevent.KeyState & MouseRightButton) == MouseRightButton)
{
qcdevent.Action = DragAction.Cancel;
}
}

/// <summary>
/// イメージの表示を終了
/// </summary>
/// <param name="drgevent"></param>
protected override void OnDragDrop(DragEventArgs drgevent)
{
base.OnDragDrop(drgevent);

IntPtr ownerWindow = Win32ImageList.GetDesktopWindow();
Win32ImageList.ImageList_DragLeave(ownerWindow);


if (drgevent.Data.GetDataPresent(typeof(ListViewItem[])))
{
ListViewItem[] dragData = (ListViewItem[])drgevent.Data.GetData(typeof(ListViewItem[]));

foreach (ListViewItem listViewItem in dragData)
{
this.Items.Add((ListViewItem)listViewItem.Clone());
}
Invalidate(false);
}
}
}

public static class Win32ImageList
{
[DllImport("comctl32.dll")]
public static extern bool ImageList_BeginDrag(
IntPtr himlTrack, // イメージリストのハンドル
int iTrack, // ドラッグするイメージの番号
int dxHotspot, // ドラッグ位置 (イメージ位置との相対座標)
int dyHotspot //
);

[DllImport("comctl32.dll")]
public static extern bool ImageList_DragEnter(
IntPtr hwndLock, // ドラッグするイメージの親となるウィンドウのハンドル
int x, // ドラッグするイメージの表示位置 (ウィンドウ位置との相対座標)
int y //
);

[DllImport("comctl32.dll")]
public static extern bool ImageList_DragLeave(
IntPtr hwndLock // ドラッグするイメージの親となるウィンドウのハンドル
);

[DllImport("comctl32.dll")]
public static extern bool ImageList_DragMove(
int x, // ドラッグするイメージの表示位置 (ウィンドウ位置との相対座標)
int y //
);

[DllImport("comctl32.dll")]
public static extern void ImageList_EndDrag();


[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
}
}
■No29821に返信(麻緒さんの記事)

> Form1にFreeListViewを配置し、
> Form1_Loadの中で
> FreeListView listview = new FreeListView(@"c:\images");
> とやったのですが、ListViewが表示されませんでした。

フォームデザイナで配置したFreeListViewも表示されませんでしたか?もしそうであれば、私にも理由が分かりません。

フォームデザイナで配置したFreeListViewとlistviewは別物です。ですので、2つ表示するのでなければ、どちらかのみにしてください。もしFreeListViewをフォームデザイナで配置したいのであれば、コンストラクタにパラメータがなくてもいいようにしてください(プロパティかメソッドにしてください)。もしlistviewの方を表示したいのであれば、

コントロールを実行時に作成する
http://dobon.net/vb/dotnet/control/addcontrol.html

を参考にしてください。
2012/02/14(Tue) 09:05:53 編集(投稿者)
2012/02/14(Tue) 09:05:24 編集(投稿者)

■No29826に返信(管理人さんの記事)
ありがとうございます。
> フォームデザイナで配置したFreeListViewも表示されませんでしたか?
フォームデザイナのFreeListViewは表示されていました。

> もしlistviewの方を表示したいのであれば、
パラメータを使いたいのでlistviewの方を表示するよう
下記のようにコーディングしましたが表示されませんでした。
調べてみたのですが原因がわかりません。
引き続き調べてみますが
原因がわかるようでしたらよろしくお願いします。

FreeListView listview = new FreeListView(@"c:\images");

//フォームのレイアウトロジックを中断する
this.SuspendLayout();
listview.AllowDrop = true;
listview.Dock = System.Windows.Forms.DockStyle.Fill;
listview.Location = new System.Drawing.Point(0, 0);
listview.Name = "listview";
listview.Size = new System.Drawing.Size(849, 503);
listview.TabIndex = 0;
listview.UseCompatibleStateImageBehavior = false;

//フォームのレイアウトロジックを再開する
this.ResumeLayout(false);
2012/02/14(Tue) 13:11:50 編集(投稿者)

いろいろ調べてみたのですがわかりませんでした。
なので、ListViewは使わず、
自分自身で計算して等間隔に表示するように修正しました。
等間隔に表示は思い通りの動作をしたのですが、
コントロールが重ならないようにすることは可能でしょうか?
マウスをはなしたときにコントロールが下にある
というのはイベントなどでわかりますか?
イベントがない場合、
ひとつひとつコントロールのLocationを調べないといけないでしょうか?
内容を整理すると、
・コントロールをD&D(ドラッグ&ドロップ)で自由に移動できる
・何らかのアクション(ボタンクリック・メニューアイテムクリック)でコントロールを整列できる
ということだと思いますが、

> コントロールが重ならないようにすることは可能でしょうか?

とは、コントロールをD&Dで移動する際のことでしょうか?
そうであるならば、例えば、コントロールをドロップしようとした時、そのコントロールの範囲内に別のコントロールがある場合、
どのようにしたいですか?
■No29836に返信(ズッカさんの記事)
ありがとうございます。
>>コントロールが重ならないようにすることは可能でしょうか?
> とは、コントロールをD&Dで移動する際のことでしょうか?
はい。移動したときです。

> そうであるならば、例えば、コントロールをドロップしようとした時、そのコントロールの範囲内に別のコントロールがある場合、
> どのようにしたいですか?
コントロール(Contorl_A)の範囲内に別のコントロール(Contorl_B)がある場合、
Control_Bの範囲外の一番近い場所にControl_A配置したいです。
下記の図は、Control_Aの範囲内にControl_Bがドロップされた場合
Control_Bの配置はB1もしくはB2の位置に配置したいです。
____
|AB1  |
|B2   |
|____|
> コントロール(Contorl_A)の範囲内に別のコントロール(Contorl_B)がある場合、
> Control_Bの範囲外の一番近い場所にControl_A配置したいです。

なるほど、そうですか。
ただ、この場合、ドロップしようとしたところにたくさんのコントロールが密集している場合、どこに置くかという仕様や、
空き地を探すロジックなどはよく考えないといけませんね。
ドラッグドロップのイベントで置き場所を確定することになろうかと思いますが、結局のところ、
その時に各コントロールの位置をループで回してすべて見てあげる必要がありそうですね。
■No29839に返信(ズッカさんの記事)
ありがとうございます。
> その時に各コントロールの位置をループで回してすべて見てあげる必要がありそうですね。
やはりひとつひとつ見る必要があるようですね・・・。
大変ですが頑張ってみたいと思います。
ちょっと、■No29828のコードが気になったのですが、
もしかして、この(FreeListView) listviewは、フォームにAddしていない、つまり、

this.Controls.Add(listview);

を行っていないので表示されない、というオチはないでしょうか?
(ちゃんとAddしているのであれば、この書き込みは無視してください。)
■No29844に返信(ズッカさんの記事)
ありがとうございます。
> ちょっと、■No29828のコードが気になったのですが、
> もしかして、この(FreeListView) listviewは、フォームにAddしていない、つまり、
>
> this.Controls.Add(listview);
>
> を行っていないので表示されない、というオチはないでしょうか?
> (ちゃんとAddしているのであれば、この書き込みは無視してください。)

this.Controls.Add(listview);
を行うとエラーになってしまいます。

エラー内容:
ArgumentExceptionはハンドルされませんでした。
使用されたパラメーターが有効ではありません。

ユーザーコントロールはAddしなくてもいいのかな?
と思い無視していたのですが・・・
やっぱり必要だったのですね・・・笑;
そうですか。
FreeListViewクラスがどのように定義されているか分かりませんが、
this.Controls.Add(listview);の箇所で例外が発生しているのでしょうか?
スタックトレースはどのようになっているのでしょうか?
■No29849に返信(ズッカさんの記事)
ありがとうございます。
返信が遅くなり申し訳ありません。

> FreeListViewクラスがどのように定義されているか分かりませんが、
No29821がFreeListViewクラスの定義です。

> this.Controls.Add(listview);の箇所で例外が発生しているのでしょうか?
上記の箇所で例外が発生しています。

> スタックトレースはどのようになっているのでしょうか?
下記でよろしいでしょうか?
補足:
Form1のbutton3をクリックしたときに
Form2が表示され、そこでFreeListViewが表示されます。

  場所 System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
場所 System.Environment.get_StackTrace()
場所 IconFreeListView.Form2.Form2_Load(Object sender, EventArgs e) 場所 C:\IconFreeListView\IconFreeListView\Form2.cs:行 43
場所 System.Windows.Forms.Form.OnLoad(EventArgs e)
場所 System.Windows.Forms.Form.OnCreateControl()
場所 System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
場所 System.Windows.Forms.Control.CreateControl()
場所 System.Windows.Forms.Control.WmShowWindow(Message& m)
場所 System.Windows.Forms.Control.WndProc(Message& m)
場所 System.Windows.Forms.ScrollableControl.WndProc(Message& m)
場所 System.Windows.Forms.Form.WmShowWindow(Message& m)
場所 System.Windows.Forms.Form.WndProc(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
場所 System.Windows.Forms.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
場所 System.Windows.Forms.Control.SetVisibleCore(Boolean value)
場所 System.Windows.Forms.Form.SetVisibleCore(Boolean value)
場所 System.Windows.Forms.Control.Show()
場所 IconFreeListView.Form1.button3_Click(Object sender, EventArgs e) 場所 C:\IconFreeListView\IconFreeListView\Form1.cs:行 154
場所 System.Windows.Forms.Control.OnClick(EventArgs e)
場所 System.Windows.Forms.Button.OnClick(EventArgs e)
場所 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
場所 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
場所 System.Windows.Forms.Control.WndProc(Message& m)
場所 System.Windows.Forms.ButtonBase.WndProc(Message& m)
場所 System.Windows.Forms.Button.WndProc(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
場所 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
場所 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
場所 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
場所 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
場所 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
場所 System.Windows.Forms.Application.Run(Form mainForm)
場所 IconFreeListView.Program.Main() 場所 C:\IconFreeListView\IconFreeListView\Program.cs:行 18
場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
場所 System.Threading.ThreadHelper.ThreadStart()
>> FreeListViewクラスがどのように定義されているか分かりませんが、
> No29821がFreeListViewクラスの定義です。

ということは、可能性として、引数ありのコンストラクタで、partialな部分、つまり
InitializeComponent();がうまく呼び出されているかどうか、確認が必要ですね。
■No29853に返信(ズッカさんの記事)
ありがとうございます。
> ということは、可能性として、引数ありのコンストラクタで、partialな部分、つまり
> InitializeComponent();がうまく呼び出されているかどうか、確認が必要ですね。
@FreeListView listview = new FreeListView(@"c:\images");
A引数なしコンストラクタ
BInitializeComponent();
C引数ありコンストラクタ
の順番で呼び出され、
ブレークポイントを貼って確認しましたが
InitializeComponent();は一行一行実行されていることが確認出来ました。
そうですか。
this.Controls.Add(listview);はForm2_Loadで行っているので、その部分を見ないと何とも言えませんが、
デザイナでフォーム上に配置したFreeListViewはきちんと表示されている(当然追加されている)とのことですので、
考え方を変えて、いっそのこと、デザイナでFreeListViewを追加しておいて、引数は後で
メソッドなりプロパティなりで与えた方がいいかも知れません。

ただ、このFreeListViewを使うことで根本の課題(重ならないコントロール)が解決すればいいのですが...
本題から逸れていってしまって申し訳ないです。
2012/02/15(Wed) 16:37:42 編集(投稿者)

/// <summary>
/// コンストラクタ
/// </summary>
public FreeListView()
{
 InitializeComponent();
}

public FreeListView(string imageDir)
: this()
{
 string[] jpgFiles =
  System.IO.Directory.GetFiles(imageDir, "*.jpg");

 int width = 100;
 int height = 80;

 imageList1.ImageSize = new Size(width, height);
 this.LargeImageList = imageList1;

 for (int i = 0; i < jpgFiles.Length; i++)
 {
  Image original = Bitmap.FromFile(jpgFiles[i]);
  Image thumbnail = this.createThumbnail(original, width, height);

  imageList1.Images.Add(thumbnail);
  this.Items.Add(jpgFiles[i], i);

  original.Dispose();
  thumbnail.Dispose();※
 }
}

※の部分が原因だったみたいで
コメントアウトしたら実行できました。
ご迷惑おかけしました。
■No29856に返信(ズッカさんの記事)
ありがとうございます。
> ただ、このFreeListViewを使うことで根本の課題(重ならないコントロール)が解決すればいいのですが...
解決できるようにがんばってみます!

> 本題から逸れていってしまって申し訳ないです。
いえいえ。問題を無視して進めた私が悪いので・・・
解決できて良かったと思っています。
ありがとうございました。

DOBON.NET | プログラミング道 | プログラミング掲示板