下面是我如何做的一個例子。
XAML:
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<ScrollViewer>
<ListView ItemsSource="{Binding MyData}" HorizontalAlignment="Stretch" Name="listview" ScrollViewer.PanningMode="VerticalOnly">
<ListView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
Margin="5 2" Width="150" Height="50"
FontSize="30" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Resources>
<Style TargetType="Button">
<EventSetter Event="PreviewMouseMove" Handler="PreviewMouseMove" />
<EventSetter Event="Drop" Handler="Drop" />
<Setter Property="AllowDrop" Value="True" />
</Style>
</ListView.Resources>
</ListView>
</ScrollViewer>
</Grid>
視圖模型:
class MyViewModel
{
public MyViewModel()
{
MyCommand = new ICommandImplementation();
}
public ObservableCollection<string> MyData
{
get
{
return new ObservableCollection<string>(new string[]{
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"
});
}
}
public ICommand MyCommand { get; private set; }
private class ICommandImplementation : ICommand
{
public bool CanExecute(object parameter) { return true; }
public event EventHandler CanExecuteChanged;
public void Execute(object parameter) { System.Windows.MessageBox.Show("Button clicked! " + (parameter ?? "").ToString()); }
}
}
即使TS:
private void Drop(object sender, DragEventArgs e)
{
var source = e.Data.GetData("Source") as string;
if (source != null)
{
int newIndex = listview.Items.IndexOf((sender as Button).Content);
var list = listview.ItemsSource as ObservableCollection<string>;
list.RemoveAt(list.IndexOf(source));
list.Insert(newIndex, source);
}
}
private void PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Task.Factory.StartNew(new Action(() =>
{
Thread.Sleep(500);
App.Current.Dispatcher.BeginInvoke(new Action(() =>
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var data = new DataObject();
data.SetData("Source", (sender as Button).Content);
DragDrop.DoDragDrop(sender as DependencyObject, data, DragDropEffects.Move);
e.Handled = true;
}
}), null);
}), CancellationToken.None);
}
}
上面的例子是一個有點複雜原因list
每一個項目是一個Button
和Button
click
我也有做一些動作。 你的情況相對容易。
拖動&對許多開發人員來說拖放可能會造成混淆。但低於 是一些關鍵點是如何做到這一點:
使用PreviewMouseMove
事件真正開始一拖在處理程序使用DragDrop.DoDragDrop
事件來提高DragDrop
相關 事件和Cursors
。 sender
自變量是 捕獲鼠標當前在這種情況下UIElement
被 被拖動的元素。
如果要換在其上Mouse
正在拖動視覺元素的使用DragEnter
& DragOver
事件。 sender
參數是目前拖過/只是 結束拖拽情況的元素。使用Drop
事件來處理被丟棄的元素。 sender
參數是Drop發生的元素。使用DataObject
對象在這些事件之間傳遞信息。 SetData
該類的方法用於在此添加數據。此方法 有兩個參數,它們的工作方式如同key-value
對。一旦設置你 可以通過使用 GetData
方法通過傳遞key
作爲參數在下一次調用事件DragDrop
中獲取此數據。 (即 e.Data.GetData("Source")
)
Here是一個相對柱。
嗨。我看到@ Golbin提供的鏈接。但這個例子是關於藥物和2個小組之間的下降。實際上我想像你一樣在ONE'ItemsControl'中重新排序。你能幫我嗎?你能把你的解決方案代碼放在這裏嗎或者你能給我一些建議嗎?提前致謝。 – 2012-06-21 15:56:34
@ king.net你還需要關於這個問題的例子嗎?這裏是一個有關的列表框 - http://stackoverflow.com/questions/36642622/rearrange-customcontrol-inside-wrappanel-in-wpf-c-sharp。如果你需要我可以嘗試適應這個數據模板... – Ilan 2016-04-19 06:44:16