This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi guys, I was wondering if anyone had used WPF Flow Diagrams in this way: i'd like to be able to double click/right click on a node and fire an event - is it possible to do this and, if so, is there any sample code anywhere? Thanks, Martin BG |
|
|
Hello Martin I have found that the best way to do this is to attach an event handler to the MoveThumb.MouseDoubleClick and MoveThumb.MouseRightButtonDown events for each node. In the standard styles, the MoveThumb is the most exposed control on any node so it is the best place to attach these kinds of event handlers. To do this you simply need to provide your own DiagramNodeElement style and attach an event handler to the appropriate events of the MoveThumb. The event handlers would be put into the code-behind. Let us know if you need further help with providing your own node style, or if you don't think this approach is what your looking for. Cheers |
|
|
Thanks Jason, that looks like the stuff! Martin BG |
|
|
I m using Demo Version in Node i didnt found MoveThumb as event. before purchaseing this we need to things 1. Validation on Nodes or connection Drag n drop to Surface. 2.We creating diagram dynamically and we needs to save it as par our requirement . so at the time of saving i need details of Nodes and related connection for saving data. if any one help on this so better thanks in advance. |
|
|
Hi bhavana, I'm not sure I understand your first issue. Could you give a concrete example of what you're trying to do? Thanks! Regarding your second issue, you can save the FlowDiagramModel in whatever format you like by iterating over the Nodes and Connections collections and saving whatever info you require from each FlowDiagramNode or FlowDiagramConnection in accordance with your desired format. |
|
|
Jason, I don't quite understand this: [quote user="Jason"] To do this you simply need to provide your own DiagramNodeElement style and attach an event handler to the appropriate events of the MoveThumb[/quote] Any chance of a quick code snippet. Essentially I have a class that derives from FlowDiagramNode and when the node is double clicked, I want to fire an event. Thanks, |
|
|
Hello David Start by having a look at this blog post: http://www.mindscape.co.nz/blog/index.php/2009/09/29/wpf-diagrams-styling-a-node-element/ Here you will find the xaml for the standard diagram node style. you will need to copy this to create your own diagram node style, and use it in your diagrams. To use it in your diagram, you can set the NodeStyleSelector property of a FlowDiagramFormatter to be a FixedStyleSelector that uses this node style. Using FlowDiagramFormatters can be seen in some of the samples. Near the top of the node style in the blog post, there is an element called MoveThumb. This is the best place to put things like double click event handlers on nodes. So attach an event handler to the MouseDoubleClick event on the MoveThumb in the node style that you create. Let me know if you need me to explain some of this more. - Jason |
|
|
I got this working as you suggested by attaching an event handler to the MouseDoubleClick event on the MoveThumb, however I now have a need to handle the double click event when the DiagramSurface IsReadOnly (with the ReadOnlyCanSelect). Any ideas about how to get this working? Thanks, David |
|
|
I don't think you'll be able to do this using the MouseDoubleClick event on the MoveThumb without a bit of jiggery-pokery, because we need the MoveThumb to be disabled in read-only mode, which means WPF doesn't even notify us about the double-click. However, here's an alternative which works for me: * Add a ContentControl to your DiagramNodeElement template. This should look as follows: <ContentControl Panel.ZIndex="99" where the MouseDoubleClick event is hooked up to the same handler as the MoveThumb.MouseDoubleClick. Note this element is collapsed by default so it normally doesn't raise mouse events or otherwise get in the way. However, when it does appear, we want it to be the first thing that gets mouse events, so we place it on top of the z-order when it does appear; we also clip it to the same geometry as the MoveThumb so you don't get spurious double-clicks from outside the visible part of the element. * In the ControlTemplate.Triggers for the DiagramNodeElement template, you should have a MultiDataTrigger for IsReadOnly=True and ReadOnlyCanSelect=True, with Setters to disable the Mover and Resizer. Add the following Setter to this MultiDataTrigger: <Setter TargetName="DoubleClickProxy" Property="Visibility" Value="Visible" /> So our DoubleClickProxy content control will now "appear" when the MoveThumb is disabled. Of course it is transparent so this will make no difference to the actual appearance, but it will now receive mouse clicks. With these template changes, when the node is read-write, it will raise double-click events from the MoveThumb; when the node is read-only but selectable, it will raise double-click events from the DoubleClickProxy ContentControl. Since you have hooked the double-click events to the same handler the effect is that the node is double-clickable in either mode. A bit fiddly, but should get you going and could possibly be reworked into something more elegant if necessary. Let me know if you have any trouble getting this working -- in particular I'm not sure exactly what your DiagramNodeElement control template looks like so my description of the MultiDataTrigger may be slightly at odds with yours. |
|
|
How can I know, which node raise click? |
|
|
In my event handler I use the following code DiagramNodeElement element = VisualTreeExtraHelper.GetParent<DiagramNodeElement>(sender); VisualTreeExtraHelper is:
public static class VisualTreeExtraHelper { /// <summary> /// This method will find the parent of the specified type (T) for the given object (sender) /// </summary> /// <param name="sender"></param> /// <returns>The parent object</returns> public static T GetParent<T>(object sender) where T : class { var fe = sender as FrameworkElement; T acb = null; while (fe != null & acb == null) { fe = VisualTreeHelper.GetParent(fe) as FrameworkElement; acb = fe as T; } return acb; } }
Hope that this helps. |
|
|
I find more simple :) FlowDiagramNode node = (FlowDiagramNode)ds.SelectedItem; where ds is ms:DiagramSurface. |
|
|
Hmmm, that would be much more simple. Can't think now why I did it like I did. |
|
|
Hello, I'm evaluating your product to see if it fits our requirements. Now I'm trying to fire an event when a node is double clicked. I looked at your blog post about customizing nodes and copied the both NodeStyle and FixedStyleSelector codes from there.But I could not manage to run that codes. Error is like this: {System.Xaml.XamlObjectWriterException: 'Provide value on 'MS.Internal.Markup.StaticExtension' threw an exception.' Line number '197' and line position '24'. ---> System.Xaml.XamlParseException: Prefix 'styles' does not map to a namespace.
at MS.Internal.Xaml.XamlContext.ResolveXamlType(String qName, Boolean skipVisibilityCheck)
at MS.Internal.Xaml.Context.ObjectWriterContext.ServiceProviderResolve(String qName)
at MS.Internal.Markup.StaticExtension.ProvideValue(IServiceProvider serviceProvider)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
--- End of inner exception stack trace ---
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
at System.Xaml.XamlObjectWriter.LogicProvideValue(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.LogicAssignProvidedValue(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.WriteEndObject()
at System.Xaml.XamlServices.Transform(XamlReader xamlReader, XamlWriter xamlWriter, Boolean closeWriter)
at System.Windows.ResourceDictionary.GetKeyValue(KeyRecord key, IServiceProvider serviceProvider)
at System.Windows.ResourceDictionary.SetKeys(IList`1 keyCollection, IServiceProvider serviceProvider)
at System.Windows.Baml2006.WpfSharedBamlSchemaContext. I think it is happening because some resources of blog codes does not exist in the project where i copied them to(I am working on customnodetype.flowdiagrams project). But I don't know how to fix it right now, and i need to get this double click behaviour as soon as possible. Would you please explain more detailed what to do or show a full example about it? Thanks for your help. |
|
|
You're missing an I think the article you're looking at may be from WPF Diagrams 1.0, and the API has changed since then, but what you probably need is to add something like this to your
|
|
|
Hi ivan, Thanks for your response. I checked that i was trying the codes on http://www.mindscapehq.com/blog/index.php/2009/09/29/wpf-diagrams-styling-a-node-element/ link and they are probably for older version. Is there a sample for double click event with your new API? I tried to mix old and new node edit examples but could not manage to make it work.
I added MoveThumb element to one of your examples (CustomNodeType.FlowDiagrams) like the code above but i get the error : Cannot find the static member 'GeometryProperty' on the type 'ContentPresenter'. Am I missing something again? Thanks. |
|
|
Hello Here is the easiest way to listen to the double click event on a node that doesn't require custom styling: Somewhere in code-behind (Such as the constructor of a Window), add an event handler to the DiagramSurface to listen for the MouseDoubleClickEvent like this:
Where "ds" is the name of a DiagramSurface set up in xaml. In the event handler (which I have called DoubleClick in the code above) You can get the DiagramNodeElement in one of two ways.
Once you have the DiagramNodeElement, you can use its Node property to get the IDiagramNode model object if you need it. Try this out and let me know if you have any questions. -Jason |
|
|
Hello, Thanks for your reply. With first method i was able to catch the double click and get the clicked DiagramNodeElement. But DiagramNodeElement seems like it does not have a Node property. With second method MoveThumb is always null, i think sender may not cast into MoveThumb. Anyway, first way is ok for me if i can get the Node. Am i missing something about it? Thanks. |
|
|
I found what is missing. FindMouseOverElement() method returns a DiagramElement object, not a DiagramNodeElement. So i cast DiagramElement's Content to IDiagramNode and it worked. Thanks for your help. |
|
|
Hello Good to hear you got it working. Note that there is also a FindMouseOverNodeElement method which only returns DiagramNodeElements. The FindMouseOverElement can return either node or connection elements depending on what the mouse is over. -Jason |
|