I'm working on a project that allows users to drawing something, and save it in the database.
Basically, the user draws on a canvas, the canvas is 5 time bigger than the screen size, and the canvas is still in the center of the screen (or the screen is in the center of the canvas).
In order to make it flexible for the canvas size (we want to change the size of the canvas in the future), we want to set the center of the canvas as the Origin Point, that is, (0, 0) is in the center of the canvas. So when the mouse clicks somewhere, the point I get is measured based on the center of the canvas.
Maybe you would say:
Canvas.RenderTransformOrigin = (.5,.5). But I'm not asking the rotating center, so it's not the solution.
Canvas.RenderTransform = TranslateTransform (Canvas.Width/2.0, Canvas.Height/2.0). But this just move all the objects on the canvas to the center.
You may also say that, why don't we just translate the MouseClick points with an offset Canvas.Width/2.0, Canvas.Height/2.0, and then translate them back when rendering. We could do that, but too much effort, because we have a lot of other operations to be implemented, so every time we have to translate back and forth.
It looks like you have thought of almost every possible approach to this problem, however, I will see if I can add just one more!
The Canvas properties, Left and Top, which dictate an elements position are attached properties. You could create your own attached properties, OffsetLeft, OffsetTop which allow you to position elements based on the origin you require. These would be simple to implement, when they are get / set, just handle their change event to set the respective Canvas attached properties.
Related
I have an issue where I snap the window to the left and after I close the window I will save the location (Left, Top) along with size of the window. Next time the window is loaded I will try to apply the location and size.
I say try because the window might have been viewed on a screen that has larger resolution so it might not be visible at all on our new screen. What I do is - I see if the window(after I apply location and size) fits in the screen. If it doesn't I will show it on the center and if it does, well it's already where I want it.
My issue is when I snap window to the left. The actual Left property is not 0(zero) but -6.something. I suspect this is because the window has shadow around it so the location must be in minus so the actual form(the one with border) is touching left part of the screen. Because of my logic I will get this screen in the center.
Is there a bullet proof way of determining that the form is snapped to one of the sides?
Is there a bullet proof way of determining that the form is snapped to one of the sides?
No, I don't think so. There is at least no "IsSnapped" property or similar that you can use.
You will have to rely on the Left value and adjust it based on the difference in size between the different screens that are involved I am afraid.
I have a custom Panel implementation that renders objects relative to a physical space (think like a floor plan). The panel allows the following actions:
Zoom in/out
Pan up/down/left/right
and more that isn't relevant to this question
The panel lives in with several other elements on screen, and I need to make sure the custom panel's graphics don't spill over the navigation and other controls.
The problem is this:
If the panel is set to clip, it clips the children before arranging them.
Let's say I have a circle in the floor plan and the user zooms in enough to make the circle bigger than the parent control. The panel applies clipping to the circle as if it were placed dead center, then arranges the circle where it is supposed to be. The end result is that the circle no longer looks like a circle and I have gaps in the image.
I need the clipping to be applied after arranging the elements, or only applied to the overall image as compiled by the children. How can I do this?
It turns out I had the opposite problem of the question the OP had in his letter to Dr. WPF where ClipToBounds = "Maybe"
If I override the GetLayoutClip() method in my control and return null, I essentially turn off clipping for the element. However, since ClipToBounds is still true for my panel, the rendered item doesn't spill over the rest of the application.
In the base class for all items that will be added to my custom panel I have this:
protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
return null;
}
In my case this is exactly what I want. I honestly want my layout clip to be based on the parent panel and not the child size (with no sense of location within the panel).
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 new to silver light and would like to understand a bit more from the pros. Let me tell you what I am trying to do. I am into photography and my goal is to create a web site that allows users to view their images and be able to rotate, zoom, crop, special effect etc. I have developed the web site that allows users to order pictures but now I want to start working on the actual picture/image manipulation. So for testing i put a canvas and a rectangle( with an image). Placed a slider and was able to link the slider to the rectangle. As i increase the slider the image gets larger. But I was kind of hoping as the image gets larger it does not surpass the boundries of the canvas. I assumed that is what it means by being a child of a canvas. Am i mistaken? If so how do you suggest me doing this? Remember I am very new to this and may be going about this very wrong.
Thanks!
Your are right. In Silverlight (like in WPF, WinForms etc.) gui-elements form a hierarchy of elements wherein controls can act either as parents or as children.
The reason why your rectangle surpasses the boundaries of it's container lies in the way controls are getting aligned. This depends on what kind of container you want to place your child into.
In a canvas for example you position the children with absolute measurements (left, top, height, width). In a self-organizing container like the StackPanel you choose an horizontal alignment (Left, HCenter, HStretch, Right) or a vertical alignment (Top, VCenter, VStretch, Bottom) which determines the childs behavior when you place it inside the parent. Furthermore you can specify the dimension of the child (Width, Height) and an optional margin which determines the gap between the Top, Right, Bottom and Left bound of your child to its enclosing parent.
But what ever container you choose it's inherent to it that you can let its children surpass its boundaries e.g. with a margin that is negative or greater than the container boundaries or simply by an child that is bigger in dimension that its container as you described the situation with your rectangle.
In your case I would consider working with the idea of clipping. Clipping simply means to
(1) define an geometrical area (in Silverlight and WPF it is a Path object) which lies over some graphical context (some section of your ui or your control etc).
(2) what lies inside the boundaries of this clipping area remains visible and everything else remains invisible.
So you can think of a clipping area as a window onto your screen which you use to look through.
When you are using Microsoft Blend this is easy to realize:
(1) Just use a geometrical shape like a Rectangle, a Circle or a custom Path.
(2) Place it somewhere upon your UI
(3) Right-click the shape, select "Path" and then "Make clipping Path"
(4) and voulĂ , you've just defined a clipping area which you can modify as you are used to modify controls.
Hope this gave you an idea how to deal with your problem.
cheers.
I have some problems with implementing autoscrolling in WPF (I think I could call it that way).
I have a canvas placed inside a scrollviwer. On my canvas I can dynamicly add different shapes. The position of this shapes can be changed with mouse. Everytime I add new shape on canvas or change position of shape I fire measureOverride function.Thanks to this scrollview "know" the real size of canvas and the scrollbars appear. However even if scrolbars appear, the view doesn't "follow" shape which I currently move. I mean if I reach visible part of canvas I would like canvas to srcoll.
I was trying to use this function
ScrollToHorizontalOffset()
However I have problem with proper use of that function. I was trying to use (as a parameter) canvas actualwidth but it didn't work well. I also was trying to use as a parameter current position of shape (which I move) but it works only one way. I the viewer follow the moving element if I was moving this element to right side of canvas. However if I move shape back(to the left) the view don't follow the shape.
I hope somebody will understand this :) It is hard to explain my problem.
I also was trying to use as a
parameter current position of shape
That is the correct way to implement. Waht you need is a converter, which will returns the position according to the direction you move the object.