<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: How can I drag and drop items between data bound ItemsControls?</title>
	<atom:link href="http://bea.stollnitz.com/blog/?feed=rss2&#038;p=53" rel="self" type="application/rss+xml" />
	<link>http://bea.stollnitz.com/blog/?p=53</link>
	<description>on Silverlight and WPF</description>
	<lastBuildDate>Mon, 02 Aug 2010 17:57:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Jalal</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-213516</link>
		<dc:creator>Jalal</dc:creator>
		<pubDate>Thu, 22 Jul 2010 04:58:30 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-213516</guid>
		<description>Thank you!</description>
		<content:encoded><![CDATA[<p>Thank you!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-193281</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Wed, 10 Mar 2010 05:53:28 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-193281</guid>
		<description>Hi Derek,

I&#039;m not sure that I fully understand your scenario. The drag and drop code is attaching handlers for the preview mouse events with the assumption that during a drag drop operation, we don&#039;t want mouse events to affect anything else in the app. If you need to detach the preview mouse events temporarily in your app, you can use the standard event syntax:

element.PreviewMouseLeftButtonDown -= MyElement_PreviewMouseLeftButtonDown;

And to re-attach it, you can do the same thing with +=. 

Bea</description>
		<content:encoded><![CDATA[<p>Hi Derek,</p>
<p>I&#8217;m not sure that I fully understand your scenario. The drag and drop code is attaching handlers for the preview mouse events with the assumption that during a drag drop operation, we don&#8217;t want mouse events to affect anything else in the app. If you need to detach the preview mouse events temporarily in your app, you can use the standard event syntax:</p>
<p>element.PreviewMouseLeftButtonDown -= MyElement_PreviewMouseLeftButtonDown;</p>
<p>And to re-attach it, you can do the same thing with +=. </p>
<p>Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-192394</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Fri, 05 Mar 2010 18:05:43 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-192394</guid>
		<description>Hi Zach,

FYI: I have updated the source code of this post with a fix for the issue you encountered.

Bea</description>
		<content:encoded><![CDATA[<p>Hi Zach,</p>
<p>FYI: I have updated the source code of this post with a fix for the issue you encountered.</p>
<p>Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: derek</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-190474</link>
		<dc:creator>derek</dc:creator>
		<pubDate>Wed, 24 Feb 2010 22:25:39 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-190474</guid>
		<description>Bea,

I have used this generic approach for our application and now the list items are becoming richer and richer.... to the extent that we have an AdornerDecorator which can be made visibleon occasions as part of the list item. The AdornerDecorator can contain other controls... and what I have noticed is that controls that rely on drag and drop themselves [e.g dragging a scroll bar, or drag -resizing a grid column] do not get an opportunity to handle their drag events before the DragDropHelper takes over...

Hope this makes sense.

Is there some way of making such an Adornerdecorator  not allow the PreviewMouseDown, PreviewMouseMove etc to block these events temporarily?

Thanks for any insight you can give.

Derek</description>
		<content:encoded><![CDATA[<p>Bea,</p>
<p>I have used this generic approach for our application and now the list items are becoming richer and richer&#8230;. to the extent that we have an AdornerDecorator which can be made visibleon occasions as part of the list item. The AdornerDecorator can contain other controls&#8230; and what I have noticed is that controls that rely on drag and drop themselves [e.g dragging a scroll bar, or drag -resizing a grid column] do not get an opportunity to handle their drag events before the DragDropHelper takes over&#8230;</p>
<p>Hope this makes sense.</p>
<p>Is there some way of making such an Adornerdecorator  not allow the PreviewMouseDown, PreviewMouseMove etc to block these events temporarily?</p>
<p>Thanks for any insight you can give.</p>
<p>Derek</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Zach</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-186014</link>
		<dc:creator>Zach</dc:creator>
		<pubDate>Tue, 26 Jan 2010 15:48:38 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-186014</guid>
		<description>Rock and Roll.   Thanks.   I wrote a combined version of GetItemContainer and FindAncestor so it essentially does the FindAncestor loop inside GetItemContainer and then does the test for the container belonging to the itemsControl inside the loop.  Works great.   Less filling.  Thanks.</description>
		<content:encoded><![CDATA[<p>Rock and Roll.   Thanks.   I wrote a combined version of GetItemContainer and FindAncestor so it essentially does the FindAncestor loop inside GetItemContainer and then does the test for the container belonging to the itemsControl inside the loop.  Works great.   Less filling.  Thanks.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-185127</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Thu, 21 Jan 2010 22:53:46 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-185127</guid>
		<description>Hi,

The code assumes that if the mouse is over a ListViewItem, it will figure out a way to insert the item before or after the hovered item. If it&#039;s not, then it inserts the item at the end of the list. The problem you see (which I can repro) is that the default style for ListViewItem introduces a 1 px margin around it, so when you&#039;re hovering that 1 px area, you&#039;re not really over a ListViewItem. 

One solution to this problem is to remove the margin from the ListViewItem. This can be easily done by adding a style to ListViewItem that sets its margin to 0.

&lt;Style TargetType=&quot;{x:Type ListViewItem}&quot; x:Key=&quot;ListViewItemStyle&quot;&gt;
&lt;Setter Property=&quot;Margin&quot; Value=&quot;0&quot;/&gt;
&lt;/Style&gt;

&lt;ListView ItemContainerStyle=&quot;{StaticResource ListViewItemStyle}&quot; ...

If you want that 1px space to remain for aesthetical reasons, instead of a margin you can add it as padding, or a border.

Hope this helps.
Bea</description>
		<content:encoded><![CDATA[<p>Hi,</p>
<p>The code assumes that if the mouse is over a ListViewItem, it will figure out a way to insert the item before or after the hovered item. If it&#8217;s not, then it inserts the item at the end of the list. The problem you see (which I can repro) is that the default style for ListViewItem introduces a 1 px margin around it, so when you&#8217;re hovering that 1 px area, you&#8217;re not really over a ListViewItem. </p>
<p>One solution to this problem is to remove the margin from the ListViewItem. This can be easily done by adding a style to ListViewItem that sets its margin to 0.</p>
<p>&lt;Style TargetType=&#8221;{x:Type ListViewItem}&#8221; x:Key=&#8221;ListViewItemStyle&#8221;&gt;<br />
&lt;Setter Property=&#8221;Margin&#8221; Value=&#8221;0&#8243;/&gt;<br />
&lt;/Style&gt;</p>
<p>&lt;ListView ItemContainerStyle=&#8221;{StaticResource ListViewItemStyle}&#8221; &#8230;</p>
<p>If you want that 1px space to remain for aesthetical reasons, instead of a margin you can add it as padding, or a border.</p>
<p>Hope this helps.<br />
Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-185084</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Thu, 21 Jan 2010 17:46:59 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-185084</guid>
		<description>Hi Daniel,

Yeah, the fact that selection gets messed up when adding the same item twice to a ListBox is a well known and much discussed issue. When I was still on the team, we often talked about how common of a scenario that is, the priority of fixing it, and how we should fix it. Somehow the team never actually shipped a solution to that issue.

Your solution is good. Another alternative is to wrap the data items in containers. This way, even though the actual items may not be unique, the containers are.

Thanks for posting your solution! I&#039;m sure it will be useful to others.

Bea</description>
		<content:encoded><![CDATA[<p>Hi Daniel,</p>
<p>Yeah, the fact that selection gets messed up when adding the same item twice to a ListBox is a well known and much discussed issue. When I was still on the team, we often talked about how common of a scenario that is, the priority of fixing it, and how we should fix it. Somehow the team never actually shipped a solution to that issue.</p>
<p>Your solution is good. Another alternative is to wrap the data items in containers. This way, even though the actual items may not be unique, the containers are.</p>
<p>Thanks for posting your solution! I&#8217;m sure it will be useful to others.</p>
<p>Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-185082</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Thu, 21 Jan 2010 17:42:02 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-185082</guid>
		<description>Hi Zach,

Yep, I can repro what you describe (you can see my code in &lt;a href=&quot;http://bea.stollnitz.com/BlogComments/45DragDropListBox.zip&quot; rel=&quot;nofollow&quot;&gt;this project&lt;/a&gt;), and understand what is going on.

The code in &quot;GetItemContainer&quot; first gets the type of container for the ItemsControl, which in this case is ContentPresenter. Then it walks up the visual tree, starting from the bottom-most element clicked (in this case, the Label), until it finds the first element of type ContentPresenter. Then it checks that the ContentPresenter found is in fact a container of the ItemsControl passed as a parameter. This is where things go wrong. The problem is that Label&#039;s default template contains a ContentPresenter, and this one is encountered first when walking up the tree. So the code failes when verifying that it is a container of the ItemsControl.

There are a few ways in which the code can be fixed:

- You can use a TextBlock instead of a Label. 

- You can modify the code in &quot;GetItemContainer&quot;. Here&#039;s the code that checks whether the container belongs to the ItemsControl (the comparison that fails in your scenario):

FrameworkElement itemContainerVerify = itemsControl.ItemContainerGenerator.ContainerFromItem(itemContainer.DataContext) as FrameworkElement;
if (itemContainer != itemContainerVerify)
{
itemContainer = null;
}

If the verification that the container belongs to the ItemsControl fails, you can continue walking up the tree looking for the next container of the same type, and repeat the comparison. This would be done until the container in fact belongs to the ItemsControl or the tree walk reaches the top window. 

Let me know if this makes sense.

Thanks,
Bea</description>
		<content:encoded><![CDATA[<p>Hi Zach,</p>
<p>Yep, I can repro what you describe (you can see my code in <a href="http://bea.stollnitz.com/BlogComments/45DragDropListBox.zip" rel="nofollow">this project</a>), and understand what is going on.</p>
<p>The code in &#8220;GetItemContainer&#8221; first gets the type of container for the ItemsControl, which in this case is ContentPresenter. Then it walks up the visual tree, starting from the bottom-most element clicked (in this case, the Label), until it finds the first element of type ContentPresenter. Then it checks that the ContentPresenter found is in fact a container of the ItemsControl passed as a parameter. This is where things go wrong. The problem is that Label&#8217;s default template contains a ContentPresenter, and this one is encountered first when walking up the tree. So the code failes when verifying that it is a container of the ItemsControl.</p>
<p>There are a few ways in which the code can be fixed:</p>
<p>- You can use a TextBlock instead of a Label. </p>
<p>- You can modify the code in &#8220;GetItemContainer&#8221;. Here&#8217;s the code that checks whether the container belongs to the ItemsControl (the comparison that fails in your scenario):</p>
<p>FrameworkElement itemContainerVerify = itemsControl.ItemContainerGenerator.ContainerFromItem(itemContainer.DataContext) as FrameworkElement;<br />
if (itemContainer != itemContainerVerify)<br />
{<br />
itemContainer = null;<br />
}</p>
<p>If the verification that the container belongs to the ItemsControl fails, you can continue walking up the tree looking for the next container of the same type, and repeat the comparison. This would be done until the container in fact belongs to the ItemsControl or the tree walk reaches the top window. </p>
<p>Let me know if this makes sense.</p>
<p>Thanks,<br />
Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-185047</link>
		<dc:creator>Daniel</dc:creator>
		<pubDate>Thu, 21 Jan 2010 11:06:45 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-185047</guid>
		<description>Hi Bea,

i get into troubles when i have to drag the same object multiple times into the same drop target. The underlying listbox can&#039;t make differences between the items and selected them all.

To fix this i used die IClonable Interface in your InsertItemInItemsControl. Hope this can help someone else.


if (itemToInsert != null)
			{
				IEnumerable itemsSource = itemsControl.ItemsSource;

				if (itemsSource == null)
				{
					itemsControl.Items.Insert(insertionIndex, itemToInsert);
				}
				// Is the ItemsSource IList or IList? If so, insert the dragged item in the list.
				else if (itemsSource is IList)
				{
/* New */                   
 if (itemToInsert is ICloneable)
                    {
                        object copy = ((ICloneable)itemToInsert).Clone();
                        ((IList)itemsSource).Insert(insertionIndex, copy);
                    }
                    else
                    {
                        ((IList)itemsSource).Insert(insertionIndex, itemToInsert);
                    }/* New end */
				}
				else
				{
					Type type = itemsSource.GetType();
					Type genericIListType = type.GetInterface(&quot;IList`1&quot;);
					if (genericIListType != null)
					{
						type.GetMethod(&quot;Insert&quot;).Invoke(itemsSource, new object[] { insertionIndex, itemToInsert });
					}
				}
			}

with kind regards
daniel</description>
		<content:encoded><![CDATA[<p>Hi Bea,</p>
<p>i get into troubles when i have to drag the same object multiple times into the same drop target. The underlying listbox can&#8217;t make differences between the items and selected them all.</p>
<p>To fix this i used die IClonable Interface in your InsertItemInItemsControl. Hope this can help someone else.</p>
<p>if (itemToInsert != null)<br />
			{<br />
				IEnumerable itemsSource = itemsControl.ItemsSource;</p>
<p>				if (itemsSource == null)<br />
				{<br />
					itemsControl.Items.Insert(insertionIndex, itemToInsert);<br />
				}<br />
				// Is the ItemsSource IList or IList? If so, insert the dragged item in the list.<br />
				else if (itemsSource is IList)<br />
				{<br />
/* New */<br />
 if (itemToInsert is ICloneable)<br />
                    {<br />
                        object copy = ((ICloneable)itemToInsert).Clone();<br />
                        ((IList)itemsSource).Insert(insertionIndex, copy);<br />
                    }<br />
                    else<br />
                    {<br />
                        ((IList)itemsSource).Insert(insertionIndex, itemToInsert);<br />
                    }/* New end */<br />
				}<br />
				else<br />
				{<br />
					Type type = itemsSource.GetType();<br />
					Type genericIListType = type.GetInterface(&#8220;IList`1&#8243;);<br />
					if (genericIListType != null)<br />
					{<br />
						type.GetMethod(&#8220;Insert&#8221;).Invoke(itemsSource, new object[] { insertionIndex, itemToInsert });<br />
					}<br />
				}<br />
			}</p>
<p>with kind regards<br />
daniel</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=53&#038;cpage=1#comment-184982</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Thu, 21 Jan 2010 01:19:45 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=53#comment-184982</guid>
		<description>Right.
Same thing for the double click. You would have to detect that case (either with Control.MouseDoubleClick if you&#039;re dealing with a control or by looking at the ClickCount property if you&#039;re not), and deal with that scenario specifically.

Bea</description>
		<content:encoded><![CDATA[<p>Right.<br />
Same thing for the double click. You would have to detect that case (either with Control.MouseDoubleClick if you&#8217;re dealing with a control or by looking at the ClickCount property if you&#8217;re not), and deal with that scenario specifically.</p>
<p>Bea</p>
]]></content:encoded>
	</item>
</channel>
</rss>
