Reuse Button Content in XAML - silverlight

I have button Content that I want to use in multiple buttons on a UserControl in my Silverlight application. Here is the code for one button:
<Grid x:Name="LayoutRoot" Background="White">
<Button Grid.Column="1" IsEnabled="{Binding PrivilegeChanged}" Height="24" Width="24">
<Button.Content>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="UndoIcon" Width="16" Height="16" Clip="F1 M 0,0L 16,0L 16,16L 0,16L 0,0" UseLayoutRounding="False">
<Canvas x:Name="Arrow_2" Width="16" Height="16" Canvas.Left="0" Canvas.Top="0">
<Path Width="17.0154" Height="17" Canvas.Left="-0.5" Canvas.Top="-0.499999" Stretch="Fill"
StrokeLineJoin="Round" Stroke="#FF006432" Fill="#FF00C800"
Data="F1 M 12.5819,16C 14.1685,12.7951 14.1052,6.14911 11.0969,4.25C 9.23816,3.07665 6.71915,3.4789 5.40404,5.25L 8.12669,8.25L 0,8.91667L 0,9.53674e-007L 3.17642,3.25C 4.16648,1.91667 5.52584,0.61155 7.13664,0.25C 9.85332,-0.359774 13.4395,0.629333 15.0571,2.91667C 17.402,6.23256 15.0026,12.7401 12.5819,16"/>
</Canvas>
</Canvas>
</Button.Content>
</Button>
</Grid>
How can I make Button.Content reusable without removing the button outline?

The easiest approach would be to stick your button content design in its own UserControl :-
<UserControl x:Class="SilverlightApplication1.MyButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Canvas Width="16" Height="16" Clip="F1 M 0,0L 16,0L 16,16L 0,16L 0,0" UseLayoutRounding="False">
<Canvas Width="16" Height="16" Canvas.Left="0" Canvas.Top="0">
<Path Width="17.0154" Height="17" Canvas.Left="-0.5" Canvas.Top="-0.499999" Stretch="Fill"
StrokeLineJoin="Round" Stroke="#FF006432" Fill="#FF00C800"
Data="F1 M 12.5819,16C 14.1685,12.7951 14.1052,6.14911 11.0969,4.25C 9.23816,3.07665 6.71915,3.4789 5.40404,5.25L 8.12669,8.25L 0,8.91667L 0,9.53674e-007L 3.17642,3.25C 4.16648,1.91667 5.52584,0.61155 7.13664,0.25C 9.85332,-0.359774 13.4395,0.629333 15.0571,2.91667C 17.402,6.23256 15.0026,12.7401 12.5819,16"/>
</Canvas>
</Canvas>
</UserControl>
Now you can create multiple instances of this user control where ever you need this content:-
<UserControl x:Class="SilverlightApplication1.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication1"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Horizontal">
<Button Grid.Column="1" IsEnabled="{Binding PrivilegeChanged}" Height="24" Width="24" Margin="2">
<local:MyButton />
</Button>
<Button Grid.Column="1" IsEnabled="{Binding SomethingElseChanged}" Height="24" Width="24" Margin="2">
<local:MyButton />
</Button>
</StackPanel>
</Grid>
</UserControl>

Normally you would create a Template that creates the custom layout for your button. A quicker and more immediate solution for you would be to set the content within a Style, and apply the style to buttons you need.
Define the style with your content:
<Window.Resources>
<Style x:Key="ButtonArrowStyle" TargetType="Button">
<Setter Property="Content">
<Setter.Value>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="UndoIcon" Width="16" Height="16" Clip="F1 M 0,0L 16,0L 16,16L 0,16L 0,0" UseLayoutRounding="False">
<Canvas x:Name="Arrow_2" Width="16" Height="16" Canvas.Left="0" Canvas.Top="0">
<Path Width="17.0154" Height="17" Canvas.Left="-0.5" Canvas.Top="-0.499999" Stretch="Fill"
StrokeLineJoin="Round" Stroke="#FF006432" Fill="#FF00C800"
Data="F1 M 12.5819,16C 14.1685,12.7951 14.1052,6.14911 11.0969,4.25C 9.23816,3.07665 6.71915,3.4789 5.40404,5.25L 8.12669,8.25L 0,8.91667L 0,9.53674e-007L 3.17642,3.25C 4.16648,1.91667 5.52584,0.61155 7.13664,0.25C 9.85332,-0.359774 13.4395,0.629333 15.0571,2.91667C 17.402,6.23256 15.0026,12.7401 12.5819,16"/>
</Canvas>
</Canvas>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And then define a button to use the style:
<Button Style="{StaticResource ButtonArrowStyle}"/>

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>

Getting a path to overlap a rectangle or other control

I have the following XAML :
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel Margin="5">
<Path Stroke="Black" StrokeThickness="1" Fill="White" DockPanel.Dock="Left" VerticalAlignment="Center">
<Path.Data>
<GeometryGroup>
<LineGeometry StartPoint="10,0" EndPoint="0,10" />
<LineGeometry StartPoint="0,10" EndPoint="10,20" />
</GeometryGroup>
</Path.Data>
</Path>
<Rectangle Stroke="Black" RadiusX="10" RadiusY="10"/>
</DockPanel>
</Page>
It creates like a speech bubble. However I would like the part where the two join to be white or not to have any stroke.
Not very clever, but perhaps sufficient:
<DockPanel Margin="5">
<Path Stroke="Black" StrokeThickness="1"
Fill="White" DockPanel.Dock="Left" VerticalAlignment="Center"
Panel.ZIndex="1" Margin="0,0,-1,0" Data="M10,0 L0,10 10,20"/>
<Rectangle Stroke="Black" RadiusX="10" RadiusY="10"/>
</DockPanel>
A better solution might be to create a CombinedGeometry from the Path and the Rectangle.
If you have access to Blend you can use the Callout control, which does exactly what you want.
It resides in this assembly:
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries\Microsoft.Expression.Drawing.dll
and is used like that:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" x:Class="WpfApplication1.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ed:Callout AnchorPoint="-0.061,0.716" CalloutStyle="RoundedRectangle" Content="Callout" Fill="#FFF4F4F5" FontSize="14.667" HorizontalAlignment="Left" Height="109" Margin="61,78,0,0" Stroke="Black" VerticalAlignment="Top" Width="375"/>
</Grid>
</Window>
Edit: if you have Blend (for VS 2012) you can easily draw a path yourself that looks like a callout.
Example:
<Path Data="M110.029,0.5 L305.895,0.5 C314.17927,0.50000358 320.895,7.2157323 320.895,15.500005 L320.895,144.202 C320.895,152.48627 314.17927,159.202 305.895,159.202 L110.029,159.202 C101.74473,159.202 95.028999,152.48627 95.029,144.202 L95.029,119.139 0.5,94.029644 94.530329,44.776012 95.029,69.723011 95.029,15.500005 C95.028999,7.2157323 101.74473,0.50000358 110.029,0.5 z" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="159.702" Margin="122.366,45.642,0,0" Stretch="Fill" Stroke="Black" VerticalAlignment="Top" Width="321.395"/>

how I put image on progress bar?

i put progress bar but its not look proper
<ProgressBar Height="30" Width="300" VerticalAlignment="Center" BorderThickness="0" HorizontalAlignment="Center" Foreground="#0A8098" BorderBrush="Transparent" Name="pbProcessing" >
<ProgressBar.Background>
<ImageBrush ImageSource="/ClientApplication;component/Images/ProgressBackground.png"/>
</ProgressBar.Background>
<ProgressBar.Clip>
<RectangleGeometry RadiusX="20.5" RadiusY="20.5" Rect="0,0,300,19"/>
</ProgressBar.Clip>
</ProgressBar>
but i shown
Any idea how to put image on progress bar perfrectly? Thanks.
Try this
<ProgressBar Value="30" Height="30" Width="300" VerticalAlignment="Center" BorderThickness="0" HorizontalAlignment="Center" Foreground="#0A8098" BorderBrush="Transparent" Name="pbProcessing" >
<ProgressBar.Template>
<ControlTemplate>
<Grid>
<Image Name="PART_Track" Source="bird1.jpg" Stretch="Fill"/>
<Rectangle Name="PART_Indicator"
Fill="BlanchedAlmond"
HorizontalAlignment="Left"/>
</Grid>
</ControlTemplate>
</ProgressBar.Template>
</ProgressBar>

WPF Square auto-size to parent container

I have a UniformGrid object in my WPF project that has 2 rows and 3 cols and its width and height are set to auto (with both alignments set to Stretch).
This grid will hold 6 squares that I want to fill as much of their cell as possible and be centered horizontally and vertically.
What do I need to be added to allow for the squares to increase/decrease their length/width based on the dynamic size of the parent? I.E., when the window is resized.
Here is my xaml so far:
<UniformGrid Rows="2" Columns="3">
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Stroke="Black" Width="100"/>
</UniformGrid>
Edit:
And the Rectangle objects need to remain square.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid>
<UniformGrid Rows="2" Columns="3">
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
<Viewbox Stretch="Uniform"><Rectangle Height="100" Width="100" Fill="#FFF4F4F5" Stroke="Black" /></Viewbox>
</UniformGrid>
</Grid>
</Page>
You could do this:
<UniformGrid.Resources>
<Style TargetType="Rectangle">
<Setter Property="Width"
Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualHeight}" />
</Style>
</UniformGrid.Resources>
Or you could bind the Height to the ActualWidth.
Unfortunately this will not keep them stretched to the maximum.
If you remove the height and width properties it will do just that.

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