Here's the basic idea of what I'm trying to do; have this (see image link) graphic with roots going into the ground and the roots split off into different directions. At the end of each root I'd like to place a round button with a number in it which will take them to a new page. (the image only shows a few buttons but later on, for updates i'll have more lessons, meaning more buttons, and so the page would scroll down revealing more buttons)
What I have tried; I tried drawing a dynamic root system graphic, which worked and resized properly based on the screen size. But Skiasharp doesn't really work with absolute layouts and adding buttons on top of the SKCanvas. From my understanding absolute layouts are the only way to but buttons in customs spots.
I'd like to have the Graphic dynamic and locked onto the buttons. I'v tried just placing the buttons over the top of a background image that already had the root graphic on it. But, they don't always align properly.
Is there a way to make this work, or another way to draw the graphic and have the buttons bound to the end of the roots? Or am I just stuck with not having them align with a static background image?
Concept image for app page is below:
In WPF, I have a custom "toolbox" which consists of Label controls and some vector icons docked to the left of the screen.
In the center, I have a Canvas control which I eventually am going to need to serialize out the relative coordinates (for other platforms) for this "designer surface".
Basic question, I can drag/drop controls from this psuedo-control box onto a Canvas but I need to know how to place this WPF control properly in the canvas, under where the mouse pointer is, realtive to the Canvas and not the screen or main Window.
What are the functions that needed to be called so that I can ensure that if I drop a Button control at 10%, 20% of the canvas, I get an actual location back and the button drops where expected?
Mouse events provide a Point structure.
Converting of positions can be done by Control.PointToScreen and TargetControl.PointToClient.
I have a UserControl that is basically a ViewBox inside a Grid with a Border. The ViewBox has a background image and I blit various little icons onto the image. The icons are nothing more than pixels painted onto the background image. In code-behind I can detect when the mouse stays within the bounds of on one of these icons for more then 500ms. I call this a 'hover event'.
When I detect a hover event, I need to pop up something that shows details unique to the object represented by the icon. These details are not just text, there could be images of small graphs, so I think the popup needs to contain a StackPanel. I would like it to pop up, via some slick animation, at a location I specify near the location where the pointer is hovering.
Can someone please show me how to 1) create a popup containing a StackPanel at any given location in the ViewBox and (optionally) 2) have the popup use some slick animation when it appears?
I'm working on a simple application with text animations and videos as background.
It's really similar to a simple LED scrolling text and I'm using the animations framework of WPF for this (Storyboards and timelines).
My text comes from the right side and finishes animation to the left side, thus it is visible for the entire width of the window.
Now, what if I want to display this text only in a specific rectangle of the window? The text would normally come from the right and finish to the left, but should be visible only when passing through this rectangle. Imagine it like a "rectangle hole" in the background where the text is shown.
I hope I have been straightforward in my explanation!
Thank you.
Is it an opacity mask you're after?
http://www.c-sharpcorner.com/uploadfile/dbeniwal321/implementing-opacity-masks-in-wpf/
Obviously you won't be using gradients of opacity as seen in the article - you'll use a more strict rectangle outline and play your animation as usual - using the bounds of the mask as the boundaries of your animation.
Text in a Canvas. Set the size and position of your Canvas to be your rectangle hole. With clipping on, when the text is outside the Canvas, it will not show. You just animate Canvas.Left attached property on your text.
I have a panel (here called parent), where I draw a calculated picture.
Some rectangular areas of this picture shall higlight by hoovering over.
It is the same behaviour like on a web page using , and , e. g.
the german map on the right upper side.
At hoovering the according rectangle shall be covered by a half transparent blue .
(And depending on keys like Alt, Ctrl and/or Shift in other colors, and clickable).
The first solution was a single instance of a transparent Panel - inherited from the Panel class.
In the hoovering event of the parent I moved and resized the single instance to the right place, changing the color.
This had some problems:
* moving and resizing (SetBounds()) fired MouseLeave event of the parent and a MouseEnter event of the single panel. The events had to be adapted accordingly to get it working correctly, I did it, but it is was very slow, due to finding the right map area from the list.
The second solution was to generate dynamically an instance of a transparent panel for each map area.
Each transparent panel had to set the e. g. Color.FromArgb(50, Color.Blue) at entering, and
remove it at leaving the panel.
But it seems to be even slower than before.
If the mouse hurries over several maps, they are all drawn like hoovered, and slowly get transparent again.
Does anybody know a good solution for this requirements:
at picture resize in parent panel, map etc. has to be changed as well
partly transparent highlight hoovered rectangle area.
detection of Ctrl/Shift/Alt as events for an area and change of the color.
detect click events there
Are there other controls I better use for this purpose?
Thanks for on practice based ideas.
PS: The world map with satellite pictures shows better what I want to do:
At hoovering the background is still visible more or less.
But in my case the parent image, its size and the maps are calculated at runtime
(after settings are completed by the user).
Solution
Description
I found now a solution, that reacts sufficiently fast to hoovering areas with the mouse.
The Main pictures is drawn in a PictureBox instance, in more detail its property Image is assigned.
The SizeMode property is set to Zoom, that automatically centers and resizes the image with keeping the aspect ratio of the assigned image.
I use a dynamically created Picturebox instance for each map area (childs), that is invisible, if the mouse does not hoover over it.
At hoovering over the map area the child shall appear - this is done in the mouse move event of the parent PictureBox,
where I iterate over the children, detecting whether the mouse position is in the bounds of a child.
The found child is set visible. Therefore the mouse enters this child control.
In the leave event of the child control I set it invisible again.
I experienced losses of mouse leave events for the child controls, if the mouse is moved too fast over all map areas.
I assume, if the mouse pointer already left the area before it has been set visible, the event is never raised.
The solution is, that all (other) child controls are set invisible, if in the mouse move event handler of the parent control does find no (a) child control.
Steps to implement
What to do, to implement my solution:
Use a designed parent PictureBox instance.
Assign the (dynamically) drawn picture to the Image property
Set SizeMode to Zoom
a list of Picturebox instances as form field
At assignment of a newly calculated image to the parent Picturebox instance:
remove all child controls, its event handler, its entry from the list, if they already exist.
create dynamically a PictureBox instance for each map area and add it to a list.
add it to the parent PictureBox instance as a child control.
set its Tag property points to a data object containing the origin map bounds and the object represented by the rectangular map area.
set the bounds to the map area scaled and centered according to the bounds of the parent Picturebox instance, that it suits the automatically zoomed image.
register a mouse click event
register a mouse leave event
set background color to e. g. semi transparent green
set Visible to false
In the parent Picturebox instance the mouse over event handler does:
finding the child Picturebox instance, where the mouse points at
if found it sets the found child visible
set all (other) child Picturebox invisible
In the parent Picturebox instance the resize event handler does:
scale/move all the map area Picturebox instances according to the bounds of the parent image and the bounds of the parent Picturebox instance.
The mouse leave event of each map area Picturebox instance set itself invisible (losses of events previously mentionned).
The mouse click event of each map area Picturebox instance makes whatever shall be done by clicking the map area.
Here playing a sine tone of the right chromatic pitch.
Pictures
The pictures below show the prototype with the map areas (not yet correctly aligned, some offset):
The first picture is for illustration of parent picture and all map areas.
The main picture (scale) and all map areas (dynamically created child Picturebox instances) are drawn in the first picture (by disabling the invisible action for map areas).
The second image is productive, where the mouse hoovers over tone G4.
In the second image the form has been resized - therefore the parent image is automatically been centered and resized.
The map areas were simply changed in their Bound property in the resize event handler of the parent PictureBox.
And the invisible action has been enabled for the map areas.
I checked the ImageMap:
It is a user control, that contains a static image, that was drawn before compile time.
At runtime the clickable areas are added – rectangle, polygon, ellipse are possible.
It uses a PictureBox, that is created as child of the ImageMap (that is inherited from UserControl).
It registers a Click, a Move and a Leave event to its event handlers.
In these event handlers it checks the current position against the list of paths in a GraphicsPath instance and returns an index (int).
The ImageMap keeps track of the last selected index (-1 = no object selected), sets the cursor accordingly (hand or default), sets or removes the tooltip.
But it has no hoover event, it does not change the area at hoovering, like I need it too.
Therefore I can need ImageMap it for proper detection of area,
but my picture is drawn at runtime!
And still I have to switch on and off the rectangles with its semi transparent layer.
I got the idea to use the property Visible to switch on and off the controls for the areas.
That it is easier to draw, I will set the background to the part of the parent image,
covered with the semi transparent color - this is a workaround, that is possible,
because the maps are relatively fixed to the parent picture.
If I have time, I will test this solution idea - it is a private project, therefore I can not work fulltime :-).