Edit progress bar shape wpf - wpf

I have a progress bar whose ControlTemplate is as follows and I want to set the value of the progress bar to a number so the progress updates to that value. I refered to the accpeted answer on this post but don't know how to use the converter for my scenario. I also checked this post and editing the Rect works fine. But I can't use the Rectangle Geomerty. Please help. (If I remove the commented Paths in the xaml below, it creates some value that fills the container.) This is the screenshot if I remove the commented xaml.
<Window.Resources>
<ControlTemplate x:Key="ProgressBarPath" TargetType="ProgressBar">
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Canvas Name="Test" Width="100" Height="100" Canvas.Left="0" Canvas.Top="0">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas.Resources/>
<Canvas Name="g40">
<!--<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path28"
Fill="Red">
<Path.Data>
<PathGeometry Figures="M35.1 57h-.2l-2.1 2.6-10 12.5c-2.1 2.7-5.2 6.2-4.3 9.5 1.7 6.1 7.6 6.1 11.8 6.1H50V57H35.7z" FillRule="NonZero"/>
</Path.Data>
</Path>-->
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path30" Fill="#FF333333">
<Path.Data>
<PathGeometry Figures="M30.8 87.7c-4.2 0-10.1 0-11.8-6.1-.9-3.3 2.2-6.8 4.3-9.5l10-12.5 2.1-2.6 5-6.3 1.6-2.1 1-1.3V17.5l-2.2-.2c-1.2-.1-2.1-1.1-2.1-2.4 0-1.3 1.1-2.4 2.4-2.4H50v-5h-9.2c-.9 0-1.7.3-2.2.4-2.8 1-4.9 3.8-4.9 7 0 3 1.8 5.6 4.4 6.7v24.2L29.3 57 16.7 72.8c-2.9 3.7-3.5 8.6-1.4 12.8 2 4.2 6.2 6.9 10.9 6.9H50v-4.8H30.8z" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path32" Fill="#FF333333">
<Path.Data>
<PathGeometry Figures="M35.4 57l-2.1 2.6 2.1-2.6z" FillRule="EvenOdd"/>
</Path.Data>
</Path>
<!--<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path34"
Fill="Red">
<Path.Data>
<PathGeometry Figures="M64.3 57H50v30.7h19.2c4.2 0 10.7-.7 11.8-6.1.7-3.4-2.2-6.8-4.3-9.5l-10-12.5-2.1-2.6h-.3z"
FillRule="NonZero"/>
</Path.Data>
</Path>-->
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path36" Fill="#FF666666">
<Path.Data>
<PathGeometry Figures="M84.7 85.6c2-4.2 1.5-9.1-1.4-12.8L70.7 57l-8.8-11.1V21.7c2.6-1.1 4.4-3.8 4.4-6.8 0-4.1-3.3-7.4-7.4-7.4H50v5h8.9c1.3 0 2.4 1.1 2.4 2.5 0 1.2-.9 2.2-2.1 2.3l-2.2.2v29.8l1 1.3 1.6 2.1 7.1 8.9 10 12.5c2.1 2.7 5 6.1 4.3 9.5-1.1 5.3-7.6 6.1-11.8 6.1H50v4.8h23.9c4.6 0 8.8-2.6 10.8-6.9z" FillRule="NonZero"/>
</Path.Data>
</Path>
<!--Unknown tag: metadata-->
</Canvas>
</Canvas>
</Viewbox>
</ControlTemplate>
</Window.Resources>
<Grid HorizontalAlignment="Center" Margin="0 4 0 0">
<ProgressBar Template="{StaticResource ProgressBarPath}" Width="480" Height="102" Value="40" />
</Grid>
</Window>

If the bar is a rectangular shape, you can utilize the built-in mechanism of ProgressBar to change the shape to show current value. Otherwise, you will need to implement the mechanism on your own.
I think Clemens's answer will give a good hint for this. Let's say, you create a custom ProgressBar named "FlaskProgressBar". In the CustomTemplate for this ProgressBar,
Define a PathGeometry for the Path of outline and set its Stroke two-colored Brush to draw outline.
Add a RectangleGeometry for the Path of vacant area and crop it using the Data of the Path of outline.
Add a RectangleGeometry for the Path of filled area which shows current value and crop it as well. Name the RectangleGeomety "PART_Content" so that it can be found from the code-behind.
<ControlTemplate x:Key="FlaskProgressBarTemplate" TargetType="{x:Type local:FlaskProgressBar}">
<ControlTemplate.Resources>
<LinearGradientBrush x:Key="OutlineBrush" StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="#FF333333" Offset="0.5"/>
<GradientStop Color="#FF666666" Offset="0.5"/>
<GradientStop Color="#FF666666" Offset="1"/>
</LinearGradientBrush>
</ControlTemplate.Resources>
<Grid>
<Grid Margin="6">
<!-- Draw outline -->
<Path x:Name="Outline"
StrokeThickness="8"
Stroke="{StaticResource OutlineBrush}">
<Path.Data>
<PathGeometry Figures="M 20,0 L 20,60 0,100 60,100 40,60 40,0 Z"/>
</Path.Data>
</Path>
<!-- Draw vacent area -->
<Path Data="{Binding Data, ElementName=Outline}"
Fill="{TemplateBinding Background}">
<Path.Clip>
<RectangleGeometry Rect="0,0,60,100"/>
</Path.Clip>
</Path>
<!-- Draw filled area -->
<Path Data="{Binding Data, ElementName=Outline}"
Fill="{TemplateBinding Foreground}">
<Path.Clip>
<RectangleGeometry x:Name="PART_Content" Rect="0,100,60,100"/>
</Path.Clip>
</Path>
</Grid>
</Grid>
</ControlTemplate>
In the "FlaskProgressBar", find the RectangleGeometry named "PART_Content" and when current value is changed, change Y value of its Rect to move it up or down.
[TemplatePart(Name = "PART_Content", Type = typeof(RectangleGeometry))]
public class FlaskProgressBar : ProgressBar
{
public FlaskProgressBar() : base()
{
ValueProperty.OverrideMetadata(typeof(FlaskProgressBar),
new FrameworkPropertyMetadata(0D, (d, e) => SetValue((FlaskProgressBar)d, (double)e.NewValue)));
}
private RectangleGeometry? _content;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_content = this.GetTemplateChild("PART_Content") as RectangleGeometry;
SetValue(this, Value);
}
private static void SetValue(FlaskProgressBar instance, double value)
{
if (instance._content is not null)
{
var rect = instance._content.Rect;
instance._content.Rect = new Rect(rect.X, rect.Height - value, rect.Width, rect.Height);
}
}
}
This ProgresBar looks like this:
The actual design of PathGeometry for the Path of outline is all up to you.

Related

Relative coordinates in DrawingBrush

I am somewhat confused about how relative coordinates work in WPF, especially in scenarios with DrawingBrushes.
Let's say I want to paint the background of a square area, which is flexible in it's size. I want to paint the background with a special "shape", let's say a kind of "T" laying on the side, with the vertical stroke going through the middle of the area.
Using relative coordinates (the size of the area is flexible), I came up with the following XAML:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="722" Width="722" UseLayoutRounding="True">
<Window.Resources>
<DrawingBrush x:Key="EdgeGrid">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<!-- draw a single T laying on the side -->
<GeometryGroup>
<!-- top to bottom -->
<LineGeometry StartPoint="0.5,0.0" EndPoint="0.5,1"/>
<!-- left to right -->
<LineGeometry StartPoint="0.5,0.5" EndPoint="1,0.5"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness="0.01" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Window.Resources>
<Grid Name="LayoutRoot">
<Rectangle Width="400" Height="400" Stroke="Black" StrokeThickness="1" Fill="{StaticResource EdgeGrid}">
</Rectangle>
</Grid>
But the result I get looks like this:
(source: bilder-hochladen.net)
Shouldn't the vertical stroke go right through the middle (X coordinate is 0.5)?
And also how can I set the pen thickness to be 1 or 2 pixels in relative mode?
Any ideas?
You'll have to set the ViewboxUnits property of the DrawingBrush to Absolute (instead of the default RelativeToBoundingBox). The Viewbox would still be (0,0,1,1).
See the TileBrush Overview article on MSDN for details about a brush's viewbox and viewport.
<DrawingBrush x:Key="EdgeGrid" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<LineGeometry StartPoint="0.5,0.0" EndPoint="0.5,1"/>
<LineGeometry StartPoint="0.5,0.5" EndPoint="1,0.5"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness="0.01" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
Of course this won't let you define stroke widths in pixels. Making the drawing in absolute coordinates and then putting the whole thing in a Viewbox won't also help much, because strokes would still be scaled.
In order to get a scalable drawing with fixed stroke width, you would have to use a Path element, where you set the StrokeThickness and Data properties and assign a ScaleTransform to the Transform property of the Geometry used as Data.
In your special case of drawing a centered, T-shaped figure with fixed stroke width, you may simply draw two (very long) Lines in a Canvas, where the coordinate origin is centered by putting the Canvas in a 2x2 Grid. You may even choose to have different strokes and stroke widths for the two Lines.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Canvas Grid.Column="1" Grid.Row="1">
<Line Y1="-10000" Y2="10000" Stroke="Black" StrokeThickness="1"/>
<Line X2="10000" Stroke="Black" StrokeThickness="1"/>
</Canvas>
</Grid>
To get vertical stroke right you need to do it like this:
<GeometryGroup>
<!-- top to bottom -->
<LineGeometry StartPoint="0.75,0.0"
EndPoint="0.75,1" />
<!-- left to right -->
<LineGeometry StartPoint="0.5,0.5"
EndPoint="1,0.5" />
</GeometryGroup>
But that won't help you with pen thickness. In general, if you want to scale a geometry - first create it using absolute coordinates you like (say in 0-100 range), then put that into ViewBox or use ScaleTransform, like this:
<Viewbox Width="400"
Height="400">
<Path Stroke="Black"
StrokeThickness="1">
<Path.Data>
<GeometryGroup>
<!-- top to bottom -->
<LineGeometry StartPoint="75,0"
EndPoint="75, 100" />
<!-- left to right -->
<LineGeometry StartPoint="50,50"
EndPoint="100, 50" />
</GeometryGroup>
</Path.Data>
</Path>
</Viewbox>
Let's see how the proposed solution would look like.
Let's assume we want to show the shapes in a kind of grid and draw various shapes depending on the data (by selecting an appropriate DateTemplate). For simplicity, in this example, let's draw only one kind of shape (a cross, as in my initial question):
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="722" Width="722" UseLayoutRounding="True">
<ItemsControl ItemsSource="{Binding data}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="10" Rows="10">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="Cell">
<Path StrokeThickness="2" Stroke="Blue" SnapsToDevicePixels="True">
<Path.Data>
<GeometryGroup>
<GeometryGroup.Transform>
<ScaleTransform ScaleX="{Binding ElementName=Cell, Path=ActualWidth}" ScaleY="{Binding ElementName=Cell, Path=ActualHeight}"/>
</GeometryGroup.Transform>
<!-- top to bottom -->
<LineGeometry StartPoint="0.5,0.0" EndPoint="0.5,1"/>
</GeometryGroup>
</Path.Data>
</Path>
<Path StrokeThickness="1" Stroke="Black" SnapsToDevicePixels="True">
<Path.Data>
<GeometryGroup>
<GeometryGroup.Transform>
<ScaleTransform ScaleX="{Binding ElementName=Cell, Path=ActualWidth}" ScaleY="{Binding ElementName=Cell, Path=ActualHeight}"/>
</GeometryGroup.Transform>
<!-- left to right -->
<LineGeometry StartPoint="0,0.5" EndPoint="1,0.5"/>
</GeometryGroup>
</Path.Data>
</Path>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
#Clemens Is this the solution you had in mind? Is this the correct way of doing it?
The only problem I have with the result is that the lines are blurry and there is even a break to be seen in the horizontal line. Is there any solution for this?

How do I draw with coordinates in [0;1] instead of pixels in WPF?

My coordinates are relative to the control size, in the 0 to 1 range. I currently draw on my control using manual scaling by RenderSize, which works fine, but is surely the wrong way.
How can I draw directly in 0-1 coordinates instead?
You may use Path controls and scale their Data by applying an appropriate transform to the Geometry.Transform property, like in the trivial example shown below. This way you would scale the drawn shapes, but not their stroke thicknesses.
<Grid>
<Canvas>
<Canvas.Resources>
<ScaleTransform x:Key="transform"
ScaleX="{Binding Value, ElementName=scaleSlider}"
ScaleY="{Binding Value, ElementName=scaleSlider}"/>
</Canvas.Resources>
<Path Stretch="None" Stroke="Blue" StrokeThickness="2">
<Path.Data>
<RectangleGeometry Rect="0.1,0.1,0.8,0.4"
Transform="{StaticResource transform}"/>
</Path.Data>
</Path>
<Path Stretch="None" Stroke="Red" StrokeThickness="2">
<Path.Data>
<EllipseGeometry Center="0.6,0.5" RadiusX="0.3" RadiusY="0.3"
Transform="{StaticResource transform}"/>
</Path.Data>
</Path>
</Canvas>
<Slider x:Name="scaleSlider" HorizontalAlignment="Center" VerticalAlignment="Bottom"
Width="100" Minimum="100" Maximum="500"/>
</Grid>

Set the icon color in a MahApp application

I want to set the icon color in a MahApp application, but the brush is not working. In this example the icoun should be white, but still it is black.
<Rectangle Width="20" Height="20">
<Rectangle.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="White" />
</Rectangle.Resources>
<Rectangle.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_cupcake}" />
</Rectangle.Fill>
</Rectangle>
This is the resource icons.xml file in my app.
<Canvas Width="48" Height="48" Clip="F1 M 0,0L 48,0L 48,48L 0,48L 0,0" x:Key="appbar_cupcake">
<Path Width="24" Height="25" Canvas.Left="13" Canvas.Top="11" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 32,14C 33.1046,14 34,14.8954 34,16C 34,16.3643 33.9026,16.7058 33.7324,17L 34,17C 35.1046,17 36,17.8954 36,19C 36,20.1046 35.1046,21 34,21L 35,21C 36.1046,21 37,21.8954 37,23C 37,24.1046 36.1046,25 35,25L 15,25C 13.8954,25 13,24.1046 13,23C 13,21.8954 13.8954,21 15,21L 16,21C 14.8954,21 14,20.1046 14,19C 14,17.8954 14.8954,17 16,17L 16.2676,17C 16.0974,16.7058 16,16.3643 16,16C 16,14.8954 16.8954,14 18,14C 19,14 21,12 25,11C 29,14 31,14 32,14 Z M 15,26L 35,26L 32,36L 18,36L 15,26 Z " />
</Canvas>
What I'm doing wrong?
If you want to dynamically set the Fill color, you can do that by setting the Fill property. As you can see, you are already using the Fill property for the VisualBrush. Fortunately you can use the VisualBrush also in the OpacityMask property.
<Rectangle Fill="Black">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_cupcake}" Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
Hope that helps.

How can I check whether 2 WPF Paths (with MatrixTransform applied) overlap

In my WPF multitouch application, I want to check whether a Path is overlapping another Path.
How can I do this? I have found different solutions on the Internet, but none is working, because of the combination of requirements:
2 Paths of irregular shape (so Bounds are not working: no Rect)
On the Paths a MatrixTransform is applied (because of Manipulation events)
The Paths can be rotated and scaled (using the MatrixTransform)
The RenderTransformOrigin is 0.5, 0.5
How can I do this?
Example: in this example the blue and red star are overlapping, the red and the green are not.
<Window x:Class="WPFTest.OtherWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OtherWindow" Height="300" Width="300" >
<Canvas >
<Path x:Name="path1" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#99FF0000" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="1,0,0,1,50,50"/>
</Path.RenderTransform>
</Path>
<Path x:Name="path2" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#990000FF" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,35,45"/>
</Path.RenderTransform>
</Path>
<Path x:Name="path3" Data="M17,0 L23,11 34,13 27,21 28,32 18,24 8,30 9,19 0,11 13,11 z" Fill="#9900FF00" Stroke="Black" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,82,55"/>
</Path.RenderTransform>
</Path>
</Canvas>
How can I check this from code behind?
Thanks,
Jim
If it is acceptable, you may use transformed geometries for Path.Data instead of (render-)transformed Paths (with the drawback of course that their stroke won't be scaled).
Once you use such transformed geometries, you can determine their mutual intersection by Geometry.FillContainsWithDetail, which gives you an enum value for the kind of intersection.
Your XAML might look like the following. Note that because Geometry does not have something like a transform origin, I modified your geometry so that the coordinate origin lies in its center. I also added the resulting offset to the MatrixTransform offset values.
<Canvas>
<Path Name="redStar" Fill="#99FF0000" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="1,0,0,1,67,66"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
<Path Name="blueStar" Fill="#990000FF" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,52,61"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
<Path Name="greenStar" Fill="#9900FF00" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M0,-16 L6,-5 17,-3 10,5 11,16 1,8 -9,14 -8,3 -17,-5 -4,-5 z">
<PathGeometry.Transform>
<MatrixTransform Matrix="0.777817459305202,0.777817459305202,-0.777817459305202,0.777817459305202,99,71"/>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
The following code will determine the intersections:
Geometry redGeometry = redStar.Data;
Geometry blueGeometry = blueStar.Data;
Geometry greenGeometry = greenStar.Data;
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));
Trace.TraceInformation("blue/green intersection: {0}", blueGeometry.FillContainsWithDetail(greenGeometry));
Trace.TraceInformation("green/red intersection: {0}", greenGeometry.FillContainsWithDetail(redGeometry));
redGeometry.Transform = new MatrixTransform(1, 0, 0, 1, 70, 90);
Trace.TraceInformation("red/blue intersection: {0}", redGeometry.FillContainsWithDetail(blueGeometry));

Inheriting values declared at UserControl instantiation

First off, I apologize if this question has been asked before. I've done a bit of Google searching but I'm not really sure what the correct keywords are to find what I'm looking for.
Basically my problem is simple to understand. I have a Silverlight project and on the MainPage.xaml I have declared a UserControl and given it a height and a width.
<Grid>
<control:AlarmButton Height="50" Width="50" />
</Grid>
Now within AlarmButton I have a button that has its own Control Template which is set up the way I want. It has a content presenter within it right now.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Alarms.AlarmButton">
<UserControl.Resources>
<ControlTemplate x:Key="StatusButton" >
<Viewbox Stretch="Fill">
<Grid>
<Path x:Name="Base" StrokeThickness="1.0" Stroke="#ff000000" StrokeMiterLimit="1.0" Fill="#ff666666" Data="F1 M 99.500,99.500 L 0.500,99.500 L 0.500,0.500 L 99.500,0.500 L 99.500,99.500 Z"/>
<Path x:Name="Interior" Opacity="0.5" StrokeThickness="1.0" Stroke="#ff191919" StrokeMiterLimit="1.0" Data="F1 M 97.500,97.500 L 2.500,97.500 L 2.500,2.500 L 97.500,2.500 L 97.500,97.500 Z">
<Path.Fill>
<LinearGradientBrush MappingMode="Absolute" StartPoint="2.500,2.499" EndPoint="97.500,97.499">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.00" Color="#3FFFFFFF"/>
<GradientStop Offset="0.151" Color="Transparent"/>
<GradientStop Offset="1.00" Color="#BFFFFFFF"/>
<GradientStop Color="#53FFFFFF" Offset="0.655"/>
</LinearGradientBrush.GradientStops>
<LinearGradientBrush.Transform>
<MatrixTransform Matrix="1.000,0.000,-0.000,-1.000,0.000,100.000" />
</LinearGradientBrush.Transform>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path x:Name="LargeShader" Opacity="0.1" Fill="#ffffffff" Data="F1 M 94.667,18.667 L 94.667,94.667 L 6.333,94.667 C 6.333,94.667 94.667,67.348 94.667,18.667 Z"/>
<Path x:Name="SmallShader" Opacity="0.1" Fill="#ffffffff" Data="F1 M 94.667,43.667 L 94.667,94.667 L 20.333,94.667 C 20.333,94.667 94.667,76.334 94.667,43.667 Z"/>
<ContentPresenter x:Name="contentPresenter" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Viewbox>
</ControlTemplate>
</UserControl.Resources>
<Grid >
<Button Template="{StaticResource StatusButton}" >
<TextBlock Text="this is a text box"
TextTrimming="WordEllipsis" />
</Button>
</Grid>
</UserControl>
Later on I'm going to bind the Text property to a DependencyProperty so I can use this button with multiple text. What I want to happen is if the text is too big it will ellipse it and not have the box change or the textblock overflow. I just need to bind the height and width of the TextBlock to some values to contain it.
My question is this; is it possible for the TextBlock to bind its height and width to the values as declared in the MainPage.xaml? Or is this more complicated than I imagine? Is there a better way to go about this?
EDIT
This might give a little more info on what I'm trying to accomplish. This is my "button" with RobSiklos' changes
I think the problem has something to do with the Viewbox, which is telling the TextBlock that it has as much room as it wants.
Probably removing the Viewbox will solve the issue (or at least take the ContentPresenter out of the Viewbox)
I'm not sure I completely understand. Are you trying to make the text ellipse because you don't want the text block to grow if the text is too big? If so, you could use a converter (in the binding statement of the Text property) to have the the converter return the full text value if the text is under a certain length, or have the converter show an ellipse if the text is over that value.
This ought to work:-
<Grid x:Name="LayoutGrid">
<Button Template="{StaticResource StatusButton}" >
<TextBlock Text="this is a text box" TextTrimming="WordEllipsis"
Width="{Binding Parent.Width, ElementName=LayoutRoot}"
Height="{Binding Parent.Height, ElementName=LayoutRoot}" />
</Button>
</Grid>
It assumes that a Width and Height will be specified. An alternative would be to be to use the SizeChanged event of the UserControl to assign values of Width and Height directly.

Resources