How to move WPF window above top of screen? - wpf

I have a window with the following:
Background="{x:Null}" AllowsTransparency="True" WindowStyle="None"
Dragging the window by hand beyond the left, right and bottom limits of the screen results in a predictably cropped window. However this behaviour is not the same for dragging it above the top limit. Instead of cropping, it pushes it back down as if there's an automatic If Window.Top < 0 Then Window.Top = 0.
This is probably in place so that users don't lose a Windows titlebar (which is the standard way to drag windows around, and losing sight of that effectively makes it undraggable). I don't need that as my entire window is draggable via Me.DragMove().
So, how do I let a window be dragged above the top limit of the screen?
(This is unrelated to Aero Snap which only occurs if the mouse touches the borders. I'm trying to move the window beyond visible bounds)

The DragMove function do not allow you to drag a window above the screen. You need to manually move the window, for example:
How do I move a wpf window into a negitive top value?

Related

Force a window to be always maximised

I have a WPF application that I want permanently maximised.
The application starts off maximised and that's fine.
I have set the ResizeMode="NoResize" and while this does prevent the window from being resized (by dragging the edges of the window), I find I can drag the title bar down, and the window will resize to a "Restore" state - i.e. partially filling the screen. At this point the window can't be resized (as I'd expect) or maximised once again (even if I drag the title bar back to the top of the screen)
Is there a setting that will just not allow the "restore" functionality and force the Window to always be maximised?
Edit
I've discovered this is actually a window setting, and if I turn off "Arrange windows automatically by dragging them to the corners of the screen" in Settings / System / Multitasking it prevents this (I also needed to remove the ResizeMode="NoResize" funnily enough otherwise dragging the title bar just drags the entire maximised window down).
However, I can still "Restore" it by double-clicking on the title bar. I can maximise once again by doing it again, but I don't want the user to be able to restore the window at all.
Strangely enough, doing it this way ResizeMode="NoResize" lets me restore a maximised window, but not maximise a restored normal window... I'd be happy with the other way around...

Detecting X11 window resize towards top/left

I'm working on a mapping application and I'm trying to get resizing in X11 working the way I'd like. Conceptually, I'd like my window to be a viewport onto some real-valued space where my data lives. When you resize the window, the size of your view onto this real-valued world should change accordingly.
What this means is that when resizing the window, rather than shrinking/stretching the data, more or less of the underlying window becomes visible. It's easy to handle the case when the window is resized by growing/shrinking on the bottom/right, but I'd like to handle the case when it's resized on the top/left as well.
This is trickier, because a top/left resize also moves the window's origin as well as it's dimensions. I need to detect the change in the origin so that I can compensate to keep my data centered as the window is resized.
Is there a robust way to get the absolute coordinates of a window in X11? The coordinates that X11 reports directly through ConfigureNotify and XWinAttributes are dodgy due to window manager reparenting.
In Xlib use XTranslateCoordinates to translate the coordinate (0,0) in your viewport window into coordinates of the root window. This also covers the case of a stacking window manager messing with your window position.

Scroll to WPF elements outside boundary

I'm editing a WPF Window object in Visual Studio and have a canvas element that stretches outside the boundary of the Window. Visual Studio only gives a zoom in/out feature, but I can't scroll left or right, even though my canvas inside the Window stretches way off the right of the screen. How can I scroll out all that way?
Thanks,
Dave
Your big canvas must be contained in another container with a constrained size. Try to set SizeToContent="WidthAndHeight" on the window.

(VB.NET + WPF) Drag + Drop (to allow user sorting) of stackpanel elements within a Scrollviewer?

I have good model (I think!) for how to allow a user to drag an element in a stackpanel and reposition it to another location within the stackpanel.
However, my Stackpanel is placed within a ScrollViewer, like this (generalized):
<ScrollViewer>
<StackPanel>
....First item
....Second item
....Third item
....Etc.
</StackPanel>
<ScrollViewer>
Here is the problem, I wish to simulate the functionality of programs like word, where if I am dragging selected content (or an object) outside the viewable area, the window will scroll in the direction of the mouse to see more places to drop my nifty little object.
...i.e. If I move the mouse to the top of my ScrollViewer while dragging a stackpanel's contents, I want the scrollviewer to slowly move up so I can see more locations to drop my content.
Any suggestions?
If you can help me solve this, you will be a godsend!
No problem. Handle the DragOver routed event at the ScrollViewer level. Get the position. If it is near the top of the ScrollViewer bounds, scroll up. If it is near the bottom of the ScrollViewer bounds, scroll down.
The scrolling itself is done by calling scrollViewer.LineUp() or scrollViewer.LineDown().
The DragOver events come frequently, so save the value of DateTime.Now in a field each time you call LineUp() or LineDown(). Before calling them again, check DateTime.Now and if not enough time has elapsed, don't call LineUp() or LineDown().
For better control over scrolling speed you can use scrollViewer.ScrollToVerticalOffset(scrollViewer.ContentVerticalOffset + delta) instead of scrollViewer.LineUp() and scrollViewer.LineDown().
You can provide a better user experience if you allow faster scrolling when nearer to the top or bottom of the scroll viewer. This can be done by dividing the scroll area into zones, or calculating the speed from the mouse position. In this case, speed changes can be done by calling LineUp()/LineDown() multiple times when closer to the edge, or by increasing the delta value if you are using ScrollToVerticalOffset. You probably should not modify the timing (DateTime.Now comparison) for this purpose, because it will be unreliable.

WPF - how to best implement a panel with draggable/zoomable children?

I'm trying to modify the default graph viewer of the Graph# library because its user interface is awful (just try dragging a node outside of the boundaries, you'll see!)
The basic setup is this: there is a GraphCanvas control (inherited from Panel) which has children of Vertex and Edge control types. What I want to achieve is:
GraphCanvas has scroll bars if the contents do not fit in the screen;
GraphCanvas can also be scrolled by "dragging" it (just click on an empty space and drag);
GraphCanvas can be zoomed in and out (via CTRL+mouse wheel);
Vertices can be dragged around. If a vertex is dragged outside the current boundaries of GraphCanvas, the boundaries are increased. The scroll bars should reflect this, however the current viewport should not scroll away while the vertex is being dragged . The same goes if dragging a vertex reduces the boundaries of GraphCanvas - it should stay the same size until the drag operation is finished and resize only then. Automatically scrolling the viewport during a drag operation is awfully confusing and easily introduces dragging errors. See the original implementation if you want to know what I mean.
Although I've got a fair bit of experience with .NET, I'm still a complete beginner in WPF. My current attempt is (in the measure/arrange layout phase) to give each vertext the XY coordinate it desires (even if negative) and implement zooming/scrolling by handling mouse events on the GraphCanvas and modifying the RenderTransform property. Dragging just changes the XY coordinates on the specific vertex (probably triggering the re-layout of the whole thing which would be nice to avoid too). Scrollbars are implemented by placing the GraphCanvas inside a ScrollViewer and implementing IScrollInfo on the GraphCanvas.
Unfortunately there seems to be a problem: I can get mouse events on the GraphCanvas itself only if it has a background at the point. That would be OK, I want a white background anyway, but in the negative coordinates of the GraphCanvas it does not draw the background - and thus does not respond to mouse events.
I'm also wondering if I'm doing the Right Thing by allowing all my child controls (vertices and edges) to go into negative coordinates. How would you implement this?
Added: To clarify about the background problem check out the following screenshot:
(source: valts.21.lv)
What you see here is a simple Windows Forms form with a WPF Host control on it. That has a ScrollViewer in it, and the ScrollViewer has the GraphCanvas in it. The GraphCanvas contains 4 vertices and 6 edges.
The GraphCanvas is stretched to fill the ScrollViewer. But since some of the vertices are at negative coordinates, it has a RenderTransform applied which simply shifts everything to the right (TranslateTransform). It also has a white background brush.
Note the gray area on the left. That's still a part of the GraphCanvas, but the background brush somehow doesn't exted there. Also, if I left-click there with my mouse (not on a node, but on the gray area), I do NOT get an event. If I left-click on the white area, I get all events just fine.
Call CaptureMouse on canvas.mouseDown and ReleaseMouseCapture on mouse up. Also, if you set your canvas background to transparent it will still be hit testable
You can attach a 'Draggable' behavior to each element.

Resources