2016-12-26 6 views
0

beginner here。WPFドラッグアンドドロップオブジェクトfromリストボックス

他のコントロールの中に1つのリストボックスを持つusercontrolを作成しようとしています。このリストボックスを使用して、usercontrolの他の同様のインスタンスにドラッグアンドドロップできるようにします。

これは私がドラッグして別のリストボックスからドロップしたいオブジェクトである:ここでは

[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が常にnullになるため、リストボックスに何も追加されません。

ヒント?

はありがとうのDataObjectの

+0

https://www.nuget.org/packages/gong-wpf-dragdrop/からgong-wpf-dragdropを試しましたか?ソースコードもawbleで実装方法を見ることができます – bamanow

+0

@bamanow、gong-wpfのnugetはWPFToolkitパッケージに依存しています。このパッケージは.NET 3.5に依存しています。それは、.NET 4.0以降と互換性がありません。 –

+0

@Eriawanあなたは間違っていますが、代わりに.NET 4.0から始まり、依存関係はありません – bamanow

答えて

1

データではなく、ListBoxItemのListBoxFileNameする必要があります:

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のコピーの1つを選択すると、すべてのリストボックスで選択されます。これがどこから来たのだろうか? – lecloneur

+0

同じListBoxFileNameオブジェクトは2つの異なるビジュアルコンテナのDataContextです。したがって、IsSelectedプロパティ(またはそれを呼び出すもの)を設定すると、両方のコンテナが同じプロパティにバインドされているため選択されます。これを必要としない場合は、2番目のListBoxに追加する前に、ListBoxFileNameオブジェクトの複製を作成する、つまりそのコピーを作成する必要があります。 – mm8

+0

それは働いています、ありがとう – lecloneur

関連する問題