from what i think i understand - i have to add a Drag Initialization handler to set up the payload which i can eventually grab by setting up a DropHandler
i use the following to set up the DragInitialize handler.
DragDropManager.AddDragInitializeHandler(TheRadDiagramToolbox, OnDragInitialize);
My problem is that the DragInitialization Handler is not firing
However, my DropHandler is firing
DragDropManager.AddDropHandler(this.Diagram, OnDiagramDrop);
2 questions -
1. Am i supposed to use the DragInitializedHandler on the RadDiagramToolbox
2. Is there anyway to grab the RadDigramShape payload right from the DropHandler without having to call the DragInitializeHandler
Thank You Very Much
FF
16 Answers, 1 is accepted
I am not really sure what is your goal and why you need to handle the drop-related events. However, you can access the RadDiagramShapes through the Drop event handler of the RadDiagram and you can also handle the RadDigramToolBox DragInitialize event to set up custom payload.
The RadDigramToolBox internally handles the drag operations and this is why when you want to customize its DragInitialize handler, you need to add the handler with value of true (handled events too) as the last parameter of the AddDragInitializeHandler method:
DragDropManager.AddDragInitializeHandler(TheRadDiagramToolbox, OnDragInitialize,true);
As for the RadDiagram.Drop event handler, by default it receives an object of type DiagramDropInfo when the drop operation originates from the RadDiagramToolbox. The DiagramDropInfo object exposes a SerializationInfo property, which you can deserialize to get the RadDigramShape that was dragged:
private
void
OnDiagramDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var droppedData = (e.Data
as
DataObject).GetData(
typeof
(DiagramDropInfo));
if
(droppedData !=
null
)
{
DiagramDropInfo dropInfo = (DiagramDropInfo)droppedData;
var items = SerializationService.Default.DeserializeItems(dropInfo.Info,
true
);
foreach
(var item
in
items)
{
RadDiagramShape droppedShape = item
as
RadDiagramShape;
}
}
}
I hope this information will help you build your solution. Still, if you have more questions, please let us know.
All the best,
Tina Stancheva
the Telerik team
Time to cast your vote for Telerik! Tell DevPro Connections and Windows IT Pro why Telerik is your choice. Telerik is nominated in a total of 25 categories.
I want to intercept the drop because some additional structures need to be created once an item is dropped on the Diagram.
I have the following Event Handlers for Drag and Drop. I see that the payload is getting set correctly when I drag the shape but, the droppedData is always null. Tina did mention below that by default the DropEventHandler receives an object of type DiagramDropInfo. What am I missing here. Also, how would I serialize a CustomShape that I have created as below
public class CustomShape
{
public Geometry Geometry { get; set; }
public string Header { get; set; }
}
private void OnDragInitialize(object sender, DragInitializeEventArgs args)
{
args.AllowedEffects = System.Windows.DragDropEffects.All; // Coresponds to the QueryResult
// Coresponds to the payload setting
var payload = DragDropPayloadManager.GeneratePayload(null);
payload.SetData("DragData", ((FrameworkElement)args.OriginalSource).DataContext);
args.Data = payload;
}
private void OnDiagramDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var droppedData = (e.Data as System.Windows.DataObject).GetData(typeof(DiagramDropInfo));
if (droppedData != null)
{
DiagramDropInfo dropInfo = (DiagramDropInfo)droppedData;
var items = SerializationService.Default.DeserializeItems(dropInfo.Info, true);
foreach (var item in items)
{
CustomShape droppedShape = item as CustomShape;
}
}
}
Let me first make a few clarifications. The RadDiagramToolbox control has a built-in dragging implementation that basically gets the dragged object (gallery item) and creates a DiagramDropInfo object that holds the serialization string of the shape displayed inside the GalleryItem. This being said, you need to carefully consider your options before customizing the default drag/drop behavior between the toolbox and a RadDiagram.
In a basic scenario, where you display custom shapes with two properties - Geometry and Header, you can use the built-in drag-drop logic. However, you'll need to keep in mind that in WPF the RadDiagramToolbox built-in dragging logic cannot serialize the data-bound Geometry property of the shape. This is why you will need to manually serialize the property to make sure that the default DiagramDropInfo that is created while a ToolboxItem is being dragged, contains the serialized Geometry property as well. Then in the RadDiagram you will have to manually deserialize the Geometry. I attached a sample solution demonstrating this approach so that you can take a closer look at it.
Apart from that approach, you have a few other options. You can leave the RadDiagramToolbox dragging logic as is. This would mean that you don't set any RadDiagramToolbox.OnDragInitialize event handlers. In that case you can add a custom OnDrop event handler for the RadDiagram. And only then you can work with the default DiagramDropInfo data as demonstrated in my previous post.
The other option you have is to add a custom RadDiagramToolbox.OnDragInitialize event handler. Once you do that, it is up to you to decide what kind of data to pass to the args.Data property. And then you will have to also handle the RadDiagram OnDrop event and get this property. But please keep in mind that in the OnDrop event handler you will get the args.Data object that you have applied in the OnDragInitialize event handler as both events are part of the same process and the dragged data is represented by one object.
In the code snippets you sent, you've tried the last approach I described. However, in the OnDragInitialize() event handler you set the args.Data using the DragDropPayloadManager and you basically drag a business data - an object of type CustomShape. This is why in the OnDrop event handler you need to use the same approach to get the draggedData (through the DragDropPayloadManager) and you need to keep in mind that the type of the draggedData is a business type - CustomShape:
private
void
OnDiagramDrop(
object
sender, Telerik.Windows.DragDrop.DragEventArgs e)
{
var droppedData = DragDropPayloadManager.GetDataFromObject(e.Data,
"DragData"
);
if
(droppedData !=
null
)
{
((sender
as
RadDiagram).GraphSource
as
IObservableGraphSource).AddNode(droppedData);
}
}
Once you get the draggedData you will have to decide how to populate the RadDiagram with items. Whether you'll use the GraphSource property or you will create a RadDiagramShape depends on the requirements and setup of your application. In the above example, I assumed that the RadDiagram should be populated with business data and that its GraphSource is data-bound to a collection that implements the IObservableGraphSource.
I hope this information will help you. Please don't hesitate to write back with any additional questions.
All the best,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
I was looking into project that you sent to that topic but i found an issue on deserializing operation. I could not figure out the exact issue,
public
MainWindow()
{
InitializeComponent();
SerializationService.Default.ItemSerializing += Default_ItemSerializing;
}
void
Default_ItemSerializing(
object
sender, SerializationEventArgs<IDiagramItem> e)
{
if
(e.Entity
is
RadDiagramShape)
e.SerializationInfo[
"MyGeometry"
] = (e.Entity
as
RadDiagramShape).Geometry.ToString();
}
private
void
RadDiagram_ShapeDeserialized(
object
sender, ShapeSerializationRoutedEventArgs e)
{
if
(e.Shape
as
RadDiagramShape !=
null
)
(e.Shape
as
RadDiagramShape).Geometry = GeometryParser.GetGeometry(e.SerializationInfo[
"MyGeometry"
].ToString());
}
Here,
(e.Shape
as
RadDiagramShape).Geometry = GeometryParser.GetGeometry(e.SerializationInfo[
"MyGeometry"
].ToString());
Thanks,
Sarper
I downloaded and tested the application I attached locally but I was not able to detect any issues. Can you confirm that you reproduce an exception in the attached solution without modifying it at all? If so, can you please send us a screencast demonstrating the steps you took to reproduce the exception you report.
It would also help us if you can check the version of the referenced Telerik assemblies that reproduce the issue.
Thank you in advance.
Regards,
Tina Stancheva
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
I downloaded and builded the solution that you've attached again and the same issue occured. I didn't make any changes at all afer downloading.The referenced assemblies were the old versions because of that post is old and so the attached solution is old.
However, i have upgraded the project's assemblies but the same issue occured again. I will try it with a new project and send the results back to you. Now, I'm sending the screenshots of the process so you can find out where the issue is.
Note 1: The exceptions about databindings are gone after upgrading the project.
Note 2: I have tried it with a new solution and it is same so i am looking forward for your help.
Thanks,
Sarper
I still can't reproduce this issue locally. However, in the snapshots you sent I did note a difference between what I see while debugging and what you see on your side.
It seems that on my machine the Geometry of the shapes is saved in a string with no semicolons(;) - instead the Geometry elements are separated with spaces. However, on your side the same Geometry uses semicolons to separate the parts of the geometry.
Although I am not sure what might be causing this inconsistency, you can try to workaround it by replacing all semicolons with spaces like this:
private
void
RadDiagram_ShapeDeserialized(
object
sender, ShapeSerializationRoutedEventArgs e)
{
if
(e.Shape
as
RadDiagramShape !=
null
)
(e.Shape
as
RadDiagramShape).Geometry = GeometryParser.GetGeometry((e.SerializationInfo[
"MyGeometry"
].ToString().Replace(
";"
,
" "
)));
}
Please give this a try and let me know if it helps.
Regards,
Tina Stancheva
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
I tried your workaround and it worked well for the semicolons ut there is another issue with letters in the format.
I am sending the screenshots of my format so maybe we can find out the localization issue about serialization.
Thanks,
Sarper
Thank you for getting back to us. I believe that the cause for the issue is in the Culture set up in your application. Basically the GeometryParser expects a Geometry string in Invariant Culture. However, in my solution when I serialize the Geometry property I don't specify any specific culture and the ToString() method basically uses the default application culture. Instead, if you explicitly use the CultureInfo.InvariantCulture the string should be properly parsed during deserialization:
void
Default_ItemSerializing(
object
sender, SerializationEventArgs<IDiagramItem> e)
{
if
(e.Entity
is
RadDiagramShape)
e.SerializationInfo[
"MyGeometry"
] = (e.Entity
as
RadDiagramShape).Geometry.ToString(CultureInfo.InvariantCulture);
}
Please give this a try and let me know if it helps.
Regards,
Tina Stancheva
Telerik
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Thanks for the reply. It worked well for me.
Regards,
Sarper
I also want to add a custom control in the RadDiagramToolBox but I want to add the Pie/Line Chart of Micorsoft in that. Is that possible in the RadDiagramToolBox?
Thanks
Rahul
Yes, you can add a custom control in RadDiagramToolBox, but the approach that can be used depends on your implementation.
A possible approach is to achieve your requirement is to create a custom diagram shape with a custom style. Then you can place a chart in the shape's ContentTemplate and add it in the toolbox's galleries. For your convenience I prepared a sample project demonstrating this approach.
You can also take a look at the Dashboard demo that demonstrates drag/drop chart (and other controls) from a toolbox to RadDiagram. Please click the Run button to display the tool box. Notе the the demo is in Silverlight but it shares most of its code with the WPF version of the demos.
Regards,
Martin
Telerik
Thanks
Rahul
Hi Tina
My company has a licence for UI for WPF.
The RadDiagramToolbox is seems to be missing from the namespace. I am able to create a RadDiagram and add RadDiagramShapes etc, but the toolbox is missing. Also, when I attempt to use the Telerik for WPF demos tool to see a demo of the toolbox, the demo freezes (in fact, the same can be said for many of the controls advertised there... for some reason many are unavailable). Screenshot attached.
Mike
The demo freezing issue is observed sometimes when you install a new version of the demos application. Some old files are not replaced and are used by the demo which causes exceptions. In order to resolve this you can:
- Uninstall the demos app
- Delete its folder manually - <drive>:\Users\<your_user>\AppData\Local\Apps\2.0
- Install the demos app
About the missing RadDiagramToolbox, note that it is located in the Telerik.Windows.Controls.Diagrams.Extensions.dll. In order to use the diagram extensions you will need to reference the dll, along with some additional assemblies. You can see which ones in the Extensions help article. If the issue still occurs, you can double check if the .NET version of the dlls matches the Target framework (the .NET version) of the Visual Studio project. Also, you can manually delete the "bin" and "obj" folders of the project and Clean/Rebuild the solution.
Regards,
Martin
Telerik by Progress