Dưới đây là ví dụ về cách tôi đã thực hiện.
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>
ViewModel:
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()); }
}
}
Thậm chí 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);
}
}
Ví dụ ở trên là một nguyên nhân phức tạp chút mỗi mục của list
là một Button
và trên Button
click
Tôi cũng phải làm một số hành động. Trường hợp của bạn tương đối dễ dàng.
Kéo & Thả có thể gây nhầm lẫn cho nhiều nhà phát triển. Nhưng dưới đây là một số điểm chính như thế nào để làm điều đó:
Sử dụng PreviewMouseMove
kiện để thực sự bắt đầu một kéo và trong xử lý sử dụng DragDrop.DoDragDrop
kiện để nâng cao DragDrop
liên quan sự kiện và Cursors
. Đối số sender
là phần tử có đã chụp chuột hiện tại trong trường hợp này là UIElement
là đang được kéo.
Sử dụng DragEnter
& DragOver
kiện nếu muốn thay đổi hình ảnh của nguyên tố trên mà Mouse
hiện đang kéo. Đối số sender
là phần tử hiện đã được kéo qua/chỉ kết thúc kéo qua tình huống.
Sử dụng sự kiện Drop
để xử lý phần tử đã bị xóa. Đối số sender
là yếu tố mà Drop đã xảy ra.
Sử dụng đối tượng DataObject
để chuyển thông tin giữa các sự kiện này. SetData
phương pháp của lớp được sử dụng để thêm dữ liệu trong này.Phương thức này có hai đối số và chúng hoạt động như cặp key-value
. Sau khi đặt bạn có thể nhận dữ liệu này trong sự kiện được gọi là DragDrop
tiếp theo bằng cách sử dụng phương pháp GetData
bằng cách chuyển đối số key
làm đối số. (Ví dụ: e.Data.GetData("Source")
)
Here là một bài tương đối.
Xin chào. Tôi thấy liên kết được cung cấp của @ Golbin. Nhưng ví dụ là về thuốc và thả giữa 2 bảng. thực sự tôi muốn quay lại ONE ONE ItemsControl' giống như bạn. Bạn co thể giup tôi được không? Bạn có thể đặt mã giải pháp của mình ở đây không? Hoặc bạn có thể gợi ý cho tôi một số hướng dẫn không? Cảm ơn trước. –
@ king.net bạn vẫn cần ví dụ liên quan đến vấn đề này? đây là một liên quan đến hộp danh sách - http://stackoverflow.com/questions/36642622/rearrange-customcontrol-inside-wrappanel-in-wpf-c-sharp. Nếu bạn cần tôi có thể cố gắng để thích nghi điều này cho các mẫu dữ liệu ... – Ilan