我有一个带有 DataTemplate 的 ItemsControl,它绑定到整数的 ObservableCollection.
I have an ItemsControl with a DataTemplate that is bound to an ObservableCollection of integers.
<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
在 Windows 资源中:
And in the Windows Resources:
<Window.Resources>
<DataTemplate x:Key="DimensionsTemplate" >
<TextBlock Text="{Binding}"
Padding="5"
VerticalAlignment="Center"
FontSize="32"/>
</DataTemplate>
</Window.Resources>
我正在尝试实现在 ItemsControl 中拖放项目的能力(即能够对整数重新排序).有没有人有一个简单的例子来说明如何做到这一点?我连接了 PreviewMouseMove、DragEnter 和 Drop 事件.问题是我无法弄清楚如何确定正在拖动哪个项目以及将其拖动到哪里.似乎整个 ItemsControl 都被传递到了事件中.
I'm trying to implement the ability to drag and drop items within the ItemsControl (i.e. to be able to reorder the integers). Does anyone have a simple example of how to do this? I hooked up the PreviewMouseMove, DragEnter and Drop events. The problem is that I can't figure out how to determine which item is being dragged and where it is dragged to. It seems that the entire ItemsControl gets passed into the events.
这是我如何做到的示例.
Here is an example how I've done it.
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()); }
}
}
事件:
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 我也得做一些动作.你的案子比较简单.
Above example is a little complex cause every item of list is a Button and on Button click I also have to do some action. Your case is relatively easy.
拖动 &Drop 可能会让许多开发人员感到困惑.但在下面是一些关键点如何做到这一点:
Drag & Drop can be confusing for many developers. But below are the some key points how to do it:
使用 PreviewMouseMove 事件实际开始拖动,并在处理程序中使用 DragDrop.DoDragDrop 事件引发 DragDrop 相关事件和 游标.sender 参数是具有在这种情况下,当前捕获的鼠标 UIElement 是被拖了.
Use PreviewMouseMove event to actually start a drag and in handler use DragDrop.DoDragDrop event to raise DragDrop related
events and Cursors. sender argument is the element that has
captured the mouse currently in this case the UIElement that is
being dragged.
使用 DragEnter &DragOver 事件,如果想要更改 Mouse 当前拖动的元素的视觉效果.发件人参数是当前拖过/的元素结束拖拽情况.
Use DragEnter & DragOver event if want to change the visual of element over which the Mouse is currently dragging. sender
argument is the element that has currently dragged over / that just
ended drag over situation.
使用 Drop 事件来处理被放置的元素.sender 参数是 Drop 发生的元素.
Use Drop event to handle the dropped element. sender argument is the element on which the Drop happened.
使用 DataObject 对象在这些事件之间传递信息.类的SetData 方法用于在其中添加数据.这种方法有两个参数,它们像 key-value 对一样工作.一旦设置你可以通过使用在 DragDrop 的下一个调用事件中获取此数据GetData 方法,通过传递 key 作为参数.(IE.e.Data.GetData("Source"))
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 like key-value pair. Once set you
can get this data in next called event of DragDrop by using
GetData method by passing the key as argument. (i.e.
e.Data.GetData("Source"))
这里是一个相对的帖子.
这篇关于ItemsControl 拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
读取 XML 时忽略空格Ignore whitespace while reading XML(读取 XML 时忽略空格)
带有检查空元素的 XML 到 LINQXML to LINQ with Checking Null Elements(带有检查空元素的 XML 到 LINQ)
在 C# 中读取带有未闭合标签的 XMLReading XML with unclosed tags in C#(在 C# 中读取带有未闭合标签的 XML)
在 C# 中使用 Html 敏捷性解析表格、单元格Parsing tables, cells with Html agility in C#(在 C# 中使用 Html 敏捷性解析表格、单元格)
使用 LINQ 从 xml 中删除元素delete element from xml using LINQ(使用 LINQ 从 xml 中删除元素)
解析格式错误的 XMLParse malformed XML(解析格式错误的 XML)