我有一个 ItemsControl,它带有一个绑定(bind)到整数 ObservableCollection 的 DataTemplate。
<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
在 Windows 资源中:
<Window.Resources>
<DataTemplate x:Key="DimensionsTemplate" >
<TextBlock Text="{Binding}"
Padding="5"
VerticalAlignment="Center"
FontSize="32"/>
</DataTemplate>
</Window.Resources>
我正在尝试实现在 ItemsControl 中拖放项目的能力(即能够对整数重新排序)。有没有人有一个简单的例子来说明如何做到这一点?我连接了 PreviewMouseMove、DragEnter 和 Drop 事件。问题是我无法弄清楚如何确定正在拖动哪个项目以及它被拖到哪里。似乎整个 ItemsControl 都传递到了事件中。
最佳答案
这是我如何完成的示例。
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>
View 模型:
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()); }
}
}
事件:
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
我也要做一些 Action 。 你的情况相对简单。
Drag & Drop can be confusing for many developers. But below are the some key points how to do it:
Use
PreviewMouseMove
event to actually start a drag and in handler useDragDrop.DoDragDrop
event to raiseDragDrop
related events andCursors
.sender
argument is the element that has captured the mouse currently in this case theUIElement
that is being dragged.Use
DragEnter
&DragOver
event if want to change the visual of element over which theMouse
is currently dragging.sender
argument is the element that has currently dragged over / that just ended drag over situation.Use
Drop
event to handle the dropped element.sender
argument is the element on which the Drop happened.Use
DataObject
object to pass info between these events.SetData
method of the class is used to add data in this. This method has two arguments, and they work likekey-value
pair. Once set you can get this data in next called event ofDragDrop
by usingGetData
method by passing thekey
as argument. (i.e.e.Data.GetData("Source")
)
Here是相关帖子。
关于c# - ItemsControl 拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3534958/