WPF Create Bitmap of Window that hasn't been shown - c#

Is it possible to create a bitmap of a window that hasn't been shown without using screenshots?
What I want to do is start my application, and have a main window that displays other windows. I use visual brush to display them after they've been shown, and the image stays after the window is closed, but how do I show an image of the window prior to Window.Show()?

I would guess that the window isn't rendered until it is needed, so there would be no way to get the flattened bitmap of it. I wonder if you could somehow make it "show" without being shown? Can you use Window.Hide() to your advantage? Just throwing it out there.
Also makes me think--why would you want to get a bitmap of a Window? Windows are for presenting UI, not for displaying as an abstract representation of a UI choice. Maybe creating an abstract icon for each choice would be more usable?

No way to do this without creating the Window first, as it won't be in the visual tree until it is created. You may create it in an area outside your working area and generate the bitmap from there. You need it laid-out first also because of bindings, layout transforms, etc.

You should get everything you need here: http://www.west-wind.com/weblog/posts/150676.aspx and here: http://www.codeproject.com/KB/WPF/WPF-Image-to-WebPage.aspx
The key is the RenderTargetBitmap class

Related

How to get WPF usercontrol designheight and designwidth at run time

I need to access a WPF usercontrol's designheight and designwidth at runtime. I know this is impossible, so I'll explain why I want to do it, and hopefully someone can provide an example of the right approach.
From a C# winforms app, I open a new window containing a very large WPF usercontrol. If the monitor I'm running on can handle it, I want it to open the window at the full design size of the usercontrol. If the monitor I'm running on can't handle it, then I want to open the window as large as possible, leaving 1 pixel on each side of the screen. So I need to know the usercontrol's current design width and height before the usercontrol is displayed.
I want to avoid hard coding values in the winforms app, or using unbound public properties in the user control, because then I have to trust other developers to update them when they change the user control. I don't know if it's possible to bind a local variable to designheight or designwidth, or how to code that in XAML. Since I don't know a lot of WPF, there may be some other way to reach the goal that I don't know about.
Thanks for your help and advice.
Why don't you try something like Resize WPF Window and contents depening on screen resolution
The answer suggests that you bind the screen size to the window height and width. It will automatically size the window according to screen size. You can even set a % value for the size of the window.

Custom cursor above every other visual component

I have a Windows Modern App with a custom cursor, that is implemented by having an image that follows the system's cursor.
I just add the custom cursor image to the main grid of my application and everything works fine.
public MainPage() : base(true)
{
this.InitializeComponent();
MainPageGrid.Children.Add(new CustomCursor());
}
But when a popup opens, it gets above my custom cursor. Is there anyway that I can set the Z-index (or something similar) of a component in order for it to be the uppermost visual component of my modern application?
I would recommend using an actual custom cursor. I think this article looks like a decent intro to using these. You could also check this question for some tips on changing cursors. Other than that - I don't think you can tell when a random popup opens. You can poll for these with VisualTreeHelper.GetOpenPopups(), and then do something to make your popup show on top (maybe just reopening would work or maybe you'd need to create a new one every time) but that might not give you a good user experience or performance. You could also figure out all the events that could display a popup from ComboBoxes, Flyouts etc, but that sounds painful. It would probably be best to create an attached behavior that you could attach to all such popup-source-elements to trigger z-index fix-ups of your XAML-rendered custom cursor...
There is no need to implement a component as a custom cursor, as it is possible to override the maximum size limitation:
How to override maximum 32x32 mouse size in Windows like this program can

WinForm Controls are transparent, and not displaying properly

When a form loads, I'd like it to show a loading image (within a Picture Box) and a standard Windows label with some text. However, all I see are white boxes, or sometimes I see another form underneath. How do I get the image and label to display properly.
I've tried setting AllowTransparency to false when the form loads, and also setting the Transparency Key of the form to some other colour, but nothing has worked.
The project is C# .Net v3.5 (also tried v4 and v4.5).
Any ideas?
First, you can't display an image, busy-wait, and then change the image - this will never redraw anything, leading to the symptoms you describe. To "wait" you will need to return control to your main application loop so it can continue to process messages (e.g. to handle redraw requests for your window). One way to do what you want is to display your initial state (splash screen) and then use a timer to call you back later to change the display to your second state.
The next problem you face is using forms controls with transparency. Most controls treat "transparent" as "fill your background with your parent controls color", which is not what you want. An easy way around this is to implement a Paint handler and draw the image and text for yourself - this gives you much more control of how your display looks, and will also allow you to get a cleaner redraw (no flicker or other problems caused by the display being built up but by bit in several controls)
Lastly, consider implementing your splash screen display as a separate control/form that you show above your main form during loading, as that makes it easy to "overlay" on your main form without having to change its design at all.
Just write formObjectName.Refresh() after formObjectName.Show()

Create the "frozen window" effect

You know when you have a window that is frozen, but when you drag another window over the top it leaves a trail? Sometimes it looks a little bit like the end of Solitaire for Windows 3 :) when you get done (like my screenshot).
I'd like to make a C# windows (winforms/wpf) application that creates a surface like this and allows me to capture the image, but I'm a little bit at a loss of where to start.
Picture:
It would be easier with WPF. You can create a VisualBrush from any control, including a Window or FrameworkElement. Once you have that VisualBrush, you can paint it all over your form and it will create that same effect. Alternatively, you could use an ImageBrush if you want to do it with a picture rather than a UI element.
When you paint, just offset it by a couple X/Y each time and it will look just like that as it overwrites (er.. overpaints?) itself!
You can create your own class FrozenVisualHost that derives from FrameworkElement to host a DrawingVisual that you render. See: MSDN: Using DrawingVisual Objects
Overriding your FrozenVisualHost.OnRender() method would allow you to draw your 'frozen snapshots' as you recorded mouse movement (via MouseMove). Just make sure that you call the InvalidateVisual() method to update the host control.
One caveat: Creating a VisualBrush from a window will not capture the title bar or window border chrome. If you want that, you'll have to grab a snapshot manually (GDI): As described here. You can use that Bitmap however for your ImageBrush and do rendering similarly.

Looking for a good WPF solution for a transparent, click-through overlay

I want to try something different, and am attempting to display an overlay on top of my current WPF GUI that allows the user to still interact with the GUI, but provides a layer of annoyance to let them know that something's up.
My question is really two separate questions:
1. How would you do the overlay?
My first attempt was to use a Rectangle, set the Fill to the appropriate color, and then change the Opacity. But it's not transparent to click-throughs. So I think what I want to do, according to search results, is to create a separate window, set its Background to Transparent, and then set AllowsTransparency to True. While this works, if I want to do something like Background="DarkRed" Opacity="0.2", click-throughs no longer work.
And this leads me to the second part:
2. What's the right way to resize this overlay region if I'm using MVVM?
My main window creates the ViewModel, which creates the Model. The Model is the only thing that knows about whether or not the overlay should be displayed. But the main window obviously is the only thing that knows its size, and the Model never knows about anything above it. Is the only way to achieve this to databind the overlay Window's size to properties in the ViewModel, and then have the ViewModel set these values any time the main Window's size changes?
Anyone have clues on how I can achieve all of these things?
To address part 1: set IsHitTestVisible="False" on your overlay, be it a Rectangle, Border or some other element. This will allow you to make it whatever color and transparency level you want without affecting interaction with the underlying controls.
Part 2: you shouldn't use a separate Window. If you keep the overlay in the main Window you can rely on the layout in your view to automatically handle sizing of the overlay.

Categories