Click through semit transparent WPF application - wpf

I created a WPF application that has an overlay mode. In this mode, the whole application gets semi transparent. I'd now like to be able to click through this window to operate with elements behind it [other program UI's, desktop icons etc.]
I wonder if there is the possibility to configure the window right away to represent this behaviour. I set up my application window like this:
WindowStyle="None" AllowsTransparency="True" Opacity="0.5" Background="Black" IsHitTestVisible="True" Focusable="True" IsTabStop="False"
If I set the Background to x:Null or Transparent, I can click through the application. However, the application is not visible at all any more then.
If this is not possible directly, I thought about another solution:
When clicking on the Application, minimize it, execute another mouse click, and then maximize the application. I found some example code for a global mouse click which looks like this:
MouseEventArgs e = new MouseEventArgs(Mouse.PrimaryDevice, 0);
e.RoutedEvent = Mouse.MouseEnterEvent;
youUIElement.RaiseEvent(e);
// Or
InputManager.Current.ProcessInput(e);
However, I think this will not work when trying to do double-clicks.
So, general desire in a few words:
Semi-transparent WPF application, always on top, click-through. Also Keyboard input should pass through.
I set up a special hotkey that brings the application back.
Any helps / ideas?

Related

WindowStyle None and touch input

In Windows 10, when using touch device like Surface, touching an input control like a TextBox in a not maximized window, causes moving the whole window up, so that the user can see what he is typing (if keyboard is docked). But it does not happen when WindowStyle is set to none. Why it does not happen? We need this behavior in our app. Can it be fixed on WindowStyle=None? I found it's not connected with it's style - there are no build in triggers or something. We need WindowsStyle=None for custom close button bar (we want the bar to be transparent, only the button is visible).
I faced a similar issue trying to get my application to react to the presence of the Windows 10 touch keyboard properly, but it wouldn't do so unless WindowStyle was set to something other than None.
Struggled with it for a while, until I decided to just try and style the Window myself and removing the borders manually, which led me to discover the WindowChrome class.
The WindowChrome documentation mentions this about WindowStyle="None":
One way to customize the appearance of a WPF application window is to set the Window.WindowStyle property to None. This removes the non-client frame from the window and leaves only the client area, to which you can apply a custom style. However, when the non-client frame is removed, you also lose the system features and behaviors that it provides, such as caption buttons and window resizing. Another side effect is that the window will cover the Windows taskbar when it is maximized. Setting WindowStyle.None enables you to create a completely custom application, but also requires that you implement custom logic in your application to emulate standard window behavior.
So it seems that because this non-client (or OS) frame is missing, it causes the application to not be able to react to the keyboards presence.
The solution is to implement a custom WindowChrome. This can be done like this:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:System.Windows.Shell;assembly=PresentationFramework"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome NonClientFrameEdges="None"
UseAeroCaptionButtons="False"
CornerRadius="0"
GlassFrameThickness="0"
ResizeBorderThickness="0"
CaptionHeight="0" />
</shell:WindowChrome.WindowChrome>
<Grid Background="DarkOrange">
<TextBlock Text="TEST" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="32" />
</Grid>
</Window>
If you absolutely must use WindowStyle="None", then according to the documentation above, the Window logic must be custom. Fortunately there's a nice example from Microsoft on how to write custom logic to react to the presence of a touch keyboard: See this link.
If you would like to add your own custom buttons to the title bar, check out this excellent post about styling your Window.
Hope this helps!
UPDATE:
After further investigation, it turned out that this solution only worked on Windows 10 version 1903. When tried on 1809 which we use in production, it didn't work. The reason is that apparently Microsoft have changed the way applications react to the touch keyboard when in full-screen mode.
This can be easily tested by maximizing Explorer in both versions of Windows, and to see how in 1809 nothing happens, but in 1903 the Window is resized to fit the remaining space on the screen.
Another important thing I noticed is that when I start the application from Visual Studio (whether debugger is attached or not), when the touch screen shows up, the UI doesn't react to it, but when I run the executable from explorer, then it does work. So in my testing I would always build, then go to bin\Debug, and start the exe from there.
Take the Grid Layout divide it into 3 rows and add the one custom button to the top right corner of row and on that button event handler do the Window closing code and same for minimizing
and Set the WindowStyle=none

In WPF, how do I create a dialog-like window (i.e. gray background with no border around the client area)?

I'm trying to create a simple 'dialog'-type window in WPF. However, for this specific instance, I do not want the client area to have a border, or even a background for that matter. I just want my controls to appear over the background of the window the way they do with a simple MessageBox.
I played with the different values for WindowStyle but they all called out the client area with a color. I also tried simply setting the client's Background to transparent, but that didn't work either just rendering it in black.
Here's a crappy Photoshop job showing what I'm after:
Note: I'm not after the messagebox contents themselves--e.g. the icon, buttons and message, etc.--I'm only asking about how to suppress the client area from appearing in any window. I just happened to use a messagebox as an example as someone linked to it in their answer.
As you can see (or rather can't) there is no visible demarcation of the client area.
Used to be so simple in WinForms, but WPF has me stumped. Anyone?
I'm not sure what you're after. Do you want only the controls on your dialog to be visible with the dialog's border and background transparent? If so, try these settings on your dialog:
WindowStyle="None"
ShowInTaskbar="False"
AllowsTransparency="True"
Background="Transparent"
If you want your dialog's background color to the Winform System.Control with no border, set your form's Background like this (instead of Transparent):
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"

Lightbox-style popup in WPF -- how?

(I am trying to learn WPF using tutorials and documentation, and trying to develop a user interface for my backend-complete application while I do say. I've heard people say that the learning curve is quite steep. But sometimes I wonder whether what I'm trying to do is actually something that's hard to do in WPF, or if it's simple but I'm thinking in wrong terms, or if it's neither, it's quite simple but I just happen not to know how.)
Here's my current question. I wanted clicking that clicking some part of my UI will bring up a 'popup' where the user can enter more information. I would like a 'lightbox-style' popup, i.e. the popup is modal to the page, it darkens the rest of the page to become the center of attention, etc. These are seen commonly on Web sites.
A bit of searching led me to the WPF Popup control. I added it, put my content in, set the IsOpen property to True, and -- presto! A popup. Then I added an invisible Rectangle that covers my whole window, and set it to Visible as well when I want my popup to open. Great!
So now I wanted to do this dynamically, because sometimes I will be loading a record which will sometimes have a need to open another control (a UserControl) in a popup to edit its information. So I made myself a method called OpenPopup. But I can't seem to find a way to write this method using WPF. In Windows Forms I'd have written: (I use VB.NET)
Sub ShowPopup (form as Form, ctrl as Control)
'Create 'rect' as new dark rectangle control
'Z-order it to the top
'form.Controls.Add 'rect'
'form.Controls.Add ctrl
'Z-order 'ctrl' to the top
'Center 'ctrl'
'Set focus to it
End Sub
But with WPF I run into problems:
1) I can't add it to the WPF window, because it already has a child.
2) If that child is a Canvas, that's not too bad. I can detect that, and add it to the Canvas. I have to find some way to set its Left, Top etc. properties and Width and Height, since those do not seem to be properties of the Rectangle control but rather extended by the Canvas object -- in XAML they're called Cavnas.Top etc. but Intellisense is not showing them when I try to use it in code.
3) But if it's a StackPanel? Then my rectangle will just be stacked below the other controls! And not covering them! Is there a way around this?
4) And if the window contains only one control and no container control at all?
5) I think there were more problems I ran into. But let's start with these.
Thanks in advance for your help.
1) I can't add it to the WPF window, because it already has a child.
Ah, the evils of codebehind. The solution is not to add it to the visual tree, it is to place it in the visual tree, ready and waiting to pounce, but hide it from the user's view.
Here's a sample you can drop in Kaxaml that demonstrates the point. Set the Lightbox Grid's Visibility to Hidden to access the hidden content.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Viewbox>
<TextBox Text="SIMULATING CONTENT" />
</Viewbox>
<Grid x:Name="Lightbox" Visibility="Visible">
<Rectangle Fill="Black" Opacity=".5"/>
<Border
Margin="100"
Background="white"
BorderBrush="CornflowerBlue"
BorderThickness="4"
CornerRadius="20">
<Viewbox Margin="25">
<TextBox Text="SIMULATING LIGHTBOX"/>
</Viewbox>
</Border>
</Grid>
</Grid>
</Page>
2) (snip) Intellisense is not showing them when I try to use it in code.
Canvas.Top etal are Attached Properties. Attached Properties are extremely convenient and easy to use in XAML, but they are very confusing and hard to use from code. Another reason why codebehind is evil.
3) But if it's a StackPanel? Then my rectangle will just be stacked below the other controls! And not covering them! Is there a way around this?
I redirect you back to 1. There are also many other container controls in WPF. You should investigate them and observe how they control layout. For instance, my use of the Grid was not to make use of its ability to block off sections of UI for controls, but for its ability to layer controls ontop of each other and to stretch them out to their maximum available size for the available space (the viewboxes are just there to zoom the controls instead of stretch them).
4) And if the window contains only one control and no container control at all?
The root of a window would almost always be a container control. But you control that, so if you needed to add controls to the visual tree at runtime you could easily ensure the child of the window is a container control you could deal with.
5) I think there were more problems I ran into. But let's start with these.
No kidding. My number one suggestion for people in your situation is to drop what you're doing and learn about MVVM. The Model-View-ViewModel is a very simple way to code WPF applications that takes advantage of many of the features of WPF--databinding, templating, commands, etc. It allows you to code your logic not in codebehind (RETCH) but in easy to create and test classes.

WP7: Rotating a popup + content?

I've been googling this issue for some time now, but havent been able to find a solution that worked for me.
The thing is I have a popup control with a user control, in which the user can enter a new value for a listpicker. This all works fine in portrait mode, but if the phone is rotated (emulator), the popup remains in portrait mode. Opening the popup when phone is already in landscape, has no effect either.
Is there any way to correct this issue? I've seen some people suggesting using Rotatetransform, but if I do this on a textbox etc., it disappears completely :/
I think this is potentially a bug in the Popup control; I've certainly heard the question asked before. However, I've also heard that the performance of the Popup controls is not that great, so I think you'd be better off just using a regular framework element (such as a Grid) to contain your popup content and show/hide it (with animation if appropriate) accordingly. At least that way it will get rotated properly when the page orientation changes.
Do not rorate the popup but place a border inside the popup and load the content in the border.
I got it to work like this:
//In .xaml
<Popup x:Name="myPopup">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="480" />
</Grid.RowDefinitions>
<Border x:Name="popupBorder"/>
</Grid>
</Popup>
//In .xaml.cs
popupBorder.Child = new MyPopupPage(); //MyPopupPage is the "Windows Phone Landscape Page"
myPopup.IsOpen = true;

WPF - Animated User Control

Greetings
I'm currently making an application in WPF as I'm fairly new to WPF I'm running into some difficulties. I have Googled my question but with no great success. This is the current situation, XAML of main window below:
<Grid Height="279" HorizontalAlignment="Left" Margin="166,0,0,0" Name="gridScoreboard" VerticalAlignment="Top" Width="808">
<!--Scoreboard Image-->
<Image Source="pack://application:,,,/Images/Style/Scoreboard.png" Width="517" Height="91" HorizontalAlignment="Left" Margin="138,1,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" />
<Canvas Name="canvasRacePlayer1" Width="14" Height="14" Canvas.Left="33" Canvas.Top="66" Background="Transparent" MouseLeftButtonDown="canvasRacePlayer1_MouseLeftButtonDown" Margin="171,70,623,195" />
<local:ucRaces HorizontalAlignment="Center" Margin="93,62,632,187" Width="78" Visibility="Hidden" x:Name="ucRacesP1" Height="33" />
</Grid>
The user control is hidden from the start (ucRaces), once the little canvas (canvasRacePLayer1) is clicked the user control will be shown. However I would like this user control to 'slide' from right to left from a certain point. As if it would become visible in small steps. I have found information for animations for rectangles and buttons but no success really for User Controls.
Thank you in advance
If you are going to create animations for your WPF project, I suggest that you use Expression Blend. You can design your program using EB and implement the functionality of it using Visual Studio. It will be hard to make animations, writing XAML syntax or C# code.
How would you be able to animate your user controls using EB? Well, it is actually very simple. You need to open your existing WPF project first. Then, go to File -> New Item -> User Control, and create the user control. Then, if you want to add it to your project, switch back to the WPF project currently open in EB and click the right arrows (>>) on the toolbar placed on the left-hand side of the screen and go to Project -> [Your User Control Here]. Now you have added it to your project.
If you want to animate the user control, you have to add a StoryBoard to your timeline. When you are on your WPF project in EB, under Objects and Timeline, click the plus (+) sign and add a new StoryBoard. Now, you have a timeline that you need to use to animate your user control. You can place KeyTime attributes on the timeline and define the path the user control is supposed to follow from location A to location B and also the level of opacity if you want the user control to gradually become visible.
You can add one more user control and implement its logic for the second user. Expression Blend will make your life easier.
Animating your UserControl shouldn't be much different from animating any other WPF object: You can either animate the margin (using a ThicknessAnimation), or drop your user control into a canvas of its own, then animate the Canvas.Left property of your user control. In the latter case, take care to put the property name in parenthesis: Storyboard.TargetProperty="(Canvas.Left)".

Resources