0

I am working on an application using WPF and visual c#, and I am trying to implement an annotation feature which allows for drawing on the desktop.

My current way of accomplishing this is by making a total screen-sized window with a transparent background, and putting this over the desktop, allowing me to "write" on this invisible window. However, I have another set of windows that constitute a floating menu of sorts on the screen, and I want this menu to always be interactable, even when the user is annotating (for example, this is where I want to put some annotation options).

When I show my transparent window, however, my menu windows are all behind it, which means i draw over these windows instead of clicking on them. I have tried things like setting topmost on the menu windows, but this does not put them over the transparency.

My current idea now is to make a non-rectangular window out of the transparent window and basically just cut out the region the floating menu is in, and dynamically update this if the user drags the menu to another place on the screen. Is this feasible/possible, and how can I dynamically make these window changes? if this is not possible, is there a better way of forcing all my menu windows to always be on top of the annotation transparency?

edit: as an additional note, is there any way at all to set a z-index of sorts on these windows? that would resolve this, I think, if I could z-index the menu windows all the way to the front and then index the transparency to one behind that, but I was unable to find a way to do this.

edit: someone commented and suggested I re-set topmost = true for my menu windows once I create my transparent window, but this ended up having no effect

FINAL EDIT: I fixed the issue using David Edey's suggestion of setting topmost; turns out I had a rogue line of code setting the transparency as topmost=true, causing this issue when setting the window topmost properties, but now it works like a charm. Thank you so much for your help!

Kevin
  • 35
  • 4
  • Usually, setting Topmost on the menus after you've last set topmost on the transparent window will cause the menus to appear on top of the transparent window. I take it this doesn't work? – David E Sep 11 '14 at 22:01
  • Well, right now I only set topmost when I create my menu windows, and then when I make the new transparency (which doesn't have topmost set either), the menu goes behind the transparency and I cannot interact with it. Would re-setting topmost after transparency creation fix this? – Kevin Sep 11 '14 at 22:47
  • Certainly my current experience with TopMost is that that would certainly be the case. Set the Menu's topmost again after you create the transparent background should solve your problem! If you're finding that hard to achieve, http://stackoverflow.com/a/20050961/3940783 might be a possible way of doing it... But I imagine you must have ways to get your menu back from elsewhere in your App (even if you have to do Application.Current.Windows or similar). Good luck! :) – David E Sep 11 '14 at 23:21
  • Resetting topmost ended up having no effect :/ so the question is still open! – Kevin Sep 12 '14 at 16:28
  • About the z-order: in panels such as Canvas and Grid, child controls are drawn in order. Their z-order is the order in which they appear in the panel. Later children are drawn on top of earlier children. Use that. – Kris Vandermotten Sep 12 '14 at 16:52
  • that sounds like setting the z-order of controls on an individual window, but my issue is that I have other windows that I want on top of this new, transparent window. These windows do not have any parent-child relationships as far as I'm aware. Also, I realized that I was setting topmost on my windows after creating the transparency, if I do it before i call transparency.show(), they stay on top, but now the transparency doesn't show up at all. I changed the background to white and nothing came up, just to confirm. – Kevin Sep 12 '14 at 17:17
  • Oh, didn't see your edit! hahaha - might be worth looking at my 'solution' below and explicitly setting the `Topmost` to `false` first, just in case you run into problems with it down the line. (Otherwise it can fail on the second set) :). – David E Sep 12 '14 at 18:26

2 Answers2

0

...another set of windows that constitute a floating menu of sorts on the screen, and I want this menu to always be interactable,

My recommendation is to place the Menu window controls in question into a single control with dependency properties which expose the business logic of the menu. Make sure the aforementioned properties are two-way bound to INotify properties on a viewmodel which ultimately will be accessed/shared with the annotation window.

When the annotation window comes up, it also creates its own menu window control which has the same zorder as the annotation window. The old original menu is hidden(?) or the new one comes up in its location(?).

By design the new menu window properties are also two-way bound to the shared VM. Hence allowing for changes from the annotation menu to go back to the original window via the shared properties.

This slight of hand with a new control, behaves to the user like the other menu control and also changes the data dynamically, for both annotation and the original. Also the second menu doesn't have the problematic z-order issues which you are running into.

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
0

I have built a replica version myself, and setting:

        Application.Current.MainWindow.Topmost = false;
        Application.Current.MainWindow.Topmost = true;

Brings that window to the front without fail (note that you do indeed need the false call first to actually refresh it sometimes... Not entirely sure why this happens, but it works!) :)

(Obviously replace the call to Application.Current.MainWindow with a reference to your Menu window).

David E
  • 1,384
  • 9
  • 14