Skip to content

Commit

Permalink
enable drop targets if ItemsControl are in ItemsControl and the Items…
Browse files Browse the repository at this point in the history
…Control is empty
  • Loading branch information
punker76 committed Aug 1, 2016
1 parent c680fcf commit f877268
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
35 changes: 35 additions & 0 deletions Examples/DefaultsExample/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -1307,5 +1307,40 @@
</ListBox>
</Grid>
</TabItem>

<TabItem Header="List in List Example">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<ItemsControl Grid.Column="0"
ItemsSource="{Binding Collection1}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.UseDefaultDragAdorner="True">
</ItemsControl>

<ListBox Grid.Column="1" x:Name="outer">
<Border BorderThickness="1" BorderBrush="Black">
<ListBox Height="200" Width="200" x:Name="inner1" Background="Aquamarine"
ItemsSource="{Binding Collection2}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True">
</ListBox>
</Border>
<Border BorderThickness="1" BorderBrush="Black">
<ListBox Height="200" Width="200" x:Name="inner2"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.UseDefaultDragAdorner="True">
<ListBoxItem Content="Test1"></ListBoxItem>
</ListBox>
</Border>
</ListBox>

</Grid>
</TabItem>
</TabControl>
</Window>
6 changes: 5 additions & 1 deletion GongSolutions.Wpf.DragDrop/DropInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)

if (this.VisualTarget is ItemsControl) {
var itemsControl = (ItemsControl)this.VisualTarget;
//System.Diagnostics.Debug.WriteLine(">>> Name = {0}", itemsControl.Name);
// get item under the mouse
item = itemsControl.GetItemContainerAt(this.DropPosition);
var directlyOverItem = item != null;

Expand All @@ -75,6 +77,7 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)
this.VisualTargetFlowDirection = itemsControl.GetItemsPanelFlowDirection();

if (item == null) {
// ok, no item found, so maybe we can found an item at top, left, right or bottom
item = itemsControl.GetItemContainerAt(this.DropPosition, this.VisualTargetOrientation);
directlyOverItem = false;
}
Expand All @@ -89,7 +92,8 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)
}
}

if (item != null) {
if (item != null)
{
itemParent = ItemsControl.ItemsControlFromItemContainer(item);

this.InsertIndex = itemParent.ItemContainerGenerator.IndexFromContainer(item);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static UIElement GetItemContainer(this ItemsControl itemsControl, UIEleme
if (itemType != null) {
return isItemContainer
? (UIElement)child.GetVisualAncestor(itemType, itemsControl)
: (UIElement)child.GetVisualAncestor(itemType);
: (UIElement)child.GetVisualAncestor(itemType, itemsControl.GetType());
}

return null;
Expand Down Expand Up @@ -123,7 +123,7 @@ public static UIElement GetItemContainerAt(this ItemsControl itemsControl, Point
result => {
var itemContainer = isItemContainer
? result.VisualHit.GetVisualAncestor(itemContainerType, itemsControl)
: result.VisualHit.GetVisualAncestor(itemContainerType);
: result.VisualHit.GetVisualAncestor(itemContainerType, itemsControl.GetType());
if (itemContainer != null && !hits.Contains(itemContainer) && ((UIElement)itemContainer).IsVisible == true) {
hits.Add(itemContainer);
}
Expand Down
27 changes: 18 additions & 9 deletions GongSolutions.Wpf.DragDrop/Utilities/VisualTreeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,24 @@ public static T GetVisualAncestor<T>(this DependencyObject d) where T : class
return null;
}

public static DependencyObject GetVisualAncestor(this DependencyObject d, Type type)
/// <summary>
/// find the visual ancestor item by type
/// </summary>
public static DependencyObject GetVisualAncestor(this DependencyObject d, Type itemSearchType, Type itemContainerSearchType)
{
var item = VisualTreeHelper.GetParent(d.FindVisualTreeRoot());
var currentVisual = VisualTreeHelper.GetParent(d.FindVisualTreeRoot());

while (item != null && type != null) {
if (item.GetType() == type || item.GetType().IsSubclassOf(type)) {
return item;
while (currentVisual != null && itemSearchType != null) {
var currentVisualType = currentVisual.GetType();
if (currentVisualType == itemSearchType || currentVisualType.IsSubclassOf(itemSearchType)) {
return currentVisual;
}
item = VisualTreeHelper.GetParent(item);
if (itemContainerSearchType != null && itemContainerSearchType.IsAssignableFrom(currentVisualType))
{
// ok, we found an ItemsControl (maybe an empty)
return null;
}
currentVisual = VisualTreeHelper.GetParent(currentVisual);
}

return null;
Expand All @@ -85,16 +94,16 @@ public static DependencyObject GetVisualAncestor(this DependencyObject d, Type t
/// <summary>
/// find the visual ancestor by type and go through the visual tree until the given itemsControl will be found
/// </summary>
public static DependencyObject GetVisualAncestor(this DependencyObject d, Type type, ItemsControl itemsControl)
public static DependencyObject GetVisualAncestor(this DependencyObject d, Type itemSearchType, ItemsControl itemsControl)
{
var item = VisualTreeHelper.GetParent(d.FindVisualTreeRoot());
DependencyObject lastFoundItemByType = null;

while (item != null && type != null) {
while (item != null && itemSearchType != null) {
if (item == itemsControl) {
return lastFoundItemByType;
}
if ((item.GetType() == type || item.GetType().IsSubclassOf(type))
if ((item.GetType() == itemSearchType || item.GetType().IsSubclassOf(itemSearchType))
&& (itemsControl == null || itemsControl.ItemContainerGenerator.IndexFromContainer(item) != -1)) {
lastFoundItemByType = item;
}
Expand Down

0 comments on commit f877268

Please sign in to comment.