Bind the height of a Polygon to the StackPanel height - wpf

I can't figure how to bind the height of a polygon to the height of my stack panel.
If I wanted to add a rectangle, all I had to do is something like that:
<Rectangle Width="75" >
<Rectangle.Fill>
<SolidColorBrush Color="Red" />
</Rectangle.Fill>
</Rectangle>
This one won't brake the height of the panel. but with the polygon it seems like I can't leave some of the points as blank so that will scale with the parent panel.
Thanks

Wrap your polygon with a <Viewbox>.
The Viewbox automatically scales its content to its size. Exactly how it does so can be tweaked with the Stretch and StretchDirection properties.

this solution works too
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Border BorderBrush="Black" BorderThickness="1,1,0,1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="TextBlock1" Margin="2" />
<TextBlock Text="TextBlock2" Margin="2" />
<TextBlock Text="TextBlock3" Margin="2" />
<TextBlock Text="TextBlock4" Margin="2" />
<TextBlock Text="TextBlock5" Margin="2" />
</StackPanel>
</Border>
<Path Fill="Yellow" Stroke="Black" StrokeThickness="1"
Width="50" Stretch="Fill">
<Path.Data>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="1,0.5">
<LineSegment Point="0,0" IsSmoothJoin="True" />
<LineSegment Point="0,1" IsSmoothJoin="True" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
</StackPanel>
</Grid>

Related

how to draw a certain shape and place it next to a text inside a textbox in wpf

I want used polygone to draw a form inside a button and then put it inside a stackpanel with a text but the result is deceiving...
this is my code:
<Button x:Name="button2" HorizontalAlignment="Left" Margin="27,164,0,0" VerticalAlignment="Top" Height="30" Width="75">
<Grid>
<StackPanel Orientation="Vertical">
<Canvas>
<Polygon
Points="0,-10 16,-10 20,-6 20,10 0,10 0,-10"
Stroke="Black"
StrokeThickness="1"
Fill="#4C87B3"/>
<Polygon
Points="2,-10 14,-10 14,-3 2,-3 2,-10"
Stroke="#d6d6c2"
StrokeThickness="1"
Fill="#d6d6c2"/>
<Polygon
Points="4,-9 6,-9 6,-4 4,-4 4,-9"
Stroke="#4C87B3"
StrokeThickness="1"
Fill="#4C87B3"/>
</Canvas>
<TextBlock Text="Save" FontSize="12" Foreground="White"/>
</StackPanel>
</Grid>
</Button>
the result:
and then in adition to that i want to give this figure some effect like the shadow shown in this picture below:
Since you only want to stack the Polygon elements on top of each other, it is sufficient to add them to a Grid. When wrap this Grid into a Viewbox, the icon will automatically scale, when setting e.g. Viewbox.Width. To prevent the icon from overlapping due to its negative positions, you have to add some Margin to the Grid that hosts the shapes.
To add a drop shadow simply add a DropShadowEffect to the outer Polygon.Effect.
<Button x:Name="button2" HorizontalAlignment="Left" Margin="27,164,0,0" VerticalAlignment="Stretch" Width="75"
Height="30">
<StackPanel>
<Viewbox Width="12" Stretch="Uniform">
<Grid Margin="0,10,0,0">
<Polygon
Points="0,-10 16,-10 20,-6 20,10 0,10 0,-10"
Stroke="Black"
StrokeThickness="1"
Fill="#4C87B3">
<Polygon.Effect>
<DropShadowEffect Opacity="0.9"
ShadowDepth="5"
Direction="315"
Color="Black"
BlurRadius="10" />
</Polygon.Effect>
</Polygon>
<Polygon
Points="2,-10 14,-10 14,-3 2,-3 2,-10"
Stroke="#d6d6c2"
StrokeThickness="1"
Fill="#d6d6c2" />
<Polygon
Points="4,-9 6,-9 6,-4 4,-4 4,-9"
Stroke="#4C87B3"
StrokeThickness="1"
Fill="#4C87B3" />
</Grid>
</Viewbox>
<TextBlock Text="Save" FontSize="12" Foreground="White" HorizontalAlignment="Center" />
</StackPanel>
</Button>

How can I draw this shape in xaml WPF?

I have to draw this shape in XAML. How can I draw this?
I tried this and this is OK but can't split two color
<Path Grid.Column="1" Fill="Red">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry Center="5,0" RadiusX="5" RadiusY="5" />
<RectangleGeometry Rect="0,0 5 80" />
<RectangleGeometry Rect="5,0 5 80" />
<EllipseGeometry Center="5,80" RadiusX="5" RadiusY="5" />
</GeometryGroup>
</Path.Data>
</Path>
You may use two Paths in a Canvas like these:
<Canvas>
<Path Fill="Yellow" Data="M0,0 A5,5 0 0 0 5,5 L5,75 A5,5 0 0 0 0,80Z"/>
<Path Fill="Red" Data="M5,5 A 5,5 0 0 0 10,0 L10,80 A5,5 0 0 0 5,75Z"/>
</Canvas>
For details, see Path Markup Syntax.
There are several ways. Perhaps the easiest one would be to create a Grid with two Ellipse elements that overlay the yellow and red parts:
<Grid Width="50" Height="200">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="Yellow" />
<Grid Background="Red" Grid.Column="1" />
<Ellipse Width="50" Height="50" Fill="White" Grid.ColumnSpan="2" VerticalAlignment="Top" Margin="0,-25,0,0" />
<Ellipse Width="50" Height="50" Fill="White" Grid.ColumnSpan="2" VerticalAlignment="Bottom" Margin="0,0,0,-25" />
</Grid>

wpf ClipToBounds right and bottom

How to clip path stroke? With ClipToBounds="True" there are unwanted pieces at rigth and bottom side.
<Grid Background="Yellow" ClipToBounds="True">
<Viewbox Stretch="Fill">
<Path Data="M30,0 L0,10 L0,40 L30,50 L30,0" Stroke="Red" StrokeThickness="5" />
</Viewbox>
</Grid>
EDIT
I figured out that I just need not to scale border thickness, so solution will be:
<Grid x:Name="grid" Grid.Row="2" Background="Yellow" >
<Grid.Resources>
<ScaleTransform x:Key="transform"
ScaleX="{Binding ActualWidth, ElementName=grid}"
ScaleY="{Binding ActualHeight, ElementName=grid}" />
</Grid.Resources>
<Path Stroke="Red" StrokeThickness="15" Stretch="Fill">
<Path.Data>
<PathGeometry Transform="{StaticResource transform}">
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="0,0.7">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="1,1" />
<LineSegment Point="1,0" />
<LineSegment Point="0,0.3" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
If it's ok not to scale the stroke thickness, you might drop the Viewbox and set Stretch="Fill" directly at the Path:
<Grid Background="Yellow" ClipToBounds="True" Margin="20">
<Path Stretch="Fill" Data="M30,0 L0,10 L0,40 L30,50 L30,0 Z"
Stroke="Red" StrokeThickness="20" />
</Grid>
Otherwise you might use the Path in a VisualBrush in e.g. a Rectangle (which needs to have some size set explicitly):
<Grid Background="Yellow" ClipToBounds="True" Margin="20">
<Viewbox Stretch="Fill">
<Rectangle Width="1" Height="1">
<Rectangle.Fill>
<VisualBrush>
<VisualBrush.Visual>
<Path Data="M30,0 L0,10 L0,40 L30,50 L30,0 Z"
Stroke="R*emphasized text*ed" StrokeThickness="5" />
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
</Viewbox>
</Grid>
Please also note that the path geometry is closed by a trailing Z.

WPF : Rounded-Corners Images

<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>

SL 4: Strange behavior with templated control

We have some xaml:
<Style TargetType="local:V_RelLine">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:V_RelLine">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Ellipse x:Name="startArrow" Height="20" Width="60" Fill="Green" Stroke="Blue" Visibility="Visible" />
<Path x:Name="LinePathPart" Visibility="Visible" Stroke="Red" StrokeDashArray="2 2" StrokeThickness="2"
>
<Path.Data>
<PathGeometry x:Name="LinePathGeometry" >
<PathFigure x:Name="linePathBezierFigure" >
<BezierSegment x:Name="linePathBezierSegment" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Ellipse x:Name="endArrow" Height="20" Width="20" Fill="Red" Stroke="Red" Visibility="Visible" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And in the code behind:
LinePathBezierFigure.StartPoint = startPoint;
Canvas.SetLeft(startArrow, startPoint.X);
Canvas.SetTop(startArrow, startPoint.Y);
/* similar for endArrow */
At runtime, startArrow and endArrow end up at the same point (even though they were set to different locations), as though they ended up at 0,0.
In fact, a subsequent call to Canvas.GetLeft(startArrow) show that it is at 0,0.
What is going on? Why are different objects in the same template, assigned the same coordinates, ending up in different locations?
Thanks for any insight in to this....
Just a thought but Canvas.Left and Canvas.Top normally only work well when the elements are placed in a Canvas rather than a Grid like you are using currently.

Resources