WPFのListViewにファイルのリストがあります。ユーザーはファイルをリストビューにドラッグでき、現在、ファイルはリストの最後に追加されています。ユーザーがファイルをドロップした場所のリストビューにファイルを挿入することは可能ですか?
3 に答える
WPFは、実際にはそのように使用するようには設計されていません。ListViewItemを直接ListViewにブルートフォースで追加することもできますが、実際に機能するはずの方法は、ある種のコレクションがあり(ObservableCollection<FileInfo>
うまく機能する)、ListViewのItemsSourceプロパティをそのコレクションにバインドすることです。
そうすれば答えは簡単です。Addメソッドの代わりに、インデックスを取得するコレクションのInsertメソッドを使用します。
マウスイベントが発生したListViewItemを見つけるには、VisualTreeHelper.HitTestメソッドを使用できます。
私の観点からは、テンプレート化されたアイテムを使用したときは少し注意が必要です。私はそれと少し戦っています。DraggableListBoxで動作するユースケースを共有しています。しかし、同じソリューションがListBoxコントロールで機能すると思います。
最初に、ListItem要素を提供できる依存関係オブジェクト拡張を作成しました。
public static class WpfDomHelper
{
public static T FindParent<T>(this DependencyObject child) where T : DependencyObject
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
T parent = parentObject as T;
if (parent != null)
return parent;
else
return FindParent<T>(parentObject);
}
}
次に、宛先ListBoxItemsの特定のドロップY位置に従ってアイテムを挿入(追加)するドロップロジックを実装しました。
private void Grid_Drop(object sender, DragEventArgs e)
{
int dropIndex = -1; // default position directong to add() call
// checking drop destination position
Point pt = e.GetPosition((UIElement)sender);
HitTestResult result = VisualTreeHelper.HitTest(this, pt);
if (result != null && result.VisualHit != null)
{
// checking the object behin the drop position (Item type depend)
var theOne = result.VisualHit.FindParent<Microsoft.TeamFoundation.Controls.WPF.DraggableListBoxItem>();
// identifiing the position according bound view model (context of item)
if (theOne != null)
{
//identifing the position of drop within the item
var itemCenterPosY = theOne.ActualHeight / 2;
var dropPosInItemPos = e.GetPosition(theOne);
// geting the index
var itemIndex = tasksListBox.Items.IndexOf(theOne.Content);
// decission if insert before or below
if (dropPosInItemPos.Y > itemCenterPosY)
{ // when drag is gropped in second half the item is inserted bellow
itemIndex = itemIndex + 1;
}
dropIndex = itemIndex;
}
}
.... here create the item .....
if (dropIndex < 0)
ViewModel.Items.Add(item);
else
ViewModel.Items.Insert(dropIndex, item);
e.Handled = true;
}
したがって、このソリューションは私のテンプレートDraggableListBoxViewで機能します。同じソリューションが、標準のListBoxViewで機能する必要があると思います。幸運を
あなたはこれを行うことができます。少し手間がかかりますが、できます。そこにはいくつかのデモがあります。これがCodeProjectのデモです。この特定のものは、 JoshSmithとして知られているwpfマスターによるものです。それはおそらくあなたが探しているものとは正確には一致しませんが、かなり近いはずです。