2016-12-26 92 views
0

初學者在這裏。WPF從列表框中拖放對象

我試圖創建一個用戶控件與在其他控制一個列表框,我想這個列表框允許拖放到該用戶控件的其他類似的實例。

這是另一個我想拖動對象,從一個列表框下拉:

[Serializable] 
public class ListBoxFileName : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 

    private string FileNameValue; 
    public string FileName 
    { 
     get { return this.FileNameValue; } 

     set 
     { 
      if (value != this.FileNameValue) 
      { 
       this.FileNameValue = value; 
       NotifyPropertyChanged("FileName"); 
      } 
     } 
    } 

    private bool FileIsSelectedValue; 
    public bool FileIsSelected 
    { 
     get { return this.FileIsSelectedValue; } 

     set 
     { 
      if (value != this.FileIsSelectedValue) 
      { 
       this.FileIsSelectedValue = value; 
       NotifyPropertyChanged("FileIsSelected"); 
      } 
     } 
    } 
} 

這裏是我如何處理拖放:

private ListBoxItem _dragged; 

    private void FileNameList_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     if (_dragged != null) 
      return; 

     UIElement element = FileNameList.InputHitTest(e.GetPosition(FileNameList)) as UIElement; 
     while (element != null) 
     { 
      if (element is ListBoxItem) 
      { 
       _dragged = (ListBoxItem)element; 
       break; 
      } 
      element = VisualTreeHelper.GetParent(element) as UIElement; 
     } 
    } 


    private void Window_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (_dragged == null) 
      return; 
     if (e.LeftButton == MouseButtonState.Released) 
     { 
      _dragged = null; 
      return; 
     } 
     DataObject obj = new DataObject(DataFormats.Serializable, _dragged); 
     DragDrop.DoDragDrop(_dragged, obj, DragDropEffects.All); 
    } 

    private void FileNameList_DragEnter(object sender, DragEventArgs e) 
    { 
     if (_dragged == null || e.Data.GetDataPresent(DataFormats.Serializable, true) == false) 
      e.Effects = DragDropEffects.None; 
     else 
      e.Effects = DragDropEffects.All; 
    } 

    private void FileListBox_Drop(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent(DataFormats.FileDrop, true)) 
     { 
      string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[]; 
      for (var i = 0; i < droppedFilePaths.Length; i++) 
      { 
       ListBoxFileName filename = new ListBoxFileName(); 
       filename.FileName = droppedFilePaths[i]; 
       filename.FileIsSelected = false; 
       FileNamesItems.Add(filename); 
      } 
     } 
     if (e.Data.GetDataPresent(DataFormats.Serializable, true)) 
     { 
      ListBoxFileName BoxItem = new ListBoxFileName(); 
      BoxItem = e.Data.GetData(DataFormats.Serializable) as ListBoxFileName; 
     } 
    } 

一切除了當細發生丟棄事件,BoxItem由於某種原因始終爲空,因此沒有任何內容添加到列表框中。

任何提示?

謝謝

+0

你試過從https://www.nuget.org/packages/gong-wpf-dragdrop/鑼WPF-的DragDrop?源代碼也awailable,所以你可以看看它是如何實現的 – bamanow

+0

@bamanow,的的NuGet鑼WPF取決於WPFToolkit包,這個包依賴於.NET 3.5。它與.NET 4.0或更高版本不兼容。 –

+0

@Eriawan你錯了,而不是與.NET 4.0開始就沒有任何依賴性 – bamanow

回答

1

的數據對象的數據應該是一個ListBoxFileName,而不是一個ListBoxItem:

private void Window_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (_dragged == null) 
     return; 
    if (e.LeftButton == MouseButtonState.Released) 
    { 
     _dragged = null; 
     return; 
    } 
    DataObject obj = new DataObject(DataFormats.Serializable, _dragged.DataContext as ListBoxFileName); 
    DragDrop.DoDragDrop(_dragged, obj, DragDropEffects.All); 
} 

private void FileListBox_Drop(object sender, DragEventArgs e) 
{ 
    if (e.Data.GetDataPresent(DataFormats.Serializable, true)) 
    { 
     ListBoxFileName BoxItem = e.Data.GetData(DataFormats.Serializable) as ListBoxFileName; 
     //... 
    } 
} 

這應該假設「FileNameList」控制的ItemsSource設置爲一個IEnumerable。

請提供能夠從頭開始重現您的問題,如果您需要在此進一步幫助需要所有相關的代碼片段。

+0

由於它是「部分」的工作。事實上,現在當我選擇BoxItem的一個副本時,它在每個列表框中被選中。任何想法可能來自哪裏? – lecloneur

+0

相同的ListBoxFileName對象是兩個不同的可視容器的DataContext,因此當您設置其IsSelected屬性(或任何您稱之爲)時,兩個容器將被選中,因爲它們綁定到相同的屬性。如果你不想要這個,你應該在將它添加到第二個ListBox之前克隆,即創建一個ListBoxFileName對象的副本。 – mm8

+0

它的工作,謝謝 – lecloneur