2010-08-20 61 views
11

Tôi có một ItemsControl với một DataTemplate được ràng buộc với một ObservableCollection của số nguyên.ItemsControl Kéo và Thả

<ItemsControl Name="DimsContainer" ItemTemplate="{StaticResource DimensionsTemplate}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

Và trong Tài nguyên Windows:

<Window.Resources> 
    <DataTemplate x:Key="DimensionsTemplate" > 
     <TextBlock Text="{Binding}" 
         Padding="5" 
         VerticalAlignment="Center" 
         FontSize="32"/> 
    </DataTemplate> 
</Window.Resources> 

Tôi đang cố gắng để thực hiện khả năng kéo và thả các mục trong ItemsControl (ví dụ: để có thể sắp xếp lại các số nguyên). Có ai có một ví dụ đơn giản về làm thế nào để làm điều này? Tôi đã kết nối các sự kiện PreviewMouseMove, DragEnter và Drop. Vấn đề là tôi không thể tìm ra cách để xác định mục nào đang được kéo và nơi nó được kéo đến. Dường như toàn bộ ItemsControl được chuyển vào các sự kiện.

+0

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. –

+0

@ 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

Trả lời

5

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 Buttonclick 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 đó:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

+0

Cảm ơn điều này, Kylo. Tôi đã tìm kiếm một thực hiện kéo và thả đơn giản hơn để sử dụng và bài đăng của bạn đã cho tôi tất cả các gợi ý tôi cần để làm cho nó hoạt động trên ứng dụng của tôi! –

+0

@HDL_CinC_Dragon bạn được chào đón :) –