I'm writing a graph (nodes and links) designing program where the main designer allows users to shift nodes (represented as ellipses) about and to add links between the node.
The problem now is that I would like to add labels to the links. The labels should be parallel to the links, i.e. the labels should not be horizontal if the links are diagonal. These links are typically just on top or below the link line.
I'm now using the a Grid instead of just a Line for the View part of the link to contain the labels and the line. The midpoints of both ends of the grid should lie exactly at the position of the two attached nodes.
However, unlike the Line control, the Grid control does not have X1 Y1 X2 Y2 properties to bind its two "endpoints" to. Since the Line control is neither a ContentControl, I am unable to embed a Grid in a Line as well.
Are there any possible solutions to this?
Related
So there's this tutorial about creating a diagram in WPF.
http://www.codeproject.com/Articles/24681/WPF-Diagram-Designer-Part
I've read it, and still studying it to understand it completely.
At the end of this tutorial, you can basically add shapes, move/rotate/scale them, and since they are created in a vector form, they are keeping their resolutions, there are also connectors that can connect each shape with another.
My goal, since I need to create a simulator which shows how internet protocols are delivered, is to create a divided diagram in which Side A communicates with Side B. it could read an automata and simulate the transitions in the diagram.
I'm thinking of how to deliever this, and since I don't have a lot of knowledge in WPF, I wonder in which way should I implement it.
Should I create 2 different Canvases? or maybe dividing 1 canvas with two sides?
The main issue I'm dealing with, is that when a shape is being dragged to the end margin of the window, then the window allow me to slide it so I can see the rest of the field, this is being done by increasing the size of the Canvas, as seen in the Tutorial Part 1.
However, if my canvas is divided by two, and there's a border in the middle, how can I create two sliders for each of the sides?
I was wondering if you can give me any tips about how approaching this idea, since my knowledge in WPF is still very limited.
Here is my point of view, but it would be very useful if you would provide a more/less final sketch of your app. I recommend using Telerik AppMock but paint will also suffice ;).
From what I have understood you should need 3 canvases.
1-st is canvas on the left.
2-nd is canvas on the right.
3-rd is on top of both canvases.
When you want to drag an element, you must set opacity of the clicked element to be a bit transparent and leave it on its place(1st canvas), add copy of dragged element in to the 3rd canvas. When you do leftmousebuttonup(drop dragged item), you have to check where was it dropped and if it was droppend on the 2nd canvas you add it to this canvas. To position element on the canvas you can use Canvas.SetLeft and accordingly SetRight method.
You can put 1st and 2nd canvases into Grid. Even if Canvases will be bigger if Grid, view will be cut only to the size of the Grid.
Moreover, to allow canvases manipulation, add there (to the Grid) a scrollviewer which will Translate Transform the canvases given to their sizes.
Later, try to use MVVM pattern to fill your Canvases with data.
I would also suggest an ObservableColletion of drawable (you can use FrameworkElement as base class) and draggable objects. Different for every Canvas.
Good luck!
I am creating grid dynamically and adding 200 rows and 240 columns and adding stackpanel at each position of the grid So totally i am drawing 4800 stackpanels .Now i want to add lines circle and 3 text blocks in each of the stackpanel
Till I am adding grid add stackpanel it working fine and rendering all controls within 4 seconds which is okay .But as i started adding text block as a child control in scakpanel it taking too much time . Should I use any other better and light weight control . Or instead of adding text block can use DrawText on show text in stack panel. I further want to use drag drop functionality for stack panel so i must use only container will move along with its child elements
I think you can avoid adding the columns and the rows phase, instead of using a Grid you can simply use a canvas and handle the tabular view (rows and columns) from your code behind using the the Left and Top properties.
Beside, a canvas will be convenient to use the drag and drop functionnality. you can use for that the MouseDragElementBehavior. but then you have to deal with absolute positioning according to your Parent Window rather then the Top and Left Properites. It still realtively easy to do.
If you're using a large view where there is only a part of it displayed, you can load only the part in view.
I Hope this will be helpfull.
Now, i have two listboxes,i want to draw a line from a listboxitem of this listbox to a listboxitem of another listbox. the two listboxitem isn't horizontal if possible. How to get listboxitem coordinate???
First you have to get both items you want to connect.
If you have both items you can start calculating the points. I would look for a parent Panel of both listboxes and calculate the points relative to that Panel.
As example you create Grid within two listboxes. Now you just have to calculate the points of both items. Now add a Line to the Grid that contains the two calculated points (point1 = x1, y1 and point2 = x2, y2).
But remember. It is not as easy as it seems because if you scroll you have to update the points. And exactly at that point the next problem apears. If you scroll out view (the items you want to connect) the line will be still visible. So you have to calculate if the line is visible or not...
The best way would be creating a DataGrid and connecting two cells because it is still easier than two different listboxes.
This Code worked for me (here I get the coordinates of the selected item relative to its hosted window):
object selectedEntry = (object)myListBox.SelectedItem;
ListBoxItem lbi = this.myListBox.ItemContainerGenerator.ContainerFromItem(selectedEntry) as ListBoxItem;
Point p = lbi.TranslatePoint(new Point(0, 0), Window.GetWindow(lbi));
I just want ask for your comments/suggestions on how to create a customized listview (if that's a good implementation) in WPF that displays images coming from a table from a database (more like a playlist) that rotates similar to a film (moving horizontally - on loop)
Any ideas?
If you have a list of Images, you can create an Image control for each one, put each Image control in a horizontal StackPanel, put the StackPanel inside a Canvas (of whatever size of the "film"), and animate the Left property of the Canvas to have the images roll.
Of course, if you need that the images wrap (the first one after the last one), you could forget about the StackPanel and move each Image separately.
I am working on an interactive WPF graph/tree tool and have nodes and links between them placed in a canvas. The nodes are usercontrols and the links are simply Line shapes, and currently the links go from the centre of a node to another node's centre.
The problem arise when I want the nodes to be slightly transparent and one sees the links behind the nodes.
I figured the most convenient solution would be to apply clipping or opacitymask to the lines, so they are not drawn behind the nodes, but I can't for the life of me figure out how?
Basically I can't figure out a bounding box geometry from the nodes to use as a clipping geometry for the lines. I am also interested in alternative solutions, of course!
It would seem to me like you're overthinking the solution. Why not just change the logic for the links so that the lines begin/end at the correct side of the node instead of starting from the center??? You should only need to do a little more math to accomplish this.
That said, to get the bounding box of a Visual you can use the VisualTreeHelper::GetContentBounnds helper method.
The VisualTreeHelper.GetContentBounds() method seems to return Empty everytime.
An alternative solution to this problem is answered at
Connecting two WPF canvas elements by a line, without using anchors?
that uses bounding boxes to find intersection points to draw the lines from/to.
We worked on something similar and our solution was to put links and nodes on different layers.
So if you want the nodes to appear above the links and the tips of the links to be hidden by the nodes, you just change the z-order of the layers so that the nodes layer is in front of the links-layer.
As layers we used VisualHosts (you find a VisualHost class here) an our node and link objects were DrawingVisuals.
Works fine and you don't need to hassle about finding the borders of your nodes etc.