2010-08-20 22 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