WPF : Rounded-Corners Images - wpf

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Black">
<!-- Rounded yellow border -->
<Border BorderThickness="3" BorderBrush="Yellow" CornerRadius="10" Padding="2"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<!-- Rounded mask (stretches to fill Grid) -->
<Border Name="mask" Background="White" CornerRadius="7"/>
<!-- Main content container -->
<StackPanel>
<!-- Use a VisualBrush of 'mask' as the opacity mask -->
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
<!-- Any content -->
<Image Source="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg"/>
<Rectangle Height="50" Fill="Red"/>
<Rectangle Height="50" Fill="White"/>
<Rectangle Height="50" Fill="Blue"/>
</StackPanel>
</Grid>
</Border>
</Page>
This XAML is from WPF – Easy rounded corners for anything but it doesn't work form me =(
<Border Canvas.Left="55"
Canvas.Top="30"
Width="100"
Height="Auto"
Margin="12,12,8,0"
VerticalAlignment="Top"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="18">
<Border.Effect>
<DropShadowEffect BlurRadius="5"
Opacity=".5"
ShadowDepth="3" />
</Border.Effect>
<Border Name="ReceiverColor"
BorderBrush="#FF96B2E4"
BorderThickness="6"
CornerRadius="15">
<Border Name="Mask"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="13">
<StackPanel>
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}" />
</StackPanel.OpacityMask>
<Image Name="Receiver" />
</StackPanel>
</Border>
</Border>
</Border>
--- EDIT ---
I make borders sizes to auto and change source of image to an image from a link
when window loaded border size becomes as image size but image not shown !!!

You can define a <Border/> element and set its <Border.Background/>
property to an <ImageBrush/> , set the Borders CornerRadius property and you
are all set!
<Border CornerRadius="8,0,8,0">
<Border.Background>
<ImageBrush Stretch="Fill" ImageSource="ImageSource"/>
</Border.Background>
</Border>

You forgot the Grid that makes the mask and the image siblings and nested the image in the mask. and you forgot to set the background of the mask.
This works:
<Grid>
<Border Canvas.Left="55"
Canvas.Top="30"
Width="100"
Height="Auto"
Margin="12,12,8,0"
VerticalAlignment="Top"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="18">
<Border.Effect>
<DropShadowEffect BlurRadius="5"
Opacity=".5"
ShadowDepth="3" />
</Border.Effect>
<Border Name="ReceiverColor"
BorderBrush="#FF96B2E4"
BorderThickness="6"
CornerRadius="15">
<Grid>
<Border Name="Mask"
Background="White"
BorderBrush="#FF3B5998"
BorderThickness=".5"
CornerRadius="13">
</Border>
<StackPanel>
<Image Name="Receiver"
Source="/Images/test.jpg" />
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}" />
</StackPanel.OpacityMask>
</StackPanel>
</Grid>
</Border>
</Border>
</Grid>

in wpf this one works for me
<Ellipse Width="50" Height="50">
<Ellipse.Fill>
<ImageBrush ImageSource="http://chriscavanagh.files.wordpress.com/2006/12/chriss-blog-banner.jpg" />
</Ellipse.Fill>
</Ellipse>

None of the above answers worked for me completely. I was trying to implement rounded corners on image which could be resized and has properties Stretch="UniformToFill" VerticalAlignment="Center" and HorizontalAlignment="Center".
The center alignments keeps the middle part cropped as opposed to bottom and right side being cropped, when image is resized. Solutions with image brush were working but I was facing problem in keeping the content at center cropped.
The marked answer has a problem with transparent non rectangular images as the "mask" border will end up showing as white background. Following was the imlementation which worked for me:
<Grid>
<WrapPanel Name ="container">
<Image Source="sample_image.png" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="UniformToFill"/>
<WrapPanel.OpacityMask>
<VisualBrush >
<VisualBrush.Visual>
<Border Height="{Binding ElementName=container, Path=ActualHeight}"
Width="{Binding ElementName=container, Path=ActualWidth}"
Background="White" CornerRadius="15" />
</VisualBrush.Visual>
</VisualBrush>
</WrapPanel.OpacityMask>
</WrapPanel>
</Grid>

You can use an ellipse like how Usman Ali has said (I thought this myself and I didn't take it from him)
It's very simple, make an ellipse with the properties you want, then set the fill to an imagebrush with your desired image like this in XAML:
<Ellipse Height="Auto" Width="100">
<Ellipse.Fill>
<ImageBrush ImageSource="YOUR IMAGE SOURCE/LINK HERE"/>
</Ellipse.Fill>
</Ellipse>
In C#, if in any case you want to do in C#:
Ellipse YourEllipseName = new Ellipse
{
Height = 50,
Width = 50,
StrokeThickness = 0,
Fill = new ImageBrush
{
Stretch = Stretch.Uniform,
ImageSource = new BitmapImage(new Uri("YOUR IMAGE SOURCE HERE"))
}
};

<Grid Background="Black">
<Rectangle RadiusX="20" RadiusY="20"
Width="130"
Height="130">
<Rectangle.Fill>
<ImageBrush x:Name="myImage" ImageSource="C:\Path\Desktop\visual-studio-2010-logo.png"/>
</Rectangle.Fill>
</Rectangle>
</Grid>

Related

WPF Border ZIndex not working as expected

I have the following problem: I overlay 2 controls over one another and want a single border to surround them both. I thought I could control the ZIndex of the border over each control and give them a low ZIndex: 2. Then give the controls a higher ZIndex (4 and 5). The following xaml as a UserControl is what I'm referring to:
<Canvas>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2" Canvas.Left="50" Canvas.Top="30">
<Rectangle Width="200" Height="20" Fill="Aqua" Canvas.ZIndex="5"/>
</Border>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2" Canvas.Left="150" Canvas.Top="00">
<Rectangle Width="50" Height="200" Fill="Yellow" Canvas.ZIndex="5"/>
</Border>
</Canvas>
The result looks like:
But I desire is the following image but with the border with red-X removed:
Can anyone recommend a way to do this ? The Border ZIndex method is not working.
Thanks!
ZIndex is not working cause Rectangles are not childs of Canvas. So you can fix it by placing them outside of borders and adjusting its Heights, Widths and Canvas.Left, Canvas.Top properties. So the example looks like this.
<Canvas>
<Border BorderBrush="Black" BorderThickness="4" Canvas.ZIndex="2"
Canvas.Left="46" Canvas.Top="26"
Width="208" Height="28">
</Border>
<Rectangle Width="200" Height="20" Fill="Aqua" Canvas.ZIndex="5"
Canvas.Left="50" Canvas.Top="30" />
<Border BorderBrush="Black" Height="208" Width="58" BorderThickness="4"
Canvas.ZIndex="2" Canvas.Left="146" Canvas.Top="00">
</Border>
<Rectangle Canvas.Left="150" Canvas.Top="4" Width="50" Height="200" Fill="Yellow"
Canvas.ZIndex="5"/>
</Canvas>

WPF MediaElement with rounded corner

In WPF, i wish to create rounded corner for my movie, but the movie actually will overlap the border and i get a normal rectangle box that load my movie. Any idea how to solve this issue?
<Border BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="20,20,20,20">
<Grid>
<MediaElement x:Name="movieLoader" HorizontalAlignment="Left" Height="128" VerticalAlignment="Top" Width="236" Source="../video/empty.mp4"/>
</Grid>
</Border>
Try this:
<Border x:Name="border" BorderThickness="1" BorderBrush="#FF000000" CornerRadius="20" Padding="1"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Border Name="mask" Background="White" CornerRadius="{Binding ElementName=border, Path=CornerRadius}"/>
<Grid>
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</Grid.OpacityMask>
<MediaElement x:Name="movieLoader" HorizontalAlignment="Left" Height="128"
VerticalAlignment="Top" Width="236" Source="../video/empty.mp4"/>
</Grid>
</Grid>
</Border>
Set ClipToBounds to True.
<Border ClipToBounds="True" BorderBrush="#FF000000" BorderThickness="1"
CornerRadius="20">
<Grid>
<MediaElement x:Name="movieLoader" HorizontalAlignment="Left"
Height="128" VerticalAlignment="Top" Width="236"
Source="../video/empty.mp4"/>
</Grid>
</Border>

Draw Image Outside of Layout in WPF

I'm creating a style to customize a RadioButton so that the RadioButton can display a star image behind the Bullet. I have the star being drawn with an ImageBrush as the background of a 20x20 grid that holds the Bullet layout. It's working fine, except I don't want the overall height of the RadioButton to be 20px tall. So I want to make the grid only 10x10 but still have the star 20x20 and centered behind the bullet (therefore the star's top left coordinate would be -5,-5 relative to the top left of grdBullet). How can I draw the star image behind or outside of the layout?
Excerpt of my style:
....
<ImageBrush x:Key="StarBrush" ImageSource="/Common;component/Resources/Images/FavoriteStar_FrontFacing_24x24_96.png" />
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<BulletDecorator VerticalAlignment="Center">
<BulletDecorator.Bullet>
<Grid Name="grdBullet" Height="20" Width="20" Background="{StaticResource StarBrush}">
<Grid Width="10" Height="10" HorizontalAlignment="Center" VerticalAlignment="Center">
<Ellipse Name="RadioOuter" Fill="#FFF4F4F4" Stroke="#FF8E8F8F" StrokeThickness="1"/>
<Ellipse Name="RadioInner" StrokeThickness="1" Margin="2" Fill="{StaticResource RadioInnerDefaultFill}" Stroke="{StaticResource RadioInnerDefaultStroke}" />
<Ellipse Name="RadioChecked" StrokeThickness=".75" Margin="2.5" Stroke="#FF193B55" Fill="{StaticResource RadioCheckedFill}" Visibility="Hidden" />
<Border CornerRadius="0" Margin="4" Name="RadioMark" Background="#FFADADAD" Visibility="Hidden" />
</Grid>
</Grid>
</BulletDecorator.Bullet>
<!--Text element-->
<TextBlock Margin="3,0,0,0" VerticalAlignment="Center" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}">
<ContentPresenter />
</TextBlock>
</BulletDecorator>
....
Two words: Negative margins.
<BulletDecorator.Bullet>
<Grid Width="10" Height="10" HorizontalAlignment="Center" VerticalAlignment="Center">
<Rectangle Height="20" Width="20" Margin="-5" Fill="{StaticResource StarBrush}" />
...
</Grid>
</BulletDecorator.Bullet>
For a more general purpose, you could set the Margin using a MultiValueConverter that returns a Thickness. For example, Margin.Left would be equal to -(SelfWidth - ParentWidth) / 2.
You can render anything anywhere with negative margins, no need for canvas. Try this (i have assumed -5,5 is center of image otherwise you need to put -15 15 or even -25 25
<ImageBrush x:Key="StarBrush"
ImageSource="/Common;component/Resources/Images/FavoriteStar_FrontFacing_24x24_96.png"
Margin="-5 5 0 0" />

WPF drop shadow

Whenever I set the Border.Effect property to a drop shadow effect every control contained within the control has a drop shadow.
Is there a way to set the shadow just to the border and not every control contained in the border?
Here is a short example of my code:
<Grid>
<Border Margin="68,67,60,67" BorderBrush="Black" BorderThickness="1" CornerRadius="10">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<Rectangle Fill="White" Stroke="Black" Margin="37,89,118,98" />
</Border>
</Grid>
Two choices:
Option 1: Add a border element with the effect on it as a sibling of the border / rectangle element tree you have. Something like this:
<Grid>
<Border Margin="68,67,60,67"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="10">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
</Border>
<Border Margin="68,67,60,67"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="10">
<Rectangle Fill="White"
Stroke="Black"
Margin="37,89,118,98">
</Rectangle>
</Border>
</Grid>
Option 2: Put the rectangle as a sibling of the border element like this:
<Grid>
<Border Margin="68,67,60,67"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="10">
<Border.Effect>
<DropShadowEffect />
</Border.Effect>
</Border>
<Rectangle Fill="White"
Stroke="Black"
Margin="37,89,118,98">
</Rectangle>
</Grid>
NOTE: You will have to tweak the layout on the second solution to make the rectangle line up where you want it
I realise that your question has an answer, but it doesn't appear to have the simplest answer. The simplest answer to your question is for you to just colour the background of the control that you set the shadow on. Like so:
<Grid>
<Border Margin="68,67,60,67" Background="White" BorderBrush="Black"
BorderThickness="1" CornerRadius="10">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<Rectangle Fill="White" Stroke="Black" Margin="37,89,118,98" />
</Border>
</Grid>
And the result:
I tried going for a similar design to this toolbar in white:
This is what I used:
<Border CornerRadius="8" Background="White" Grid.Row="1">
<Border.Effect>
<DropShadowEffect ShadowDepth="3" Opacity="0.2"/>
</Border.Effect>
</Border>

WPF shadow on stackpanel controls

Is there a way to make the shadow of the first control in a StackPanel appear on top of the second control?
I'm having trouble with this, look at the picture!
alt text http://img2.imageshack.us/img2/7073/issuef.png
Code sample:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid>
<StackPanel>
<Border Height="100" Width="100" Background="Red">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="Black" Direction="270" ShadowDepth="3" Opacity="1" Softness="2" />
</Border.BitmapEffect>
</Border>
<Border Height="100" Width="100" Background="blue">
</Border>
</StackPanel>
</Grid>
</Page>
You can do use Panel.ZIndex="0" in each of the Borders to set the z order of the items directly from the XAML.
<StackPanel>
<Border Height="100" Width="100" Background="Red" Panel.ZIndex="1">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="Black" Direction="270" ShadowDepth="3" Opacity="1" Softness="2" />
</Border.BitmapEffect>
</Border>
<Border Height="100" Width="100" Background="blue" Panel.ZIndex="0">
</Border>
</StackPanel>
Or you can use StackPanel.SetZIndex(object, value) if you wanted to do it from code.

Resources