Binding question for drag and drop

331 views
Skip to first unread message

Rob

unread,
Nov 23, 2009, 11:56:58 AM11/23/09
to gong-wpf-dragdrop
Hi,
I think this is a great library! I have a question.
Does the ListBox which I am using have to be bound to an
ObservableCollection? I have a ListBox that is bound
to an XElement, and when I try to do a drag and drop, I get an error
stating "Collection is read-only".

<ListBox x:Name="pages"
ItemsSource="{Binding Path=Elements
[page]}"
ItemTemplate="{StaticResource
pageTemplate}"
dnd:DragDrop.IsDragSource="True"
dnd:DragDrop.IsDropTarget="True">

//this is what I am binding to
public XElement XmlFile
{
get { return xmlFile; }
set
{
xmlFile = value;

base.RaisePropertyChanged("XmlFile");
}
}


Thanks!

gro...@googlemail.com

unread,
Nov 23, 2009, 12:19:29 PM11/23/09
to gong-wpf-dragdrop
I can't really work out from the example you gave what you are binding
to. What does "Elements[page]" refer to? "XmlFile.Elements" is a
method. Maybe I'm misunderstanding something...

In your code, try to add/insert items into whatever "Elements[page]"
is. Can you do it?

To answer you general question though, no you don't have to be bound
to an ObservableCollection, any collection that implements IList will
work with the default drop handler. But even if your destination
doesn't support IList, you can provide your own DropHandler.

Rob

unread,
Nov 23, 2009, 12:54:13 PM11/23/09
to gong-wpf-dragdrop
Thanks for the quick reply.

Elements[page] is the XLINQ syntax for all of the "page" elements in
the XElement.
I can successfully add, delete, insert etc. no problem at all, but I
am not working
with any collection - I am binding to the XmlFile Property in my
ViewModel, which is an in-memory
representation of the xml file.

I tried adding my own drop
dnd:DragDrop.DragHandler="{Binding }" and when I attempt the drag and
drop
I can drag the item to a location and drop it, however immediately
when I drop it I get an error stating "Collection is read-only" before
any of the
IDropTarget methods are called in my ViewModel.
I am going to try a few different things. If you have any
suggestions, please let me know.
Thanks,
Rob


On Nov 23, 12:19 pm, "gro...@googlemail.com" <gro...@googlemail.com>
wrote:

Steven Kirk

unread,
Nov 23, 2009, 1:02:46 PM11/23/09
to gong-wpf...@googlegroups.com
Ah, ok, looks like I'm not familiar with XLINQ at all then! It's one
area of .NET I've not had any need for so far.

I will attempt to get a test project setup to debug this problem
tomorrow if you've not got to the bottom of it by then.

Good luck!
Steven

Rob

unread,
Nov 23, 2009, 3:31:00 PM11/23/09
to gong-wpf-dragdrop
If I don't get it soon, I can create a stripped down test project.
Rob

Rob

unread,
Nov 23, 2009, 5:04:27 PM11/23/09
to gong-wpf-dragdrop
Hello Steve,
I placed a sample project here on my sky drive.

It has "documents" and "pages". I'm trying to drag and drop
pages with a document, and also to other documents.
Both the documents and pages are actually listboxitems.

http://cid-6199b5dddf106ad9.skydrive.live.com/browse.aspx/dev

let me know if you cannot access this or have any problems building
the project.
thanks,
Rob

Steven Kirk

unread,
Nov 24, 2009, 5:34:18 AM11/24/09
to gong-wpf...@googlegroups.com
Hello again Rob,

Thanks for creating a test project for me - saved me a lot of time!

Looking at the code, I can see that the problem is that your ListBoxes
created by "docTemplate" are bound to ReadOnlyObservableCollections.
Which is why you're getting the "Collection is read-only" exception. I
am not sure why this is, I assume it must be something to do with the
specialised binding syntax for XLINQ, as calling Elements("page")
(which I understand should do the same as Elements[page] in XAML) from
code returns a XContainer.GetElements object.

You can test this behaviour by adding a MouseDown event handler to the
your ListBox in your docTemplate and inspecting
((ItemsControl)sender).ItemsSource.GetType().

I think you'll have to write a DropHandler to handle this.

HTH,
Steven

Rob

unread,
Nov 24, 2009, 10:16:48 AM11/24/09
to gong-wpf-dragdrop
thanks for looking at that Steve and pinpointing my problem.
Last question - when I add the following to my XAML
for the "docTemplate"

dnd:DragDrop.IsDropTarget="True"
dnd:DragDrop.IsDragSource="True"
dnd:DragDrop.DropHandler="{Binding}"

and Implement the IDropTarget Interface in my viewmodel,


#region IDropTarget Members
void IDropTarget.DragOver(DropInfo dropInfo)
{
throw new NotImplementedException();
}
void IDropTarget.Drop(DropInfo dropInfo)
{
throw new NotImplementedException();
}

#endregion

the exception "Collection is read-only" is thrown before
I ever make it to either of the IDropTarget Members (I have
breakpoints set).

I then tried adding the GongSolutions.Wpf.DragDrop Project to my
solution, and I see that
the DefaultDropHandler Drop Method is what is called, even though I
have
attempted to override the DragOver and Drop methods in my viewmodel.

Does that make sense? Once I get the to the Drop Method, I can
manipulate
the XML file myself, that is not an issue.

thanks again, your responses have been very helpful.
Rob

Steven Kirk

unread,
Nov 24, 2009, 11:03:45 AM11/24/09
to gong-wpf...@googlegroups.com
Hi Rob,

The problem is that you're trying to bind in your DataTemplate and at
that point the DataContext has changed. If you bind using something
like this:

dnd:DragDrop.DropHandler="{Binding Path=DataContext,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type
UserControl}}}"

You should find your drop handler getting called.

Does that make sense?

Cheers,
Steven

Rob

unread,
Nov 24, 2009, 12:41:10 PM11/24/09
to gong-wpf-dragdrop
It works now!! - I was not sure how to fix the binding.
Very helpful, Thanks.
Rob
Reply all
Reply to author
Forward
0 new messages