2015-09-16 6 views
6

von Artikel ändern habe ich ICollectionView wiedie Gruppe in ICollectionView

public ICollectionView UsersCollectionView 
{ 
    get 
    { 
     var view = CollectionViewSource.GetDefaultView(this); 
     view.GroupDescriptions.Add(new PropertyGroupDescription("SeriesName")); 
     view.SortDescriptions.Add(new SortDescription("CreationDate", ListSortDirection.Ascending)); 
     view.SortDescriptions.Add(new SortDescription("DocumentTypeId", ListSortDirection.Ascending)); 
     return view; 
    } 
} 

ich, wie eine Idee ziehen verwenden möchte & Drop ändern, um die Artikel der Serie Namen und Standort auf der Liste anzuzeigen sieht, dass zum Beispiel tun

--- ScienceFiction 
------------> Book1 
------------> Book2 
--- History 
------------> Book3 
------------> Book4 

wenn Idraged und droped book3 in Science-Fiction sollte die Ausgabe

sein
--- ScienceFiction 
------------> Book1 
------------> Book2 
------------> Book3 
--- History 
------------> Book4 

Ich benutze XAML-Code wie folgt:

<UserControl.Resources> 
    <Style x:Key="ContainerStyle" TargetType="{x:Type GroupItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Expander Header="{Binding Name}" IsExpanded="True"> 
         <ItemsPresenter /> 
        </Expander> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 
<Grid> 
    <ListBox x:Name="lbPersonList" Margin="19,17,162,25" AlternationCount="2" ItemsSource="{Binding}"> 
     <ListBox.GroupStyle> 
      <GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/> 
     </ListBox.GroupStyle> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Name}"/> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

</Grid> 

Antwort

2

AMH,

Ändern Sie zuerst den ListviewItem Style. Es ist der Container, der jede Zeile (Datatemplate-Instanziierung) der Listbox enthält. Es ist ein guter Ort, um Drag & Drop auf Zeilenebene zu verwalten (keine Kontrolle einer Zeile, es könnte viele in der DataTemplate geben). In Visual Studio, das Listenfeld auswählen, rechts klicken und bearbeiten weitere Vorlagen/Bearbeiten generiert Artikel Container (ItemContainerStyle)/

Im ListBoxItemStyle erstellt eine Kopie bearbeiten, fügen Sie diese drei Erklärungen unter den Einrichter:

 <EventSetter Event="ListBoxItem.DragOver" Handler="ListBoxItemDragOver"/> 
     <EventSetter Event="ListBoxItem.Drop" Handler="ListBoxItemDrop"/> 
     <EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="ListBoxItemPreviewMouseMove"/> 

Stellen Sie die AllowDrop Eigenschaft auf true auf der List-Box:

<ListBox x:Name="listboxBooks" AllowDrop="True"> 

dann die Handler in der XAML implementieren.cs-Code:

#region DnD management 

    private Book sourceBook; 
    private void ListBoxItemPreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     if (e.LeftButton != MouseButtonState.Pressed) 
      return; 
     var listboxItem = sender as ListBoxItem; 
     if (listboxItem == null) 
      return; 
     sourceBook = listboxItem.DataContext as Book; 
     if (sourceBook == null) 
      return; 
     var data = new DataObject(); 
     data.SetData(sourceBook); 
     // provide some data for DnD in other applications (Word, ...) 
     data.SetData(DataFormats.StringFormat, sourceBook.ToString()); 
     DragDropEffects effect = DragDrop.DoDragDrop(listboxItem, data, DragDropEffects.Move | DragDropEffects.Copy); 
    } 
    private void ListBoxItemDrop(object sender, DragEventArgs e) 
    { 
     if (!e.Data.GetDataPresent(typeof(Book))) 
      return; 
     var listBoxItem = sender as ListBoxItem; 
     if (listBoxItem == null) 
      return; 
     var targetBook = listBoxItem.DataContext as Book; 
     if (targetBook != null) 
     { 
      viewModel.RecategorizeBook(sourceBook, targetBook.Category); 
     } 
     e.Handled = true; 
    } 
    private void ListBoxItemDragOver(object sender, DragEventArgs e) 
    { 
     Debug.WriteLine(e.Effects); 
     if (!e.Data.GetDataPresent(typeof(Book))) 
     { 
      e.Effects = DragDropEffects.None; 
      e.Handled = true; 
     } 
    } 
    private void GroupItemDrop(object sender, DragEventArgs e) 
    { 
     if (!e.Data.GetDataPresent(typeof(Book))) 
      return; 
     var groupItem = sender as GroupItem; 
     if (groupItem == null) 
      return; 
     dynamic targetGroup = groupItem.DataContext; 
     if (targetGroup != null) 
     { 
      // here I change the category of the book 
      // and refresh the view of the collectionViewSource (see link to project zipped further) 
      viewModel.RecategorizeBook(sourceBook, targetGroup.Name as String); 
     } 
     e.Handled = true; 
    } 
    #endregion 

Bitte beachte, dass ich auch in den Handler Drop-Management auf den Gruppenkopf implementiert. So der Handler in der XAML-Group deklariert werden muss:

<ListBox.GroupStyle> 
    <GroupStyle> 
     <GroupStyle.ContainerStyle> 
      <Style TargetType="{x:Type GroupItem}"> 
       <EventSetter Event="GroupItem.Drop" Handler="GroupItemDrop"/> 
       <EventSetter Event="GroupItem.PreviewMouseMove" Handler="ListBoxItemPreviewMouseMove"/> 

Es funktioniert hier ist, voll funktions Code: http://1drv.ms/1FhBZwr

wünschen, dass Sie den bestmöglichen Code

+0

@AMH, es ist nicht die Antwort auf dich Frage? –

+0

AMH, erwartest du etwas anderes/anderes, das Kopfgeld zu vergeben? –

+0

An jeden herum: wäre es nützlich, wenn ich zeigte, wie man das abgelegte Element an einer bestimmten Position in einer Gruppe, nicht in der Gruppe, sondern an einer zufälligen Position einfügen würde? Auf diese Weise wäre der Endbenutzer der Master der Gruppe. –

1

Leider ist .net noch nicht bieten eine "easy to use" Implementierung von Drag & Drop. Du musst eine Menge Dinge selbst bauen. Der Startpunkt ist ein Start der Drag und ein ContentControl ist der Bereich, auf den der Benutzer Dinge fallen lassen kann. Wenn Sie diese definiert haben, können Sie dieses Konzept problemlos wiederverwenden. Im folgenden Beispiel kann die StackPanel auf eine unsichtbare "Fläche" gezogen werden, die die TextBlock umgibt. Auf diese Weise können Sie Ihre Bücher manuell sortieren (vor/hinter dem Buch unter dem Mauszeiger ablegen).

Wenn Sie Bücher auf Ihre Kopfzeilen löschen möchten, umgeben Sie sie mit einer DropArea. Sie könnten auch beide Möglichkeiten implementieren.

XAML wird wie folgt aussehen:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
[...] 
<ListBox x:Name="lbPersonList" Margin="19,17,162,25" AlternationCount="2" ItemsSource="{Binding}"> 
    <ListBox.GroupStyle> 
     <GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/> 
    </ListBox.GroupStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <myOwn:DropArea> 
        <TextBlock Text="{Binding Name}"/> 
       </myOwn:DropArea> 
       <i:Interaction.Behaviors> 
        <myOwn:DragBehavior/> 
       </i:Interaction.Behaviors> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Die DragBehavior wird wie folgt aussehen:

public class DragBehavior : Behavior<FrameworkElement> 
    [...] 
    protected override void OnAttached() 
    { 
     AssociatedObject.MouseMove += AssociatedObject_MouseMove; 
     AssociatedObject.MouseDown += AssociatedObject_MouseLeftButtonDown; 
     AssociatedObject.MouseLeave += AssociatedObject_MouseLeave; 
     base.OnAttached(); 
    } 
    protected override void OnDetaching() 
    { 
     AssociatedObject.MouseMove -= AssociatedObject_MouseMove; 
     AssociatedObject.MouseDown -= AssociatedObject_MouseLeftButtonDown; 
     AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave; 
     base.OnDetaching(); 
    } 
    protected virtual void AssociatedObject_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (some condition of mouse button states or mouse moves) 
     { 
       DataObject data = new DataObject(); 
       data.SetData(typeof(anyKeyType), anyData); 
       data.SetData(typeof(anyOtherKeyType), anyOtherData); 
       DragDrop.DoDragDrop(fe, data, DragDropEffects.Move);     
     } 
    } 

Die DropArea wird wie folgt aussehen:

public class DropArea : ContentControl 
    [...] 
    public DropArea() 
    { 
     DragEnter += AssociatedObjectDragEnter; 
     DragLeave += AssociatedObjectDragLeave; 
     DragOver += AssociatedObjectDragOver; 
     IsTabStop = false; 
     AllowDrop = true; 
    } 
    protected override void AssociatedObjectDrop(object sender, DragEventArgs e) 
    { 
     object o = e.Data.GetData(typeof(anyKeyType)); 
     //handle dropped data 
    } 

Hoffnung, dass Sie helfen können, auf Ihrem Weg. Es kann irgendwelche Rahmen oder Bibliotheken geben, um dieses Problem zu adressieren, aber auf diese Weise können Sie Ihre eigenen Bedürfnisse adressieren.

Verwandte Themen