Skip to content

Commit

Permalink
fix Issue #55
Browse files Browse the repository at this point in the history
Wrong behaviour when listbox panel is StackPanel
FlowDirection="RightToLeft" Orientation="Horizontal"
  • Loading branch information
Jan Karger committed Mar 25, 2013
1 parent df4661c commit 97a4f16
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 12 deletions.
30 changes: 30 additions & 0 deletions Examples/DefaultsExample/Window1.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,19 @@

<TabItem Header="Horizontal ListBox">
<Grid>
<Grid.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="FontSize" Value="20" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0"
Expand All @@ -231,6 +238,29 @@
<ListBoxItem>Item4</ListBoxItem>
<ListBoxItem>Item5</ListBoxItem>
</ListBox>

<TextBlock Grid.Row="2"
Margin="0,8,0,8"
TextWrapping="Wrap">
Demonstrates the default behaviour with a horizontal ListBox with right to left flow direction.
</TextBlock>

<ListBox Grid.Row="3"
SelectionMode="Extended"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
FlowDirection="RightToLeft" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>Item1</ListBoxItem>
<ListBoxItem>Item2</ListBoxItem>
<ListBoxItem>Item3</ListBoxItem>
<ListBoxItem>Item4</ListBoxItem>
<ListBoxItem>Item5</ListBoxItem>
</ListBox>
</Grid>
</TabItem>

Expand Down
31 changes: 25 additions & 6 deletions GongSolutions.Wpf.DragDrop/DropInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,14 @@ public interface IDropInfo
UIElement VisualTargetItem { get; }

/// <summary>
/// Gets th orientation of the current drop target.
/// Gets the orientation of the current drop target.
/// </summary>
Orientation VisualTargetOrientation { get; }

/// <summary>
/// Gets the FlowDirection of the current drop target.
/// </summary>
FlowDirection VisualTargetFlowDirection { get; }

/// <summary>
/// Gets and sets the text displayed in the DropDropEffects adorner.
Expand Down Expand Up @@ -165,6 +169,7 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)

this.TargetGroup = this.FindGroup(itemsControl, this.DropPosition);
this.VisualTargetOrientation = itemsControl.GetItemsPanelOrientation();
this.VisualTargetFlowDirection = itemsControl.GetItemsPanelFlowDirection();

if (item == null)
{
Expand All @@ -187,7 +192,10 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)

if (this.VisualTargetOrientation == Orientation.Vertical)
{
if (e.GetPosition(item).Y > item.RenderSize.Height / 2)
var currentYPos = e.GetPosition(item).Y;
var targetHeight = item.RenderSize.Height;

if (currentYPos > targetHeight / 2)
{
InsertIndex++;
InsertPosition = RelativeInsertPosition.AfterTargetItem;
Expand All @@ -197,14 +205,18 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)
InsertPosition = RelativeInsertPosition.BeforeTargetItem;
}

if (e.GetPosition(item).Y > item.RenderSize.Height * 0.25 && e.GetPosition(item).Y < item.RenderSize.Height * 0.75)
if (currentYPos > targetHeight * 0.25 && currentYPos < targetHeight * 0.75)
{
InsertPosition |= RelativeInsertPosition.TargetItemCenter;
}
}
else
{
if (e.GetPosition(item).X > item.RenderSize.Width / 2)
var currentXPos = e.GetPosition(item).X;
var targetWidth = item.RenderSize.Width;

if ((this.VisualTargetFlowDirection == FlowDirection.RightToLeft && currentXPos < targetWidth / 2)
|| (this.VisualTargetFlowDirection == FlowDirection.LeftToRight && currentXPos > targetWidth / 2))
{
InsertIndex++;
InsertPosition = RelativeInsertPosition.AfterTargetItem;
Expand All @@ -214,10 +226,13 @@ public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)
InsertPosition = RelativeInsertPosition.BeforeTargetItem;
}

if (e.GetPosition(item).X > item.RenderSize.Width * 0.25 && e.GetPosition(item).X < item.RenderSize.Width * 0.75)
if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75)
{
InsertPosition |= RelativeInsertPosition.TargetItemCenter;
}
#if DEBUG
Console.WriteLine("==> DropInfo: {0}, {1}, {2}", InsertPosition, item, InsertIndex);
#endif
}
}
else
Expand Down Expand Up @@ -336,10 +351,14 @@ private CollectionViewGroup FindGroup(ItemsControl itemsControl, Point position)
public UIElement VisualTargetItem { get; private set; }

/// <summary>
/// Gets th orientation of the current drop target.
/// Gets the orientation of the current drop target.
/// </summary>
public Orientation VisualTargetOrientation { get; private set; }

/// <summary>
/// Gets the orientation of the current drop target.
/// </summary>
public FlowDirection VisualTargetFlowDirection { get; private set; }

/// <summary>
/// Gets and sets the text displayed in the DropDropEffects adorner.
Expand Down
17 changes: 11 additions & 6 deletions GongSolutions.Wpf.DragDrop/DropTargetInsertionAdorner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ protected override void OnRender(DrawingContext drawingContext)

if (itemContainer != null)
{
var itemRect = new Rect(itemContainer.TranslatePoint(new Point(), this.AdornedElement),
itemContainer.RenderSize);
var itemRect = new Rect(itemContainer.TranslatePoint(new Point(), this.AdornedElement), itemContainer.RenderSize);
Point point1, point2;
double rotation = 0;

Expand All @@ -58,13 +57,19 @@ protected override void OnRender(DrawingContext drawingContext)
}
else
{
if (this.DropInfo.InsertIndex == itemParent.Items.Count)
var itemRectX = itemRect.X;

if (this.DropInfo.VisualTargetFlowDirection == FlowDirection.LeftToRight && this.DropInfo.InsertIndex == itemParent.Items.Count)
{
itemRect.X += itemContainer.RenderSize.Width;
itemRectX += itemContainer.RenderSize.Width;
}
else if (this.DropInfo.VisualTargetFlowDirection == FlowDirection.RightToLeft && this.DropInfo.InsertIndex != itemParent.Items.Count)
{
itemRectX += itemContainer.RenderSize.Width;
}

point1 = new Point(itemRect.X, itemRect.Y);
point2 = new Point(itemRect.X, itemRect.Bottom);
point1 = new Point(itemRectX, itemRect.Y);
point2 = new Point(itemRectX, itemRect.Bottom);
rotation = 90;
}

Expand Down
19 changes: 19 additions & 0 deletions GongSolutions.Wpf.DragDrop/Utilities/ItemsControlExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,25 @@ public static Orientation GetItemsPanelOrientation(this ItemsControl itemsContro
return Orientation.Vertical;
}

public static FlowDirection GetItemsPanelFlowDirection(this ItemsControl itemsControl)
{
var itemsPresenter = itemsControl.GetVisualDescendent<ItemsPresenter>();

if (itemsPresenter != null)
{
var itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0);
var flowDirectionProperty = itemsPanel.GetType().GetProperty("FlowDirection", typeof(FlowDirection));

if (flowDirectionProperty != null)
{
return (FlowDirection)flowDirectionProperty.GetValue(itemsPanel, null);
}
}

// Make a guess!
return FlowDirection.LeftToRight;
}

public static void SetSelectedItem(this ItemsControl itemsControl, object item)
{
if (itemsControl is MultiSelector)
Expand Down

0 comments on commit 97a4f16

Please sign in to comment.