I have ICollectionView
looks like
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;
}
}
I want to use drag & drop to change the item Series Name , and location on the list view any idea how to do that for example
--- ScienceFiction
------------> Book1
------------> Book2
--- History
------------> Book3
------------> Book4
if Idraged and droped book3 in ScienceFiction the output should be
--- ScienceFiction
------------> Book1
------------> Book2
------------> Book3
--- History
------------> Book4
I use xaml code like this :
<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>
AMH,
First modify the ListviewItem Style. It is the container that contains every line (datatemplate instanciation) of the listbox. It is a good place to manage Drag and Drop at the line level ( not a control of a line, there could be many in the DataTemplate). In Visual Studio, select the listbox, right click, Edit additional templates/Edit Generated Item Container(ItemContainerStyle)/Edit a copy
In the ListBoxItemStyle created, add those three declarations amongst the setters :
<EventSetter Event="ListBoxItem.DragOver" Handler="ListBoxItemDragOver"/>
<EventSetter Event="ListBoxItem.Drop" Handler="ListBoxItemDrop"/>
<EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="ListBoxItemPreviewMouseMove"/>
Set the AllowDrop property to true on the ListBox :
<ListBox x:Name="listboxBooks" AllowDrop="True">
Then implement the handlers in the .xaml.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
Note that I also implemented Drop management on the group header in the handlers. So the handler needs to be declared in the XAML groupstyle :
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<EventSetter Event="GroupItem.Drop" Handler="GroupItemDrop"/>
<EventSetter Event="GroupItem.PreviewMouseMove" Handler="ListBoxItemPreviewMouseMove"/>
It works, here is full working code : http://1drv.ms/1FhBZwr
Wish you the best possible code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With