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));
Related
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?
I have a simple Silverlight (v5) Grid with a fixed number of rows and columns. On this grid, I'm positioning several UserControls (called myControl in this example) at specific "grid coordinates" e.g. row 2, column 1.
Occasionally, I need to move a myControl to a new grid position; I currently do this by
Grid.SetColumn(myControl, newColumn);
Grid.SetRow(myControl, newRow);
.. and this all works fine, myControl is moved to the new coordinates.
Just purely for eye candy, I'd like to animate myControl when it moves, so that it "slides" from the old grid position to the new one rather than just appearing. Is there an easy/quick way to do this?
For handling layout changes within an element to display a smooth transition FluidMoveBehavior is generally the option you would be looking for. While it won't animate things like size or visibility, it is however specifically for animating the offset of a child element moved around a parent container.
Glad you found your answer. Cheers
I have a Grid (container) wich in turn has several grids(subContainers) arranged by rows. Each one of those "subContainers" has diferent columns and controls. And each of those "subContainers" has the horizontal alignment set to stretch, and it has to stay that way, since the layout this viewer depends on it.
I use the "container" to set each control on it's adequate position. So far so good. Now comes my headache... I want to remove the control from the grid and put it in a canvas, at the same exact position, only, the position it returns is as if the control is set to the beggining of the grid and not it's true position.
For testing purposes, I've set the "subContainters" horizontal alignment to center and (despite the layout is totally wrong) every control is in it's right position when sent to a canvas, wich it doesn't happen when HA = stretch.
Here's the code I'm using to get position:
GeneralTransform gt = nc.TransformToVisual(gridZoom);
Point offset = gt.Transform(new Point());
So you can understand, for example, my first control should be somewhere like (80, 1090), but the point that I get is (3,3).
Can anyone help me? Thanks
You should try using the top level container (which contains all other subcontainers) to get the offset point.
Also you can try:
var transform = mySubSubSubElement.TransformToVisual(Application.Current.RootVisual);
var position = transform.Transform(new Point(0, 0));
I followed the solution to the items rearranging problem provided by dnr3. Works like a charm and it is very easy to understand. Now, I wish to go one step further:
Let's say that ListBox contains items A, B, C, D and E. In the mentioned solution, if a ListBoxItem is moved down the list, it is positioned below the item on which the drop was executed. So, if I select item B and release it over the element D, it will take D's place and D will move one place down. I want to be able to make a difference if the dragged item is closer to the upper or lower target item boundary - if it is closer to the upper I want it placed above the target item, or below if otherwise. I need two things to make that happen:
I need the vertical center point of the target item in order to be able to compare it with mouse position. That should be easy to do:
targetItem.Height / 2;
I need mouse position relative to the target item. How do I get that?
In the end I want to compare those two values and if mouse position is less than or equal to the item's vertical center point, then the dragged item gets to be dropped before the target item, otherwise below.
Thanks!
Got it! The following line retrieves the mouse position relative to target item
Point p = e.GetPosition(item);
Here's what the drop event handler should look like:
private void PlaylistListBoxItem_Drop(object sender, DragEventArgs e)
{
...
ListBoxItem item;
int centerY;
Point p;
item = sender as ListBoxItem;
centerY = item.Height / 2;
p = e.GetPosition(item);
if (p.Y <= centerY)
...
}
I have stack panel with custom controls in it. User can add or remove the items.
I have attached MouseDragElementBehavior to each item. So now user can move them within the stack panel.
However the items now are arranged on arbitrary manner. Is a mess really. They stay where the user left them.
What I need now is to make them to be stacked as the stack panel supposed to be... Nicely one by one...
So I need to simply let user change the order of items by using drag / drop operation but items has to be stacked precisely.
There is DragFinished event, but I dont really see how the Behavior moves items. I thought it is Margin it changes but margins stays 0... I dont know what to do next.
Appreciate little help.
MouseDragElementBehavior does its work using a Transform on the RenderTransform property of the attached element (i.e. the one the behavior is applied to) (the exact type of transform depends on the state of the RenderTransform property but it will either be a TranslateTransform or a MatrixTransform).
The transform is not reset when you finish dragging (nor would you want it to be because the element would snap back to its position in the StackPanel when you started dragging) and this is why the element stays where "the user left them".
To change the items position in the StackPanel in the way you are talking about you will have to use the DragFinished event. What you probably want to do is work out where in the StackPanel the element will end up (as a result of the drag, i.e. which element in the panel it will "push" down) then create an animation to animate the element from its current position (where the user released the drag) to that final position in the StackPanel and another animation to move the "pushed" element in to its new position in the StackPanel (VisualTreeHelper can probably help here (I think)). Once those animations are finished just set the new index within the StackPanel for each item and remove the RenderTransform translation.