Having difficulty using Z-Index in WPF - wpf

I've followed some examples trying to layer a rectangle over the WebBrowser object:
Here is the MSDN example link. (I got it to work)
Layers issue using Z-Index
Here is the code I'm trying to get to work:
<Grid>
<Canvas Margin="2,4,0,-450" >
<Rectangle Height="452" Canvas.ZIndex="1000" Name="rectangle1" Stroke="Black" Width="524" Opacity=".5" Fill="#8CBABABA" Canvas.Top="-7" Canvas.Left="-3" />
<WebBrowser Name="mapBrowser" Canvas.ZIndex="999" Margin="5,5,5,5" Height="452" Width="516" Canvas.Top="-11" />
</Canvas>
</Grid>
I'm trying to make the WebBrowser appear grayed out by making the rectangle appear over top of it. I'll also disable it.
Can anybody point to what I'm doing wrong?

I solved this issue by creating a .png image which I placed in the same space as the webbrowser. It looks like a grayed-out version of what first appears in the webbrowser. Then I conditionally hid the webbrowser which makes the image visible. This is the only way I've found to make it work using .Net 4.0.

Related

Avalon Edit Cut\Copy\Paste Commands from MahApps.Metro Button

I'm implementing a custom simplified editor in WPF using AvalonEdit and MahApps.Metro. I am stuck trying to get the cut/copy/paste/undo/redo commands working using MahApps.Metro icon/circle buttons instead of a toolbar.
The AvalonEdit sample uses a toolbar, and if I add a similar toolbar to my current application, it works as expected.
I want to call the Cut/Copy/Paste from a series of icon buttons on my app layout instead of inside a toolbar. My MahApps.Metro buttons are as follows. I've tried it with and without the Command Target set. In both cases nothing happens when I click them.
<Button Width="48"
Height="48"
Margin="24,0,0,0"
Style="{DynamicResource MahApps.Metro.Styles.MetroCircleButtonStyle}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="Undo"
CommandTarget="{Binding ElementName=xmlTextEditor.TextArea}">
<iconPacks:PackIconMaterial Kind="UndoVariant" />
</Button>
I'm relatively new to WPF so I might be missing something really basic here. Any help is appreciated.

Image with Multiple Clickable Areas

I have an image that I want various parts of to be clickable. I found a comment in the question below mentioning this was possible with Expression Designer. I haven't been able to find a guide on how to do this. I understand that I have to export the image from Designer to Visual Studio. Is there a better way of achieving this or how do I go about creating the xaml for these clickable sections?
best way for clickable image map in wpf
Personally I'd use the second answer to that question i.e. do something like this:
<Canvas>
<Image Source="background.png"/>
<Ellipse Canvas.Left="82" Canvas.Top="88" Width="442" Height="216" Fill="Transparent" Cursor="Hand" MouseDown="Ellipse_MouseDown_1"/>
<Ellipse Canvas.Left="305" Canvas.Top="309" Width="100" Height="50" Fill="Transparent" Cursor="Hand" MouseDown="Ellipse_MouseDown_2"/>
</Canvas>
Then you can drag and resize the shapes in DevStudio using it's XAML editor's design mode.

WP7 Silverlight -- tapping image in a stackpanel scrollview to show that same picture in another grid

I am probably the absolute worst "coder" trying to create a Windows Phone 7 app, but I am in dire need of help, and some of you may even consider it to be laughably easy (which it probably is).
My problem: How on earth do I code the tapping of a picture from one grid to display as a bigger image on another grid?
And I'll elaborate:
I have an app page (in landscape mode only), with two grids splitting the screen.
The first grid (smallgrid) contains a Scrollviewer (small) with a Stackpanel (smallimages) of images reduced to 1/10 of their size within it, essentially showing thumbnails of images.
The second grid (contentgrid) is designed where once you tap on a thumbnail image from smallgrid that image will be shown in contentgrid
By default, balloon0 is displayed in the contentgrid and will change when a person taps on one of the smaller images.
I'll try to provide some mock code for this:
<grid x:name="smallgrid">
<scrollviewer x:name="small">
<stackpanel x:name="smallimages">
<image="balloon0.jpg"><image>
<image="balloon1.jpg"><image>
<image="balloon2.jpg"><image>
<image="balloon3.jpg"><image>
</stackpanel>
</scrollviewer>
</grid>
<grid x:name="contentgrid">
<image source="balloon0.jpg"><image>
</grid>
The code behind is where I need help. I am thinking I either use a button that once clicked, that image then replaces the image in contentgrid but I have no idea how to do that.
Or I can use a gesturelistener that when an image is tapped, it will replace the image in contentgrid... but I also don't know how to do that.
Any insight is helpful. Thank you for any help, as I am not a C# coder, let alone know the language or WP7 silverlight too well.
Be sure to add the Silverlight Toolkit assembly reference to your phoneapplicationpage element (and as a reference to the project):
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
You can use the GestureListener from the Silverlight Toolkit in your XAML like this (also be sure to add the name property to your large image):
<grid x:name="smallgrid">
<scrollviewer x:name="small">
<stackpanel x:name="smallimages">
<image="balloon0.jpg">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="smallImage_Tap" />
</toolkit:GestureService.GestureListener>
<image>
<image="balloon1.jpg">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="smallImage_Tap" />
</toolkit:GestureService.GestureListener>
<image>
<image="balloon2.jpg">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="smallImage_Tap" />
</toolkit:GestureService.GestureListener>
<image>
<image="balloon3.jpg">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="smallImage_Tap" />
</toolkit:GestureService.GestureListener>
<image>
</stackpanel>
</scrollviewer>
</grid>
<grid x:name="contentgrid">
<image x:Name="BigImage" source="balloon0.jpg"><image>
</grid>
Then in your code-behind you can handle the event like this:
private void smallImage_Tap(object sender, GestureEventArgs e)
{
BigImage.Source = (sender as Image).Source;
}
If you look into the toolkit source code, then it appears that GestureListener.Tap event is generated whenever XNA TouchPanel detects Tap gesture. Intuitively I would expect that this happens whenever MouseLeftButtonUp event is generated. Ok, not always, but in the described type of interaction it is basically "always".
Hence I feel both these levels (XNA and Toolkit classes) as unnecessary overhead - at least for something as simple as the tap event. (Other negative consequences: App size increases as you have to include the toolkit, slower launching as more assemblies have to be loaded.)
Having said that, I would start by simply listening to MouseLeftButtonUp event as for example
<Image Source="123.jpg" MouseLeftButtonUp="smallImage_Tap" ImageOpened="..." ImageFailed="..."/>
I included also ImageOpened/Failed events. You can optionally use them to fine tune your app. They could solve problems such as too frequent tap events or image load failures.

How to center text around point using xaml

I would like to be able to place the word "hello" centered on a specific point. I need to do this completely in XAML without extra code. Best I can tell, all the text alignment properties/styles in XAML act on text within some bounding canvas or other element.
Since I don't know the length of the text I want to center, I can't center it using my own code.
The reason I need to solve the problem entirely in XAML is that I'm not using WPF to create the XAML, I'm writing it directly to an XML DOM. It will then be loaded into a Silverlight or WPF control for display.
In most graphic languages, including SVG, which is where my code originated, text can be aligned against a "stationary point" without a bounding box.
Any suggestions appreciated
(Yes, I know this question is old.)
The effectiveness of this solution may vary with the version of Silverlight or the .NET Framework you are using, and I haven't tried it with Silverlight for Windows Phone 7. I wrote a version for stand-alone WPF applications, and I wrote another version that also works in Silverlight.
First, the version that works in Silverlight and WPF. Please note that you will need to refactor the code a little bit if you aren't using a Canvas to provide an absolute position for the center of your TextBlock. For example, you may be using a TranslateTransform to position your text.
<Canvas>
<Canvas.Resources>
<ScaleTransform x:Key="transform" ScaleX="-1" ScaleY="-1" />
</Canvas.Resources>
<Grid RenderTransform="{StaticResource transform}" RenderTransformOrigin="-.25 -.25">
<TextBlock RenderTransform="{StaticResource transform}">
Hello!
</TextBlock>
</Grid>
</Canvas>
Second, the version that works only in WPF. It doesn't work in Silverlight because it depends on the presence of the Canvas.Right and Canvas.Bottom attached properties. UniformGrid isn't in Silverlight either, but that code could have been replaced by a regular Grid with 2 star-length rows and columns.
<Canvas>
<UniformGrid Rows="2" Columns="2"
DataContext="{Binding ElementName=textBox1}"
Width="{Binding Path=ActualWidth}"
Height="{Binding Path=ActualHeight}">
<Canvas>
<TextBlock Name="textBox1" Canvas.Right="0" Canvas.Bottom="0">
Hello!
</TextBlock>
</Canvas>
</UniformGrid>
</Canvas>
By the way, there may be more efficient ways to solve this problem available. I am making no guarantees!

WPF 3.5 WebBrowser control and ZIndex

I'm trying to figure out why the control does not honor ZIndex.
Example 1 - which works fine
<Canvas>
<Rectangle Canvas.ZIndex="1" Height="400" Width="600" Fill="Yellow"/>
<Rectangle Canvas.ZIndex="2" Height="100" Width="100" Fill="Red"/>
</Canvas>
Example 2 - which does not work
<Canvas>
<WebBrowser Canvas.ZIndex="1" Height="400" Width="600" Source="http://www.stackoverflow.com"/>
<Rectangle Canvas.ZIndex="2" Height="100" Width="100" Fill="Red"/>
</Canvas>
Thanks,
-- Ed
Unfortunately this is because the WebBrowser control is a wrapper around the Internet Explorer COM control. This means that it gets its own HWND and does not allow WPF to draw anything over it. It has the same restrictions as hosting any other Win32 or WinForms control in WPF.
MSDN has more information about WPF/Win32 interop.
You are running into a common WPF pitfall, most commonly called the "The Airspace Problem". A possible solution is to NOT use the WebBrowser control, and instead go for something a little crazier - namely an embedded WebKit browser rendering directly to WPF. There are two packages that do this; Awesomonium (commercial) and Berkelium (open-source). There's a .NET wrapper for both of these.
You could SetWindowRgn to fake the overlapping area by hiding it as shown here:
flounder.com
msdn
I solved a similar issue where I was hosting a 3rd party WinForms control in my WPF application. I created a WPF control that renders the WinForms control in memory and then paints it to a bitmap. Then I use DrawImage in the OnRender method to draw the rendered content. Finally I routed mouse events from my control to the hosted control. In the case of a web browser you would also have to route keyboard events.
My case was fairly easy - a chart with some simple mouse interaction. A web browser control may have other issues that I didn't take into consideration. Anyway I hope that helps.
I hit this issue as well. In my case I was dragging images from one panel into the WebBrowser, but of course as soon as my image moved into the browser it was hidden.
Currently working on the following solution:
When the Image drag starts, create a Bitmap of the WebBrowser using "RenderTargetBitmap"
Add your Bitmap to the canvas, using the same width/location as the webbrowser
webControl.Visibility = Visibility.Hidden.
When the drag is released, remove your bitmap and set webControl.Visibility = Visible.
This solution is very specific to my situation, but maybe it will give you some ideas.
I managed to solve this by using this structure, check out the properties configuration in each element:
<Canvas ClipToBounds="False">
<Popup AllowsTransparency="True" ClipToBounds="False" IsOpen="True">
<Expander>
<Grid x:Name="YourContent"/>
</Expander>
<Popup>
</Canvas>
You just have to manage the Expander to show or hide your content, I'm using it for a menu bar, I think that the expander is optional depending on the case.
Check out this picture with the result, you can even show your controls on top of the WebBrowser and even outside the main window:

Resources