Placing a shadow over a WindowsFormsHost? - wpf

I have a WPF grid docked next to a RichTextBox hosted inside a WindowsFormsHost. The grid has a shadow that overlays the WindowsFormsHost, however, it's not showing over the WindowsFormsHost.
Is this a generic issue with hosting Windows Forms controls or is there a workaround?
Thanks in advance.
<WindowsFormsHost x:Name="WinFormsHost" Focusable="True" Background="White"/>
<Grid Background="White">
<Grid.Effect>
<DropShadowEffect Direction="90" Color="#FFC3C3C3" BlurRadius="15" Opacity="0.2"/>
</Grid.Effect>
</Grid>

WindowsFormsHost operates at the highest z-index and cannot be overridden. It's an old issue called the "airspace problem". Unfortunately there is no workaround.

Related

Place control on top of Microsoft.Toolkit.Wpf.UI.Controls.WebView

<Grid>
<!-- xmlns:webview="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView" -->
<webview:WebView ... />
<Grid x:Name="Overlay"
Panel.ZIndex="1000"
Background="Red"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
I am trying to overlay a WebView with another control (Overlay). But it seems that the WebView is always on top of other controls.
Is there a way to place controls on top of a Microsoft.Toolkit.Wpf.UI.Controls.WebView?
The Webview control is a wrapped UWP control which in turn wraps a win32 component I believe.
Due to airspace problems this control will not support transparency and will always be rendered on top. See here for a better description:
https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/technology-regions-overview
Although it is possible to run it in a popup as a workaround, it might not be very futureproof:
"WebView controls can be hosted in a popup window. We recommend that you do not do this because support for that scenario will soon be disabled for security reasons."
See here for more
CefSharp might be a better solution. It it based on Chromium and there is a Nuget package available. In the example below a red grid is rendered over the browser:
<Grid>
<cefSharp:ChromiumWebBrowser Address="https://github.com/cefsharp/CefSharp/wiki/Frequently-asked-questions" />
<Grid x:Name="Overlay"
Height="100"
Background="Red"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
Output:

WPF Rounded Corners on a Border in a Window Without AllowsTransparency

I have a problem similar to this, but I have a window that cannot have "AllowsTransparency=True" because the WebBrowser inside it would be rendered invisible. The corners of the window come out black and I need them to be transparent.
Changing the background color to transparent has no effect. I've found that you can wrap a border with rounded edges around a popup with this problem, but you can't do that with a window.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Background="Transparent" AllowsTransparency="False">
<Border Padding="0" Margin="0" BorderThickness="1" CornerRadius="100" Background="AliceBlue">
<StackPanel>
<TextBlock HorizontalAlignment="Center">v This is a webbrowser v</TextBlock>
<Border BorderBrush="red" BorderThickness="5">
<WebBrowser />
</Border>
</StackPanel>
</Border>
</Window>
Any ideas?
---EDIT---
I've tried every form of the WebBrowser Overlay solution, but my specific problem can't use it. I need a solution that has AllowsTransparency="False".
You seems to have a problem of interop between webbrowser window and a wpf window
so when you set wpf window to be transparent it effectively make the browser transparent as browser is in the hierarchy of the main window
so the whole idea to overcome this issue is to host a browser in a separate native window and overlay it on the transparent wpf window
you may follow WebBrowser control on transparent WPF window

Windows phone layer

How can I create the effect similar to Windows Phone's MessageBox, where the message gets displayed on a new layer with transparent background, so that the windows becomes modal? My layout is created out of Grid, so I do not know how to add any content over it. Please help.
It's easy to overlay one set of content with another in WPF. Try changing the visibility of the border below, for a simple message box effect. You would of course bind Visibility to your view model, or set it in code behind.
<Grid>
<Grid>
<!-- All your layout here -->
</Grid>
<Border Height="100" Width="100" Background="Azure" Visibility="Hidden">
<TextBlock Text="Hi there" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>

wpf: custom window drop shadow

I'm working on a c# wpf app with a custom window (allowtransparency = true, resize = none, window style = none).
Now I would like to add drop shadow similar to the zune pc software. I read up on this and the included dropshadoweffect is not covering all angles of my window and it is said to kill performance.
I want to implement it like this: I add a margin to my layout grid which I programmatically remove when maximizing the app.
What is the best way to add a drop shadow which can be applied to a grid, which doesn't kill performance and drops shadow in all directions?
I've tried the solutions posted here but none of them were getting me close to the end result which I wanted (See screenshot below). So I tried out a couple of different things and I am posting my solution here, just in case someone would be interested in achieving something similar. BTW: if you could improve my solution, please do let me know because I find it a bit redundant at the moment.
Ok now for the code that drives this effect:
<Window ...
WindowStyle="None" AllowsTransparency="True" Background="Transparent"
...>
<Border>
<Border.Effect>
// opacity does not need to be specified but it looks cooler when you do
<DropShadowEffect BlurRadius="20" ShadowDepth="0" Opacity="0.8"
Color="Blue" />
</Border.Effect>
// make sure the value for Grid Margin is the same as DropShadowEffect
// BlurRadius
<Grid Background="White" Margin="20">
// I tried setting borderthickness and borderbrush to the previous
// <Border> element but instead of the border being shown right after
// the grid and before the drop shadow, it would show after the drop
// shadow making the overall effect very ugly
<Border BorderThickness="1" BorderBrush="Black">
// now you can specify whatever you want to display in the window
<Grid>
....
</Grid>
</Border>
</Grid>
</Window>
DropShadowEffect doesn't "kill performance"... it is rendered using hardware acceleration, and rendering a drop shadow on a window is not a big deal for current GPUs. You're probably confusing with DropShadowBitmapEffect, which is software rendered. Anyway all BitmapEffects were made obsolete in 3.5 SP1 and don't work at all in 4.0, only Effects can be used now
Direction of -75, ShadowDepth of 2 and BlurRadius of 27 helped for me.
Best way is to use blend for doing these.
HTH
Building off of Princes's code, I wanted to paste a final product.
<Window x:Class="RDNScoreboard.Views.InitialWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="InitialWindow" Height="300" Width="300"
WindowStyle="None"
AllowsTransparency="True" Background="Transparent"
BorderThickness="3" >
<Border>
<Border.Effect>
<DropShadowEffect BlurRadius="27" Color="Black" Opacity="0.8" ShadowDepth="2" Direction="-75" />
</Border.Effect>
<Grid Background="White" >
</Grid>
</Border>

GridSplitter is hidden by WinForm element

I am working in a WPF application. And my problem is regarding the GridSplitter visiblity.
In my xaml code,I am maitaining a Grid. In the 3rd row of Grid, I am hosting a Winform DataGridView. In the same row, the GridSplitter is written.
When GridSplitter is dragged to adjust Grid Row sizes, for other controls like Buttons etc it is properly visible.
But when it comes over the DataGridView which I am hosting, the GridSplitter hides behind the hosted control.
In fact, whatever I host instead of Datagridview,makes the GridSplitter hide behind it, when it is dragged.
I tried setting the ZIndex for GridSplitter. It did not make any difference.
Can anyone help me with this?
Following is my XAML sample code:-
<Grid>
<Grid.RowDefinitions>
<RowDefinition Name="rowForButton"/>
<RowDefinition Name="rowForGridSplitter" Height="Auto" MinHeight="81" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Height="50" Width="110" Content="Button in First Row"/>
<my:WindowsFormsHost Panel.ZIndex="0" Grid.Row="1" Margin="30,11,138,0" x:Name="winHost" Height="58" VerticalAlignment="Top" OpacityMask="Transparent">
<win:DataGridView x:Name="dataGridView"></win:DataGridView>
</my:WindowsFormsHost>
<GridSplitter BorderThickness="1" Panel.ZIndex="1" Grid.Row="1" HorizontalAlignment="Stretch" Height="5" ShowsPreview="True" VerticalAlignment="Top">
</GridSplitter>
</Grid>
Thanks.
Unfortuantely the WinForms control will always sit on top of your WPF elements, it does the same when you try and scroll it. The best way to work around it is to put the required logic for sizing/scrolling/whatever the WinForms part into a WinForms control, then host that control in the WPF form.
Your Grid has only 2 rowdefinitions but needs 3. At the moment the WindowsFormsHost and the GridSplitter are sharing the second row (i.e. Grid.Row="1"). Presumably you want the WindowsFormsHost to use Grid.Row="2".

Resources