WPF: InkCanvas + Frame - c#

I need to draw over the html page. Page displayed in a Frame element.
The problem is that InkCanvas does not work with Frame.
I tried to insert TextBlock instead of Frame - painting works.
Does not work:
<Frame Grid.Row="1" Source="http://google.com/"></Frame>
<InkCanvas Grid.Row="1" x:Name="inkCanvas" Background="Transparent"></InkCanvas>
Work:
<TextBlock Grid.Row="1" Margin="10" Text="Some text"></TextBlock>
<InkCanvas Grid.Row="1" x:Name="inkCanvas" Background="Transparent"></InkCanvas>

When the Frame control navigates to HTML content, the Frame control internally instantiates the native WebBrowser ActiveX control. This involves HWND interop. As a result of that the "airspace proplem" comes into play. It basically means that no WPF content can overlap that AcitveX HWND. You can partly work around this propblem by wrapping the overlay into another HWND (e.g. using Winfows Forms and ElementHost). But this solution will not allow you to have transparency in the overlay.
Another trick you could try is to use the WindowsFormsHost to host the Windows Forms Browser Control instead of using a Frame.
Last but not least you could use the Chromium WPF Webbrowser Control instead of the Frame control if you can afford it. It is based on the Awesomium library. Which unfortunately is only free for non commercial use. This is the only solution that allows you to use all the advanced WPF goodies like transformation (rotation, skew etc.), bitmapeffects or transparency etc. Width the other two solutions you are bound to a fixed opaque rectangle.

Related

C# - How can I add background blur to an element in WPF? [duplicate]

Ultimately, what I want to achieve is a replication to some extend, of an Aero glass functionality of a WPF content control.
If I apply the BlurEffect to a StackPanel that contains a TextBlock, I will have the TextBlock's text blurred.
Consider an examples:
No blur
and with <BlurEffect Radius="5" KernelType="Gaussian"/>
But is there a WPF way to blur the background behind the panel, and not it's contents?
The background of the StackPanel is a desktop, and the window that hosts it is set to AllowTransparency="True" to allow the custom-shaped look.
no, it is not possible. The Effect is applied to the element and all its children but you can easily place the TextBlock outside the container, rather than inside it.
Normally you would use a grid like so:
<Grid>
<Border>
<Border.Effect>
<BlurEffect Radius="5" KernelType="Gaussian"/>
</Border.Effect/>
</Border>
<TextBlock .../>
</Grid>
In your example that will make no difference though. What, exactly, are you trying to blur?
What the background of the StackPanel? an ImageBrush? If so why cant you apply BlurEffect to that?
If that is not possible then try this..
1] Use an image and draw it completely over Grid as I see you dont want a TileEffect. Add BlurEffect to this Image. Make sure you fill image the uniformly.
2] Then add StackPanel with transparent background as next child in the Grid i.e. dont reverse the order of image and stackpanel.
3] Then add TextBlock in StackPanel.
OR
If you insist on using a Brush to be set as the backgrounnd of the panel then use VisualBrush that draws a blurred image as background of the stackpanel, instead of ImageBrush.
Let me know if any of these tips help.
You can use the SetWindowCompositionAttribute on a Systems.Window, but you are then forced to set the WindowStyle to "None" and implement your own native Window funtionality and handles. Also inheriting from a custom control is quite complicated. Long story short, there's BlurryControls.
You can find it via NuGet by browsing for "BlurryControls" or check out the code yourself on GitHub. Eitherway, I hope this is helpful. It uses .NET 4.5.2 and only works for Windows10, since there is no solution to this problem on Windows8, and in earlier versions (Windows7 and Vista) you can achieve this by accessing DwmEnableBlurBehindWindow.
On GitHub you will also find a sample application called BlurryWindowInvoker.
You could apply this to a Grid.
<Grid.Background>
<VisualBrush>
<VisualBrush.Visual>
<Image Source="RESOURCES/BACKGROUNDS/BACKGROUND_01.jpg">
<Image.BitmapEffect>
<BlurBitmapEffect KernelType="Gaussian" Radius="20" />
</Image.BitmapEffect>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Grid.Background>

Automatic height for WebBrowser Windows Phone 8

I'm trying to render some html content with a WebBrowser xaml control. The html content varies in length. The control is placed within a grid with single row at the moment. I would like to place other controls (StackPanels) before and after the web browser and to get vertical scrolling across the entire layout.
Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<phone:WebBrowser
Grid.Row="0"
x:Name="webBrowser1"
Background="Black"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsScriptEnabled="False"
Visibility="Visible">
</phone:WebBrowser>
<ProgressBar Visibility="Visible" x:Name="LoadingProgress" Indeterminate="True"></ProgressBar>
</Grid>
However I can only scroll the current viewport, being forced to apply a fixed height to the webbrowser.
The theoretical structure I'm aiming to is:
scrollviewer
StackPanel
WebBrowser (probably within another stackPanel)
StackPanel
...
Stackanel
and would like to scroll the scrollViewer, not the webbrowser, so the browser would automatically resize based on the content loaded. Any suggestions?
I found a good blog post on MSDN that addresses this issue: http://blogs.msdn.com/b/mikeormond/archive/2010/12/16/displaying-html-content-in-windows-phone-7.aspx
The blogger was initially trying to accomplish the same thing as you, placing a browser into a scrollviewer, etc. But found that it didn't work well for larger html pages, they went with a different solution to disable scrolling and zooming in the browser control. Hope this can help:
This worked fine until dealing with longer bodies of content; when the
height of the WebBrowser control was set to more than 1800px the the
application would crash. As it turned out, there’s a much easier way
to achieve the same effect.
Instead of disabling hit testing on the WebBrowser control (and then
embedding it in a ScrollViewer to re-enabled the scrolling
experience), it’s possible to set meta tags in the HTML to declare
that the user should not be able to zoom the content.
or
These meta tags set the width of the viewport to 320px (to avoid
horizontal scrolling) and specify that the user should not be able to
scale the viewport. Add these meta tags to the HTML injected into the
WebBrowser control and the desired behaviour is achieved.
To get the height from the webview, you can use
window.external.notify("rendered_height=document.getElementById('yourId').offsetHeight")
in body.onload and body.onresize
Here is a complete example of an AdaptativeWebview that handle scroll and resize

stretch canvas on maximize

(Can't add pictures so I'll try and explain it) So my program basically consists of two parts: a bitmap image that is scanned and shown in the main window (on a canvas), and a canvas derived class I made that basically takes data (b&w values ranging from 0-255) from the image and represents it in a histogram format (a bargraph basically) and it overlays the bitmap image (its transparent so you can still see the image).
Alright so I got my program working, the only problem is my canvas derived class wont stretch until I "refresh" the screen. The children of the class (being windows shapes rectangles) wont stretch with the window.
It looks fine up to this point
but then I maximize it...
The rectangles then just stay exactly where they're at. It isn't until I click the "display histogram" button that it will disappear and then after clicking it again, I get...
...Exactly what I want, the histogram is in the right place on the screen. So here's my question, how can I get the histogram to stretch with the main window? instead of having to refresh it every time?
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="Black" BorderThickness="5" x:Name="testview">
<local:DrawingCanvas x:Name="pbHistogram" IsHitTestVisible="False"
Width="Auto"
Background="Transparent"
Height ="{Binding Path=ActualHeight, ElementName=testview}"/>
</Border>
I know this is not really an answer, but I think the problem is the canvas class itself. It has no automatic layouting or resizing of its child elements. Link to msdn: http://msdn.microsoft.com/en-us/library/ms609101(v=vs.100).aspx
What you could try is to hook up to your main window's resize event and call the same function that the buttonpress calls.
Maybe the quickest, easiest way to do this would be to put your canvas in a Viewbox.

Grid On Top Of A WINRT Media Element Causes Video To Be Blank

I have a MediaElement full screen on a page. On top of this I have a grid that contains controls (Play,Pause etc..) and general info about the video. These controls are hidden after a few seconds of no user interaction.
If any part of the controls overlap the video being played then the entire Video is blanked out and only reappears when the controls grid is collapsed. Is it not possible to have a control of any kind over the top of a media element?
I notice that the "Video" App that comes as part of Windows8 RTM has this kind of effect over the top of a video that is playing.
UPDATE:
I've found the problem but not a solution. I'm trying to have a "Global" mediaelement so I can view it on different pages (Fullscreen, preview etc). I found this answer
http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/241ba3b4-3e2a-4f9b-a704-87c7b1be7988
And followed Jim Man's suggestion to create a MediaElement on the root frame and then pull that item when needed. The issue happens as soon as I say CurrentPageMediaElement = RootFrameMediaElement
I presume it's changing the z order of the media element to that of the "Global" media element in the root frame? I'm not sure why it shows video when ControlsGrid is collapsed as the root grid is still there. If I change the root grid to have an opacity less than 1 I see the media element all the time as in the code below.
If someone has a better way to share a Global Media Element around then that would also work.
//Here I Can't See The MediaElement
<Grid Style="{StaticResource LayoutRootStyle}" Background="Black">
<MediaElement x:Name="MainMediaElement" />
<Grid x:Name="ControlsGrid" Opacity="0.7" />
</Grid>
//Here I Can See The Media Element
<Grid Style="{StaticResource LayoutRootStyle}" Background="Black" Opacity="0.7">
<MediaElement x:Name="MainMediaElement" />
<Grid x:Name="ControlsGrid" Opacity="0.7">
</Grid>

WebBrowser as Canvas Background

I like to add a WebBrowser control as a Canvas background in WPF using C#. How do I do this? I have the following code at the moment. But does not work.
<Canvas
Name="canvas"
Grid.ColumnSpan="4"
Grid.Row="1"
MouseDown="Canvas_MouseDown"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp"
Margin="0,0,0,16"
Grid.RowSpan="3">
<Canvas.Background>
<VisualBrush>
<VisualBrush.Visual>
<WebBrowser
x:Name="wbMain"
Height="246"
Width="592" />
</VisualBrush.Visual>
</VisualBrush>
</Canvas.Background>
</Canvas>
You cannot do this. The web browser control is an Internet Explorer ActiveX wrapper with the resulting airspace issues.
However, you can draw on top of it using the <Popup> control or if you don't mind losing the interactivity, try generating an image of the web page and use it as the Canvas background.
If you are thinking about using the WPF Chrome wrapper by Chris Cavanagh, bear in mind:
It does not yet support COM-Visible (so no window.external javascript methods back to your C# code)
It has a dependency on Awesomium which is only free for non-commercial use.
It will add over 10MB to your code size as it needs to embed Chromium
The WebBrowser control isn't a standard WPF control as far as I'm aware. It's basically an embedded window with an IE control in it. I'm fairly certain you can't use it in this manner.
It's an embedded IE window, so you can't use it that way.
You CAN, however, use the chrome one that way: http://chriscavanagh.wordpress.com/2009/08/25/a-real-wpf-webbrowser/
You can also map it to a surface, animate it etc.

Categories