2010-08-20 93 views
11

我有一个ItemsControl绑定到一个整数ObservableCollection的DataTemplate。ItemsControl拖放

<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都被传入事件。

+0

嗨。我看到@ Golbin提供的链接。但这个例子是关于药物和2个小组之间的下降。实际上我想像你一样在ONE'ItemsControl'中重新排序。你能帮我吗?你能把你的解决方案代码放在这里吗或者你能给我一些建议吗?提前致谢。 – 2012-06-21 15:56:34

+0

@ king.net你还需要关于这个问题的例子吗?这里是一个有关的列表框 - http://stackoverflow.com/questions/36642622/rearrange-customcontrol-inside-wrappanel-in-wpf-c-sharp。如果你需要我可以尝试适应这个数据模板... – Ilan 2016-04-19 06:44:16

回答

5

下面是我如何做的一个例子。

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每一个项目是一个ButtonButtonclick我也有做一些动作。 你的情况相对容易。

拖动&对许多开发人员来说拖放可能会造成混淆。但低于 是一些关键点是如何做到这一点:

  1. 使用PreviewMouseMove事件真正开始一拖在处理程序使用DragDrop.DoDragDrop事件来提高DragDrop相关 事件和Cursorssender自变量是 捕获鼠标当前在这种情况下UIElement被 被拖动的元素。

  2. 如果要换在其上Mouse正在拖动视觉元素的使用DragEnter & DragOver事件。 sender 参数是目前拖过/只是 结束拖拽情况的元素。使用Drop事件来处理被丢弃的元素。 sender参数是Drop发生的元素。使用DataObject对象在这些事件之间传递信息。 SetData该类的方法用于在此添加数据。此方法 有两个参数,它们的工作方式如同key-value对。一旦设置你 可以通过使用 GetData方法通过传递key作为参数在下一次调用事件DragDrop中获取此数据。 (即 e.Data.GetData("Source")

Here是一个相对柱。

+0

感谢你,Kylo。我正在寻找一个更简单的拖放实现来使用,并且你的文章给了我所需的所有提示,以便让它在我的应用程序上运行! – 2016-10-25 17:21:18

+0

@HDL_CinC_Dragon欢迎您:) – 2016-11-03 06:21:48