OpacityMask not working with WPF WindowsFormsHost? - wpf

I'm trying to put a rounded border on a control which is hosted through a WindowsFormHost object. It seems like no matter what I set for OpacityMask, it has no effect on the rendering. Is there something I've missed?
Here is the XAML code I am using. The child control is added at run-time. I've tried various combinations of masks, none of which worked for me. Any help would be appreciated. Thanks!
<WindowsFormsHost Background="#FF2BBA62" Height="414" Width="516" Margin="176.5,223,309.5,92" Name="vcxHost1" UseLayoutRounding="False" ClipToBounds="True" >
<WindowsFormsHost.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<Rectangle Height="10" Width="100" Name="border1" />
</VisualBrush.Visual>
</VisualBrush>
</WindowsFormsHost.OpacityMask>
</WindowsFormsHost>

I suspect it doesn't work for the same reason that the z-indexing doesn't work. From the linked doc: "A hosted Windows Forms control is drawn in a separate HWND, so it is always drawn on top of WPF elements."
See the paragraph on Layout Limitations ...
http://msdn.microsoft.com/en-us/library/ms744952.aspx
This may also be helpful ... http://msdn.microsoft.com/en-us/library/ms742522.aspx

Related

WPF OpacityMask weird behavior

I think I might have found a bug in WPF, or maybe I just don't fully understand how OpacityMasks work. As you can see on the first image, I have a diamond shaped path and a red circle. My goal is to make everything outside the diamond invisible. It works when the circle is inside the diamond shape, but whenever I move it to one of the corners, or outside the path, the OpacityMask seems to get stretched or distorted as you can see on the second image. My question is how can I make the OpacityMask work regardless of where the circle (or any other child element) is.
First image
Second Image
And this is my XAML code
<Grid Name="rootGrid">
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=path}"/>
</Grid.OpacityMask>
<Path Name="path"
Stretch="Fill"
Fill="Cyan"
StrokeThickness="1"
Stroke="GreenYellow"
Data="M 0,-1 1,0 0,1 -1,0 0,-1"/>
<Ellipse Fill="Red"
Margin="20,-17,22,61"/>
</Grid>
</Grid>
Sorry for posting the images with links, but I don't have enough reputation to directly embed images.
Any help is appreciated!
Clemens solved my issue
Set ViewportUnits="Absolute" on the VisualBrush, and then set its Viewport property to an appropriate rectangle, e.g. Viewport="0,0,100,100"

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.

Having difficulty using Z-Index in 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.

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!

Reuse of StaticResource in Silverlight 2.0

I am currently testing with Silverlight 2.0 Beta 2, and my goal is to define a resource element once and then reuse it many times in my rendering. This simple example defines a rectangle (myRect) as a resource and then I attempt to reuse it twice -- which fails with the error:
Attribute {StaticResource myRect} value is out of range. [Line: 9 Position: 83]
BTW, this sample works fine in WPF.
<UserControl x:Class="ReuseResourceTest.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="200">
<Canvas x:Name="LayoutRoot" Background="Yellow">
<Canvas.Resources>
<RectangleGeometry x:Key="myRect" Rect="25,50,25,50" />
</Canvas.Resources>
<Path Stroke="Black" StrokeThickness="10" Data="{StaticResource myRect}" />
<Path Stroke="White" StrokeThickness="4" Data="{StaticResource myRect}" />
</Canvas>
</UserControl>
Any thoughts on what's up here.
Thanks,
-- Ed
I have also encountered the same problem when trying to reuse components defined as static resources. The workaround I have found is not declaring the controls as resources, but defining styles setting all the properties you need, and instantiating a new control with that style every time you need.
EDIT: The out of range exception you are getting happens when you assign a control to a container that already is inside another container. It also happens in many other scenarios (such as applying a style to an object that already has one), but I believe this is your case.

Resources