I almost have this working and just need some guidance on whether I'm going about this correctly and more importantly how to fix the tiny issue I am having.
I have uploaded a small sample project with the problem mentioned below.
I want to be able to drag multiple grid rows from the XamGrid to a XamTree. I don't physically need anything to move or change, I just need it to appear to the user they are dragging something to a specific XamTreeitem.
By crawling the forums I found a couple different approaches to this. Non seemed to be a perfect fit or to work completely but I was able to splice together something that almost works.
Approach
I loaded the tree nodes dynamically in code-behind and call SetDropTarget to specify which nodes are DropTargets. Working perfectly.
I could not figure out how to get XamGrid row's to be Drag Source objects. I posted elsewhere about this but know one has replied.
I found an example where they provided a custom DragTemplate at the XamGrid level. I put a TextBlock in the DataTemplate with Text="" so I basically get what I want. Just the default drag cursor and not the whole entire grid moving. This seems to work and I have only one issue with the XamGrid.
After the drag is finished, if I move the mouse back to the XamGrid, it starts selected all rows until I refocus or re-click the grid. Its like something gets messed up with its Visual State.
Any help would be greatly appreciated.
Hello,
It's because of a bug of DragDrop. A new service release is expected in next few days where this issue is fixed.
Best regards.Plamen.
Great! I eagerly await the service release.
I have 1 more problem to figure out. Grid rows can only be dragged to certain folders. I was originally thinking that I could set DropChannel and DragChannel but since I cannot figure out how to set the drag source on a row by row basis this doesn't appear to be an option.
How would your recommend that during that dragover I calculate that the grid row (or rows) is actually allowed to be dropped on this particular XamTreeItem and if its not, change curror back to not allowed?
I think this is my last hurdle.
Thanks in advance!
Ken
Steve,
First, thanks for the quick reply.
I actually already tried the first method you suggested by taking the default style for the CellControl from the XamGrid.xaml file in the Default Styles folder. It was working at the cell level (meaning it showed the cell dragging). I opted for the method I did in the demo application because it let me control how the drag worked. And I liked it except I have the annoying requirement that each grid row needs to drag to potentially different XamTreeItems. Meaning it can only be dragged to 2 of the 10 nodes, etc. The only way to accomplish this I believe (since I don't see any events on the DropTarget (why?)) is to set the Drag and Drop Channels. Which is why I need to do it at the row level. Your CellControlAttached event actually did help as I could do this
DragSource source = DragDropManager.GetDragSource(e.Cell.Row.Control); if (source == null){ source = new DragSource { IsDraggable = true, DataObject = e.Cell.Row, DragChannels = new ObservableCollection<string>() { "test" } }; DragDropManager.SetDragSource(e.Cell.Row.Control, source);}But there is 1 thing I don't like about this. It drags the whole entire rowvisually when all I really want is the cursor to change. Is there a way I couldset the drag template in code? Or in xaml, while still attaching eachrow.Control to the DragDropManager?Thanks in advance.
Hi,
Yes, on your DragSource, you just need to hook up the DragStart event, and set the e.DragSnapshotElement to what you want to display.
One thing to note about the code you posted, is that a CellsPanel, which is the Control for the Row, isn't always hooked up to the same Row, as its recycled when it scrolled out of view. So i'd suggest setting the DataObject to the Control instead, and accessing it's Row property in your other events.
Hope this helps,
-SteveZ
Ok, I basically just want the default icon change and no elements showing. Maybe I could null it our or set it to a hidden UiElement or something?
Is your second note, you mention about the CellsPanel being recyled. Thanks for pointing that out. It probably would of caused me heartache down the road. You suggest setting the DataObject to the Control instead. Could you elaborate a little on what you mean? It won't let me do this
DragDropManager.SetDragSource(e.Cell.Row, source);
Row object must not decend from DependencyObject. When you say set it to the control instead, I'm confused. From a Row standpoint, what control? The grid? Then I'm back to my initial problem of how can I customize each rows DragChannel so I can control which rows are allowed to be dropped to which XamTreeItems? If my requirements aren't clear, I could modify my above example to show what I need (just need to add a new Column (FolderId). The treeview I am dragging to would represent folders. So each row should only be dragged to certain folders (xamtreeitems).
Thanks again for your help, I really appreciate it.
Hey Ken,
I didn't mean to use the e.Cell.Row as the DragSource, you must use the Control as the DragSource.
What i meant was, that you're setting the DataObject to the Row:
source = new DragSource { IsDraggable = true, DataObject = e.Cell.Row, .....
instead set the DataObject to the e.Cell.Row.Control.
Then when you access the DataObject, you can get access to the row from the CellsPanel.
As for just displaying the default icon, you can try setting it to null, although that might cause it to use the
default. If thats the case, then as you said, setting it to an empty element such as a Canvas should
do the trick.
I have my CellControlAttached defined like this
private void igGridTransactions_CellControlAttached(object sender, CellControlAttachedEventArgs e){ DragSource source = DragDropManager.GetDragSource(e.Cell.Row.Control); if (source == null) {
source = new DragSource { IsDraggable = true, DragChannels = new ObservableCollection<string>() { "test" } }; source.DragStart += new EventHandler<DragDropStartEventArgs>(DragSource_DragStart); DragDropManager.SetDragSource(e.Cell.Row.Control, source); } }
My DragStart code
private void DragSource_DragStart(object sender, Infragistics.DragDrop.DragDropStartEventArgs e){ e.DragSnapshotElement = new TextBox() { Visibility = System.Windows.Visibility.Collapsed, Text = "" }; // disabling grid is only way I can figure out how to prevent rows from selecting while // I'm dragging over them??? I re-enable in DragEnd igGridTransactions.IsEnabled = false; e.Data = igGrid.SelectionSettings.SelectedRows;}
This seems to do what I want. The only thing I've noticed is that the XamGrid is now selecting all rows my mouse cursor scrolls over (even before I do any drag). I believe or hope this is the known issue from above. As soon as I comment out the CellControlAttached DragDropManager logic, the grid selection issue goes away. Hopefully this is just a manifestation of the previously mentioned bug.
Thanks for all you help!
The 10.2 SR was just released:
http://ko.infragistics.com/dotnet/netadvantage/silverlight/line-of-business.aspx#Downloads
For some reason the link Plamen sent you wasn't updated to contain the 10.2 SR.
Bummer, I don't see a service release for 10.2 Line of Business (which has the same problem). I only see a 10.1 service release. Was hoping to bite the bullet and just upgrade to 10.2 to get the name spaces in order.
Thanks for all your help guys.
Plamen,
Thanks, great link.
Hello Ken,
Here you can find information about service releases.
Any idea when that service release is coming out?
Is there a forum or place on your site I can read about service releases (dates and info on what was fixed etc).