Stretching a XAML Path to fill its containing element - xaml

I have a ControlTemplate with some Paths in it. I would like the Paths to stretch and fill the control they are in, such as a Button. How can I do this?
What I have currently looks like this:
<ControlTemplate x:Key="SomeTemplate" TargetType="Button">
<Canvas Background="AliceBlue">
<Path Data="M 99.5,50 A 49.5,49.5 0 1 1 0.5,50 A 49.5,49.5 0 1 1 99.5,50 z"
Fill="White" Stroke="Black" StrokeThickness="1" />
<Path Data="M 15,50 C 17.5,22.5 47.5,22.5 50,50 C 52.5,77.5 82.5,77.5 85,50"
Stroke="Black" StrokeThickness="1" />
</Canvas>
</ControlTemplate>
...
<Button Template="{StaticResource SomeTemplate}" Height="120" Width="120" />
I am aware of ScaleTransform's StrechX and StretchY attributes, but they are only proportional scaling of the original Path's size.
Would I use a value converter? Or perhaps some form of relative binding to the parent's size?

Throwing a ViewBox around the Canvas in your example should work.

To stretch a Path use the Stretch property. It works just like image stretching - described here: https://msdn.microsoft.com/en-us/library/system.windows.media.stretch(v=vs.110).aspx (System.Windows.Media > Stretch Enumeration). In the case shown below, setting the value to Uniform will preserve the path width-height ratio filling the control which it occupies so that the whole path is visible.
<Path Stretch="Uniform" Data="..."/>
There is a side-effect: Stretching a Path this way will "normalize" its data i.e. even if the data would be written so that all the points are transformed from the origin [1], when stretch the transform is omitted [2] (hope i'm explaining this clearly).
You can use this to your advantage when having a messy object from Inkscape for example (not transformed to the origin) not worrying about the transformed data.
<Grid Width="200" Height="200">
<TextBlock Text="(0,0)" />
<TextBlock Text="(200,200)" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
<Path Stroke="Blue" Stretch="None" Fill="Beige" Data="M 63,50 82,86 107,62 84,65 Z"/>
<Rectangle Stroke="Red" StrokeThickness="1"/>
</Grid>
<Grid Width="200" Height="200">
<TextBlock Text="(0,0)" />
<TextBlock Text="(200,200)" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
<Path Stroke="Blue" Stretch="Uniform" Fill="Beige" Data="M 63,50 82,86 107,62 84,65 Z"/>
<Rectangle Stroke="Red" StrokeThickness="1"/>
</Grid>

Related

Xamarin.forms Slider ThumImage hides on Maximum value

I am using slider control and setting triangle as thumb image. On extreme left or minimum value, image shows correctly. But on dragging it to maximum values it hides out on maximum value.
<Slider.ThumbImageSource>
<OnPlatform x:TypeArguments="FileImageSource">
<On Platform="UWP" Value="Assets/Images/Triangle.png"/>
</OnPlatform>
</Slider.ThumbImageSource>
When you use this slider control with Thumb Image in Xamarin.uwp, there is no horizontal limitation. However, the original thumb works well.
You could create a custom control to use the original Thumb style to cover the Thumb Image style.
Change:
<Thumb x:Name="HorizontalThumb"
Background="{ThemeResource SystemControlForegroundAccentBrush}"
Style="{StaticResource SliderThumbStyle}"
DataContext="{TemplateBinding Value}"
Height="24"
Width="8"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
AutomationProperties.AccessibilityView="Raw" />
<Thumb x:Name="HorizontalImageThumb"
Visibility="Collapsed"
Background="{ThemeResource SystemControlForegroundAccentBrush}"
Style="{StaticResource SliderThumbImageStyle}"
DataContext="{TemplateBinding Value}"
Tag="{Binding ThumbImageSource, RelativeSource={RelativeSource TemplatedParent}}"
Height="24"
Width="24"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
AutomationProperties.AccessibilityView="Raw" />
To:
<Thumb
x:Name="HorizontalThumb"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
Width="24"
Height="24"
AutomationProperties.AccessibilityView="Raw"
Style="{StaticResource SliderThumbImageStyle}"
Background="{ThemeResource SystemControlForegroundAccentBrush}"
DataContext="{TemplateBinding Value}"
Tag="{Binding ThumbImageSource, RelativeSource={RelativeSource TemplatedParent}}"
/>
And comment to the method which used to Swap Thumbs.
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
Thumb = GetTemplateChild("HorizontalThumb") as Thumb;
ImageThumb = GetTemplateChild("HorizontalImageThumb") as Thumb;
//SwapThumbs(this);
OnReady();
}
And add the code below to use this property to change the default for the style that the control uses.
public MySlider()
{
this.DefaultStyleKey = typeof(MySlider);
}
Then comment the code in MainPage.cs of Xamarin.uwp.
LoadApplication(new App43.App());
At last, you could use this control in Xamarin.uwp MainPage.xaml.
<local:MySlider ThumbImageSource="Assets/pig.jpg"/>
Result:
I have upload my sample on GitHub, you could download App43 folder for reference.
https://github.com/WendyZang/Test.git

WPF- Auto Resize the popup control

I am New WPF. I have PopupControl below is XAML for that:-
<Popup Name="PopupRemark" AllowsTransparency="True" Placement="Left" HorizontalOffset="45" VerticalOffset="-22"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ToggleButton}}"
IsOpen="{Binding IsChecked, ElementName=btnInfo}" StaysOpen="False" >
<Canvas Width="230" Height="200" Background="Transparent" >
<Path x:Name="Container" Canvas.Left="0" Canvas.Top="0" Fill="#f2f6f7" Stroke="#A9A9A9"
Data="M 230,40 L220,50 220,90 0,90 0,0 220,0 220,30 230,40">
<Path.Effect>
<DropShadowEffect BlurRadius="18" Color="Black" Opacity="0.4"/>
</Path.Effect>
</Path>
<Label Grid.Row="0" FontSize="13" FontWeight="Bold" FontFamily="Roboto" Content="Remark" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Center"/>
<TextBlock Canvas.Left="5" Canvas.Top="25" Width="210" Text="{Binding Remark}" Foreground="#2c3e50" FontFamily="Roboto" FontSize="11" TextWrapping="Wrapwithoverflow" />
</Canvas>
</Popup>
Issue is, I want to set auto height & width for canvas or popup control so my popup will size as per content into it.I googled and knew that canvas should have fix height or width but is there any solution(Workaround) to make popup auto sizable.or how can add scroller into popup. It will be greatly appreciable
Thanks in advance

Adaptive rendering of ListView items for UWP app

I'm writing a UWP app and have several areas where searches are performed and results are rendered in a ListView where the ItemTemplate is defined inside a DataTemplate. Nothing fancy is going on here - just returns a list of items in a single "column", if you will.
There are three supported screen states (or widths), 320, 640, and 1024. I'd like to render these search results in two "columns" when the screen state is 640 or 1024 (wide states).
I'd like to use adaptive triggers for this task, but I'm at a loss of how to do this intelligently. There are examples of creating different views for each device family, but they seem too dependent on checking the device family. Best practices dictate using screen width thresholds instead. Either way, it seems this could easily be accomplished using adaptive triggers.
Any insight or examples of where this is done would be appreciated. The code is included to provide more context and to act as my starting point.
<Page.Resources>
<ResourceDictionary>
<Style x:Key="TextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource LargeTextBlockStyle}">
<Setter Property="Foreground" Value="{StaticResource TitleBrush}" />
</Style>
<DataTemplate x:Key="SearchResult">
<StackPanel Width="{Binding ActualWidth, ElementName=Parent}">
<Border Background="Gray" MinWidth="235">
<Grid Height="155">
<Image Source="{Binding SearchResultImage}"
Style="{StaticResource ImageStyle}" />
<Rectangle Fill="{StaticResource BackgroundBrush}" />
<StackPanel Margin="10,10,15,10" VerticalAlignment="Center">
<TextBlock Text="{Binding SearchResultName}"
Style="{StaticResource TextBlockStyle}"
VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Border>
<Button Style="{StaticResource ButtonStyle}"
Command="{Binding ViewRecipeCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding}">
<StackPanel Margin="0" Orientation="Horizontal" HorizontalAlignment="Center">
<SymbolIcon Symbol="Calendar" Margin="0,0,10,0" />
<TextBlock x:Uid="ViewRecipeCommandTextBlock"
Text="View Recipe"
Style="{StaticResource TextBlockStyle}" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderStackPanel" Grid.Row="0" Margin="10">
<TextBlock x:Uid="RecipesTitle" Text="All Recipes"
Style="{StaticResource TextBlockStyle}"
Margin="0,0,0,10" />
</StackPanel>
<ListView x:Name="ResultsListView" Grid.Row="2"
ItemsSource="{Binding AllRecipes}"
ItemTemplate="{StaticResource SearchResult}" />
</Grid>
What I'd do to use a GridView instead a ListView, and change the GridView's ItemsPanel based on the width changes.
By using a GridView with an item width as wide as the screen size (320) you can get it to behave like a ListView, and if the GridView get's wider the content will automatically produce two columns for you. The only thing not to forget is to change the default scrolling direction of the ItemsPanel from horizontal to vertical.

Canvas won't overlap in XAML

I have the follow XAML code which gives a students score for a course (these are the green, yellow and red bars, they are TextBlocks) the grey bars next to them are the standard deviation scores, they are Rectangles. The grey bars need to be underneath the colored bars.
I have tried to use ZIndex but this didn't change anything.
It does overlap with the horizontal lines with the numbers next to them, these are also Rectangles.
I have to use textblocks for the colored ones (it's an assignment from school).
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Ivory" FontSize="12" Background="Red" Height="45" Width="162" TextWrapping="Wrap" TextAlignment="Center" Padding="0,10,0,0" Opacity="0.5" Canvas.Top="258" Canvas.Left="275">
Boekhoudkundig inzicht
<TextBlock.RenderTransform>
<RotateTransform Angle="90" />
</TextBlock.RenderTransform>
<TextBlock.Effect>
<DropShadowEffect BlurRadius="15" Direction="60" ShadowDepth="3" />
</TextBlock.Effect>
</TextBlock>
<Rectangle Height="3" Width="45" Fill="Black" Canvas.Top="284" Canvas.Left="275" />
<Rectangle Height="80" Width="45" Fill="Gray" Opacity="0.5" Canvas.Top="229" Canvas.Left="275" />
The full XAML code can be found at pastebin

Adding Contacts.contactdown to TagVisualization

I am working with TagVisualization, which displays an ellipse around the tag with name. I want to put 2 round buttons on the circumference (at well defined points) on the ellipse so that clicking them will result in change of some label text. I am unable to do this because I am unable to add s:Contacts.ContactDown property to the smaller ellipse.
Below is the XAML:
<s:TagVisualization x:Class="ControlsBox.TagVisual"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
Loaded="TagVisual_Loaded">
<Canvas>
<Ellipse Width="300" Height="300" Stroke="White" StrokeThickness="8" Opacity="0.7">
<Ellipse.Effect>
<BlurEffect Radius="12" />
</Ellipse.Effect>
</Ellipse>
<Ellipse Height="296" Width="296" Stroke="AntiqueWhite" StrokeThickness="4" >
<Ellipse.Effect>
<BlurEffect Radius="4"/>
</Ellipse.Effect>
</Ellipse>
<Label Content="John's Phone" HorizontalContentAlignment="Center" Padding="0,250,0,0" VerticalContentAlignment="Bottom" IsHitTestVisible="false">
<Label.Effect>
<DropShadowEffect BlurRadius="9" ShadowDepth="0" Color="Aqua"/>
</Label.Effect>
</Label>
<Ellipse Height="40" Width="40" Stroke="White" StrokeThickness="4" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,70,0,0" Fill="Black"
s:Contacts.ContactDown="UNABLE_TO_ADD" />
</Canvas>
After doing bit of googling, it appeared that using Expression Blend to create buttons with a style is an easier option.