WPF Hyperlinked Image with rounded corners - wpf

Question: How to create hyperlinked Image with rounded corners in WPF/XAML?
So far, existing code for hyperlinked image (no rounded corners) is working (see below):
Hyperlinked Image (WPF XAML)
<TextBlock Name="txtbFooterRight" >
<Hyperlink Name="lnkImg" TextDecorations="None"
NavigateUri="http://webinfocentral.com"
ToolTip="Navigate to web page">
<Image Name="someName" Source="some url" />
</Hyperlink>
</TextBlock>
Hyperlinked image code behind (C#):
lnkImg.RequestNavigate += (s, e) => {Process.Start(e.Uri.ToString()); };
Image control with rounded corners (no hyperlinks) is implemented as:
Image with rounded corners (WPF/XAML):
<Border Name="brdRounded" BorderThickness="0" CornerRadius="10">
<Border.Background >
<ImageBrush>
<ImageBrush.ImageSource>
<BitmapImage UriSource="some Uri to .jpg" />
</ImageBrush.ImageSource>
</ImageBrush>
</Border.Background>
</Border>
I need to "round the corners" of the hyperlinked image (WPF/XAML), probably combining aforementioned techniques. Thanks and regards,
Note: I've accepted the answer posted by user #lisp with just minor fix: Border background color should match the surrounding color in order to avoid slight "color leakage". Kudos to the author!
On a separate note: it was an eye-opening experience on how relatively difficult it is to achieve such simple effect while using WPF/XAML comparing to HTML5/CSS3 (see for, example, essentially the same effect on rounded corner image at: http://infosoft.biz/SlideShowCSS.aspx). It seems like WPF folks at Microsoft should take a note...

Border is used for rounded corners. But in your case if you simply put TextBlock inside of Border, you wouldn't get the desired effect.
Here Corners are made transparent using a border. Grid is used so that Border stretches exactly to the size of TextBlock.
<Grid>
<Border Name="CornersMask" Background="White" CornerRadius="20"/>
<TextBlock>
<TextBlock.OpacityMask>
<VisualBrush Visual="{Binding ElementName=CornersMask}"/>
</TextBlock.OpacityMask>
<Hyperlink ...>
<Image Name="someName" Source="some url" />
</Hyperlink>
</TextBlock>
</Grid>
TextBlock is displayed on top of Border, and because of that and antialiasing you may experience slight whiteness on the rounded edges. Either change the Border background to the surrounding background color, or enclose Border in another container that will autostretch it e.g. Border of Grid, and set it's Visibility to Hidden.
<Border Visibility="Hidden">
<Border Name="CornersMask" Background="White" CornerRadius="20"/>
</Border>
This also solves the problem when the surrounding background is not a SolidColorBrush

Related

Annoying 1-pixel band between Border and Label?

I am trying to get rid of an annoying 1-pxel band of un-drawn background between a border and a label control.
Specifically, my XAML looks like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox Margin="0,0,5,3" HorizontalAlignment="Right" Grid.Column="1">
<Border BorderThickness="2" CornerRadius="2" BorderBrush="#BF272727" Background="#BF272727">
<Label Padding="-3" Content="Testing" Foreground="Red"/>
</Border>
</Viewbox>
</Grid>
And my output looks like this:
Notice that the border brush and the label background both have a semi-transparent color. I've fiddled with other properties of both the border and the label and haven't found anything that will cause this single pixel between the border and label to get filled with the background color. I imagine it is something simple, but I haven't stumbled on it yet. I've tried setting the Background property on the label instead of the border, but with no change in results.
WPF's device-agnostic rendering works very well most of the time, but yes…occasionally you'll see artifacts like this, due to adjacent elements being anti-aliased, causing pixels that nominally should be exactly the same color having some variation.
In your case, you should omit the border thickness and brush altogether. To do that and still have the same visual appearance, you need to include padding, so that the border element is expanded out to the size it would have had, had there been a non-zero thickness border. And of course, without the border included, the corner radius needs to be adjusted up (by half the original border thickness).
The following produces the result you seem to want:
<Border Background="#BF272727" CornerRadius="3" Padding="2">
<Label Padding="-3" Content="Testing" Foreground="Red"/>
</Border>
Turn on aliased edges in either your Border control or any of its parents:
RenderOptions.EdgeMode="Aliased"

How do I properly draw and scale a Canvas as a WPF background to a control?

I have a StackPanel that needs to contain drawn background. Specifically, my StackPanel needs to have the ability to grow and the rectangle must grow with the StackPanel, but must remain pseudo-anchored to each side at a fixed position.
I've attempted to use the Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom attached properties, but so far they've not worked. Furthermore, this does seem to work when drawing within Canvas objects, just not when they are embedded within a VisualBrush set as a background. How can I accomplish drawing this resizable, rectangular background within my StackPanel?
Below is the state of my current code. I've tried various approaches but none seem to work.
My Code:
<StackPanel DockPanel.Dock="Right" Orientation="Vertical" VerticalAlignment="Center">
<StackPanel.Background>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<Canvas Background="Magenta" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Rectangle Fill="#FFDDECF7" Canvas.Left="20" Canvas.Top="20" Canvas.Bottom="20" Canvas.Right="0"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</StackPanel.Background>
...
</StackPanel>
This currently doesn't render anything. I set the canvas background to magenta just so I could see if it were drawing, and I'm not even seeing that. Other attempts have drawn the canvase, however, the blue rectangle is always stretched to fill the window, regardless of attached canvas property settings.
Sample:
The image below is a sample of what I want. Again, I'm using an ugly Magenta color to show the offset of the internal, blue rectangle. As the StackPanel grows or shrinks, the rectangle needs to be affixed to the top, left, right and bottom.
My suggestion is to place the stackpanel inside a grid:
<Grid DockPanel.Dock="Right" VerticalAlignment="Center" Background="Magenta">
<Rectangle Margin="20" Fill="#FFDDECF7"/>
<StackPanel Orientation="Vertical">
no background...
</StackPanel>
</Grid>
Wrap Canvas into a ViewBox, then work on a ViewBox. As far as I know Canvas doesn't support scalling too well.

Change the MahApps Metro Split ButtoniIcon size

I'm trying to use the split button control described here:
http://mahapps.com/controls/split_dropdownbutton.html
I'm also using the MahApps resource pack with the icons collection. I want to re-size the control to a height of 40px, but the icon stays to its native height of 76px, resulting in it getting cropped, as shown below.
Any ideas how to get around this?
The SplitButton from MahApps.Metro has a property called IconTemplate. To this property you can assign a DataTemplate and there you can add almost arbitrary content, which will be put in place of the icon itself.
For example you could put a Rectangle control with fixed Height and/or Width. And setting its OpacityMask to your desired icon, will show the icon in smaller size.
In XAML it looks like this:
<controls:SplitButton Orientation="Horizontal">
<controls:SplitButton.IconTemplate>
<DataTemplate>
<Rectangle VerticalAlignment="Center" Height="35" Width="35" Fill="{DynamicResource BlackColorBrush}">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_globe}" />
</Rectangle.OpacityMask>
</Rectangle>
</DataTemplate>
</controls:SplitButton.IconTemplate></controls:SplitButton>
controls is the alias for the MahApps.Metro-namespace and may differ in your project.

Show different background for transparent buttons

We have a design requirement such that transparent buttons (with white text) are overlayed on a scenic background image. But here's the hard part, and my dilemma...
While the background image should be clear and visible OUTSIDE the image borders, the area INSIDE the buttons (the overlayed area) should be a blurred area of the background image. The idea is to make it easier for users to see the white text inside the button.
I'm a novice in XAML and even more unfamiliar with how to perform such complex styling. I have a starting point for the overlay layout, but this code does not attempt to solve the problem. It's simply a button over an image.
Any ideas or help on how to blur the area under the image?
<Grid Margin="0,0,0,12" Visibility="{Binding SignedIn, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=False}">
<Image Source="backgroundImage.png" Height="136" Stretch="Fill" HorizontalAlignment="Stretch" />
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button x:Uid="SignInBtn" Content="SIGN IN" Style="{StaticResource TransparentButtonStyle}" HorizontalAlignment="Center" Command="{Binding SignInCommand}" IsEnabled="{Binding LoadingResults, Converter={StaticResource NotBoolConverter}}" />
</StackPanel>
</Grid>
There's no straightforward way to do this in a Windows Phone 8.1 app. Image effects are not supported in either Windows Phone Silverlight or in Windows.UI.Xaml.
The typical and easy solution would be to dim (rather than blur) the image by setting the Button's background to a partially transparent brush.
<Button Background="#7F000000" </Button>
If you want to put a bit more work into it you can crop the area of the bitmap behind the button, run your blur transform on it (take a look at the Lumia Imaging SDK) and then set the new, blurred image to the button.
Consider using Effects.
In addition, see if you can leverage this example:
<Style TargetType="Window">
<Setter Property="Background">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<Image Source="Images\myImage.png">
<Image.Effect>
<BlurEffect Radius="20"/>
</Image.Effect>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
...

Unintended opacity mask change by child control

I want to make a canvas which has rounded border. I think I can implement it by OpacityMask. but it's a hard to me.
<Canvas Background="Red" ClipToBounds="True" x:Name="can">
<Canvas.OpacityMask>
<!--czc.png is opacity mask source which represents a rounded rectangle.-->
<ImageBrush ImageSource="/WpfApplication3;component/Images/czc.png"/>
</Canvas.OpacityMask>
<Image Source="/WpfApplication3;component/Images/1lvhuman.jpg" Margin="-129,56,192,46" Canvas.Left="193" Canvas.Top="25" Height="186" Width="153" />
</Canvas>
figure 1. is the Image in canvas that don't hanged in the Canvas's border. In the contrary, the Image of figure 2 hanged in left border of the Canvas. when hanged in there, OpacityMask was changed.
Why are you using Canvas? Can you just use a Border with a BorderRadius instead?

Resources