Rectangle Stretch Property Behavior - wpf

Can someone explain my misunderstanding of the Rectangle's Stretch property when setting it to NONE? According to MSDN, the definition for this value is "The content preserves its original size." Look at the code below. When I set Stretch = NONE on the fourth rectangle, it disappears.
<Grid Margin="20">
<Rectangle Height="Auto" Width="2" HorizontalAlignment="Left" VerticalAlignment="Stretch" Fill="Black"/>
<Rectangle Height="2" Width="10" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Black"/>
<Rectangle Height="2" Width="10" HorizontalAlignment="Left" VerticalAlignment="Bottom" Fill="Black"/>
<Rectangle Stretch="None" Name="Right" Height="Auto" Width="2" HorizontalAlignment="Right" VerticalAlignment="Stretch" Fill="Black"/>
<Rectangle Height="2" Width="10" HorizontalAlignment="Right" VerticalAlignment="Top" Fill="Black"/>
<Rectangle Height="2" Width="10" HorizontalAlignment="Right" VerticalAlignment="Bottom" Fill="Black"/>
</Grid>
Why is this happening? This code is an excerpt from a paging control I'm using on a custom chart. I am wrapping the paging control in a ViewBox to allow auto-resizing, but I do not want my border markers resizing (the example above is what the page border markers look like).

Rectangle class uses private _rect field for rendering.
Here is the code of the Rectangle.OnRender:
protected override void OnRender(DrawingContext drawingContext)
{
...
drawingContext.DrawRoundedRectangle(base.Fill, pen, this._rect, this.RadiusX, this.RadiusY);
}
Now let's look at the ArrangeOverride method:
protected override Size ArrangeOverride(Size finalSize)
{
...
switch (base.Stretch)
{
case Stretch.None:
{
this._rect.Width = (this._rect.Height = 0.0);
break;
}
...
}
...
return finalSize;
}
It seems that when Stretch in None there is only empty rectangle. You may see it only adding a stroke. Maybe it's a bug.

Related

Horizontal dashed line stretched to container width

I have a layout contained within a ScrollViewer in which I need to draw a horizontal dashed line that stretches to the full width of the container. The closest I've managed is the following
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel>
<Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" />
<Line HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black"
X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
StrokeDashArray="2 2" StrokeThickness="1" />
</StackPanel>
</ScrollViewer>
This nearly works, however once the container (in my case a window) has been enlarged, the line doesn't shrink back down to the appropriate size when the container is sized back down. The below is the screenshot of the same window after I have horizontally sized the window up and down.
Note that the fact that the line is dashed is important as it means that solutions that involve stretching the line don't work (the dashes appear stretched).
I know that this is because of the X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" binding (by design the line is always the widest thing in the scrollable region, so when I size the window down the scrollable region the line defines the width of the scrollable region), however I can't think of a solution.
How can I fix this problem?
Screenshot of why using ViewportWidth doesn't work
I realised that what I needed was for the Line to ask for zero space during the measure step of layout, but then use up all the available space during the arrange step. I happened to stumble across the question Make WPF/SL grid ignore a child element when determining size which introduced the approach of using a custom decorator which included this logic.
public class NoSizeDecorator : Decorator
{
protected override Size MeasureOverride(Size constraint) {
// Ask for no space
Child.Measure(new Size(0,0));
return new Size(0, 0);
}
}
(I was hoping that some existing layout control incorporated this logic to avoid having to write my own layout logic, however the logic here is so simple that I'm not really that fussed). The modified XAML then becomes
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel>
<Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" />
<local:NoSizeDecorator Height="1">
<Line Stroke="Black" HorizontalAlignment="Stretch"
X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"
StrokeDashArray="2 2" StrokeThickness="1" />
</local:NoSizeDecorator>
</StackPanel>
</ScrollViewer>
This works perfectly
You may put a very long Line in a left-aligned Canvas with zero Width and ClipToBounds set to false.
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel>
<Button Width="400" Height="50" VerticalAlignment="Top" Margin="10" />
<Canvas HorizontalAlignment="Left" Width="0" ClipToBounds="False">
<Line Stroke="Black" StrokeDashArray="2 2" X2="10000"/>
</Canvas>
</StackPanel>
</ScrollViewer>

Creating a sidebar - flyout like Windows desktop app in WPF

what i am trying to do is create a Desktop application in WPF whose UI is such that a small icon will remain fixed in the center of the left edge of screen and on click(or maybe hover) will slide open a sidebar(like the google desktop bar) running along the left edge of the screen (fixed position, cannot be moved).
do note that what i'm asking for might be like an appbar but i do not want the desktop icons along the left edge to be moved as it happens with an appbar i.e. i do not want it to hog up the desktop spacce....can anyone please suggest me a way out ??
I have implemented a partial solution using this, but i cant get the slide animation and fixed position to workout
Something like this could work:
then of course you could create a slide in animation for the sidebar. This shows (partial) transparency and the switching principle.
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None" Topmost="True" WindowState="Maximized"
AllowsTransparency="True" Background="Transparent">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Name="rect" Width="100" VerticalAlignment="Stretch" Fill="#99000000" Visibility="Collapsed" />
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Width="32" Height="32" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Right" Background="White" Click="Button_Click">></Button>
</Grid>
</Window>
C#:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (rect.Visibility == System.Windows.Visibility.Collapsed)
{
rect.Visibility = System.Windows.Visibility.Visible;
(sender as Button).Content = "<";
}
else
{
rect.Visibility = System.Windows.Visibility.Collapsed;
(sender as Button).Content = ">";
}
}
Based on this answer and more answers on this site I made a side bar, I liked the result so i made a repo.
https://github.com/beto-rodriguez/MaterialMenu
you can install it from nuget too.
here is an example
<materialMenu:SideMenu HorizontalAlignment="Left" x:Name="Menu"
MenuWidth="300"
Theme="Default"
State="Hidden">
<materialMenu:SideMenu.Menu>
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<StackPanel Orientation="Vertical">
<Border Background="#337AB5">
<Grid Margin="10">
<TextBox Height="150" BorderThickness="0" Background="Transparent"
VerticalContentAlignment="Bottom" FontFamily="Calibri" FontSize="18"
Foreground="WhiteSmoke" FontWeight="Bold">Welcome</TextBox>
</Grid>
</Border>
<materialMenu:MenuButton Text="Administration"></materialMenu:MenuButton>
<materialMenu:MenuButton Text="Packing"></materialMenu:MenuButton>
<materialMenu:MenuButton Text="Logistics"></materialMenu:MenuButton>
</StackPanel>
</ScrollViewer>
</materialMenu:SideMenu.Menu>
</materialMenu:SideMenu>

How to implement Camera app style photo strip on WP7?

I'm running into a number of problems creating an effect very similar to the photo strip in the Camera app.
All I want to do is display a row of grids that each have the same dimensions as the screen (whether in portrait or landscape). Already, I had to do something hacky and create dependency properties that the grids width and height properties bind to to maintain the aspect ratio.
And this works fine. But when I create a StackPanel for my strip and implement my navigation (or just zoom back with the z-index transform) I see that my StackPanel can't display larger than the screen dimensions (it's clipped to the size of just one grid). I thought I found a post describing this issue but I can't find it now - please post if you know which post I'm thinking of or if you know more about this limitation.
The only workaround I've found is to use a ScrollViewer, which is absolutely not the behavior I want, but it allows the StackPanel to be wider than the screen.
My real problem is with the ScrollViewer behavior - because I need to hop from grid to grid (just like the photo strip does) instead of freely scrolling, and as far as I can tell the HorizontalOffset is not an animatable property. I can force it to animate by calling ScrollToHorizontalOffset every 15 milliseconds, basically implementing my own easing effect manually. This seems like a huge hack, and the behavior is very glitchy (either I'm not getting the ManipulationCompleted event every time I expect it - at the end of every swipe action - or the built in inertia physics of ScrollViewer is interfering with my effect).
Does anyone know better workarounds for the issues I've run into, or a completely different way to get the experience of the Camera Photo strip in Silverlight?
I have considered using the Pivot control, but it isn't quite what I want (if I wanted each item to animate out completely before the next one comes in, instead of appearing to be all attached to one strip, there should be less constraining ways to achieve that). More importantly, the strip is just one of many effects I want to be able to do dynamically. I'd like to alternately have a CoolIris-like 3d-tilt, or a FlipPad style page turn. I believe if I could get my current setup working nicely it would be easy to implement these other effects (as themable transitions). Committing to a control like Pivot won't get me any closer to that vision.
Here is my XAML:
<Grid x:Name="LayoutRoot" Background="Transparent" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top">
<ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Margin="0,0,0,-31" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left">
<Grid x:Name="Slide0" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo0" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide1" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo1" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
<Grid x:Name="Slide2" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" Background="#FFCCCCCC">
<Image x:Name="Photo2" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="UniformToFill"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
It turns out the setup I described works pretty well if I just prevent the ScrollViewer from getting manipulated directly by the user and position it manually. This eliminates the physics effects that were causing most of the glitchiness I mentioned.
XAML
<ScrollViewer x:Name="SlideScroller" VerticalScrollBarVisibility="Disabled" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" ScrollViewer.HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel x:Name="SlidePanel" Orientation="Horizontal" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" VerticalAlignment="Top" HorizontalAlignment="Left">
</StackPanel>
</ScrollViewer>
<Rectangle x:Name="ScrollInterceptRect" Margin="0,0,0,-31" Width="{Binding RealWidth, ElementName=phoneApplicationPage}" Height="{Binding RealHeight, ElementName=phoneApplicationPage}" HorizontalAlignment="Left" VerticalAlignment="Top">
Codebehind
public MainPage()
{
InitializeComponent();
ScrollInterceptRect.MouseLeftButtonUp += new MouseButtonEventHandler(ScrollInterceptRect_MouseLeftButtonUp);
ScrollInterceptRect.MouseLeftButtonDown += new MouseButtonEventHandler(ScrollInterceptRect_MouseLeftButtonDown);
ScrollInterceptRect.MouseMove += new MouseEventHandler(ScrollInterceptRect_MouseMove);
}
//...
NavigationIndices navigationIndices = new NavigationIndices();
readonly double swipeThreshold = 80.0;
SwipeDirection swipeDirection;
bool tapCancelled;
Point swipeDelta;
Point swipeStartPosition;
double startScrollOffsetX;
void SlideScroller_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
swipeStartPosition = e.GetPosition(this);
startScrollOffsetX = SlideScroller.HorizontalOffset;
}
void ScrollInterceptRect_MouseMove(object sender, MouseEventArgs e)
{
Point touchPosition = e.GetPosition(this);
swipeDelta = new Point() { X = swipeStartPosition.X - touchPosition.X, Y = swipeStartPosition.Y - touchPosition.Y };
SlideScroller.ScrollToHorizontalOffset(startScrollOffsetX + swipeDelta.X);
// swipe right
if (swipeDelta.X > swipeThreshold)
{
swipeDirection = SwipeDirection.Left;
tapCancelled = true;
}
// swipe left
else if (swipeDelta.X < -swipeThreshold)
{
swipeDirection = SwipeDirection.Right;
tapCancelled = true;
}
}
void ScrollInterceptRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (swipeDirection == SwipeDirection.Left && navigationIndices.X < photos.Count - 1 && photos[navigationIndices.X] != null)
{
navigationIndices.X++;
}
// only go back when you aren't already at the beginning
else if (swipeDirection == SwipeDirection.Right && navigationIndices.X > 0)
{
navigationIndices.X--;
}
if (!tapCancelled)
{
// handle tap
}
else
{
animateScrollViewerToCurrentPhoto();
}
}
This is simplified a bit for clarity (I also use vertical swipe for something in my app and I omitted how I'm animating the ScrollViewer - probably worthy of it's own post).
I'd love to hear any improvements you can offer to this, or suggestions on better ways to implement it altogether. Perhaps extending the Panel Class or as a custom Behavior. Thoughts?

Dynamic Clipping Width in Silverlight Within Canvas

Why does this throw an error and how can I fix... I need to set the clipping rect to be dynamic.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="42"/>
<ColumnDefinition x:Name="ListBoxContainer" Width="*"/>
<ColumnDefinition Width="42"/>
</Grid.ColumnDefinitions>
<Canvas>
<Button x:Name="btnGalleryLeft"
Click="btnGalleryLeftClick"
Style="{StaticResource GalleryNavigationLeft}"
Canvas.Left="7"
Canvas.Top="50" />
</Canvas>
<Canvas Grid.Column="1" x:Name="ListboxWrapper">
<Canvas.Clip>
<RectangleGeometry>
<RectangleGeometry.Rect>
<Rect X="0" Y="0"
Width="{Binding ElementName=ListBoxContainer, Path=Width}"
Height="{Binding ElementName=ListBoxContainer, Path=Height}"/>
</RectangleGeometry.Rect>
</RectangleGeometry>
</Canvas.Clip>
<ListBox x:Name="ListBox1"
Margin="15, 18, 15, 0"
Style="{StaticResource GalleryListBoxStyle}"
ItemsSource="{Binding DocItemCollection}"
SelectionChanged="ListBox_SelectionChanged"
MouseLeftButtonUp="ListBox_MouseLeftButtonUp"
Canvas.Top="0"
Canvas.Left="0"
/>
</Canvas>
<Canvas Grid.Column="2">
<Button x:Name="btnGalleryRight"
Click="btnGalleryRightClick"
Style="{StaticResource GalleryNavigationRight}"
Margin="0, 0, 7, 0"
Canvas.Top="50" />
You can still use RectangleGeometry as clipping area. Just subscribe to the Loaded event, and in that create a new RectangleGeometry
void control_Loaded(object sender, RoutedEventArgs e)
{
LayoutRoot.DataContext = this;
Rect rect = new Rect(0, 0, yourWidth, yourHeight);
RectangleGeometry reo = new RectangleGeometry();
reo.Rect = rect;
this.canvas.Clip = reo;
}
Just to add little information
In addition, opacity and clip property settings are handled by the
composition thread. However, if an Opacity mask or non-rectangular
clip is used on the animated object, these operations will be passed
to the UI Thread. This means that even if the clip region is a
rectangular shape but uses the PathGeometry the operations will be
passed to the UI thread. So make sure to always use the
RectangleGeometry for clipping paths if possible.
Solution finally.... after much cursin and swearing. If only everything was as stright fwd as in CSS (overflow bloody hidden property).
Front-end:
<Canvas Grid.Column="1" x:Name="ListboxWrapper" Background="Black">
<ScrollViewer Background="Red"
FlowDirection="LeftToRight"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
x:Name="ScrollViewerClipper">
<Canvas x:Name="CarouselContainer">
<gallery:ImageCarousel x:Name="carousel" />
</Canvas>
</ScrollViewer>
Back-end:
public GalleryPanel()
{
InitializeComponent();
LayoutRoot.SizeChanged +=new SizeChangedEventHandler(LayoutRoot_SizeChanged);
}
private void LayoutRoot_SizeChanged(object s, SizeChangedEventArgs e)
{
ScrollViewerClipper.Width = ListboxWrapper.ActualWidth;
ScrollViewerClipper.Height = ListboxWrapper.ActualHeight;
}
I think you are over complicating it. Binding to Width/Height of ColumnDefinition not going to work. I'd simply create behavior that would subscribe to SizeChanged event and set clipping based on ActualWidth[Height].

XAML Path sizing and positioning

I am trying to design a template for a TabItem using paths and rectangles. The sides of the tab layout are paths to accommodate curves in the design. I am having a problem with getting the sides to line up/resize correctly. Here's my XAML:
<StackPanel Orientation="Horizontal">
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 97.1985,101.669L 104.824,95.0005C 105.574,94.3338 106.921,93.8627 107.824,93.9171L 107.824,101.667L 97.1985,101.669 Z "/>
<Grid>
<Rectangle Grid.Column="1" Fill="#FF000000"/>
<ContentControl Grid.Column="1" x:Name="HeaderTopSelected" FontSize="{TemplateBinding FontSize}" Foreground="{TemplateBinding Foreground}" IsTabStop="False" Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</Grid>
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 118.714,101.678L 111.088,95.0097C 110.338,94.343 108.991,93.8719 108.088,93.9264L 108.088,101.676L 118.714,101.678 Z "/>
</StackPanel>
(I apologize for the lack of line breaks. I'm new to StackOverflow and don't know how to insert them, nor do I have the time to figure it out :D)
The code snippet posted almost works: The side paths are the correct size, but they do not display in a line, they overlap behind the rectangle/next element. If I set a fixed width they work as well, but I can't set the width as fixed, they need to be fluid in case the content of the tab exceeds the basic height.
This is an idea of what I would like to get
The sides (paths) grow uniformally based on the height of the ContentControl
Take 3 (now we know what the requirement is):
Basically to get the desired effect you need your 2 side parts to resize their width if their height changes, in order to keep a fixed aspect ratio. This will force the parent container to expand as the actual content gets taller and the sides get taller to match. none of the containers (including ViewBox) work exactly this way.
You could use a custom container to do this, but the preferred solution would be to create a behaviour that retains its object's aspect ratio on height changes. We will call it a FixedAspectBehavior:
using System.Windows;
using System.Windows.Interactivity;
namespace SilverlightApplication1
{
public class FixedAspectRatioBehavior : TargetedTriggerAction<FrameworkElement>
{
public double AspectRatio { get; set; }
protected override void OnAttached()
{
base.OnAttached();
FrameworkElement element = this.AssociatedObject as FrameworkElement;
if (element != null)
{
AspectRatio = element.Width/element.Height;
element.SizeChanged += new SizeChangedEventHandler(element_SizeChanged);
}
}
void element_SizeChanged(object sender, SizeChangedEventArgs e)
{
FrameworkElement element = AssociatedObject as FrameworkElement;
element.Width = element.Height * AspectRatio;
}
protected override void Invoke(object parameter)
{
}
}
}
The layout requires some work as self resizing elements (of type path) do some very weird things depending on their parent container. I had to use ViewBoxes as the parent of the paths, combined with the behaviours to get the desired result:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Viewbox>
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 97.1985,101.669L 104.824,95.0005C 105.574,94.3338 106.921,93.8627 107.824,93.9171L 107.824,101.667L 97.1985,101.669 Z " UseLayoutRounding="False" HorizontalAlignment="Left">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<local:FixedAspectRatioBehavior/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Path>
</Viewbox>
<Grid Width="Auto" Background="#FFFF0D0D" Grid.ColumnSpan="1" Grid.Column="1">
<Rectangle Grid.Column="1" Fill="#FFD21F1F"/>
<ContentControl Grid.Column="1" x:Name="HeaderTopSelected" FontSize="{TemplateBinding Control.FontSize}" Foreground="{TemplateBinding Control.Foreground}" IsTabStop="False" Cursor="{TemplateBinding FrameworkElement.Cursor}" HorizontalAlignment="{TemplateBinding FrameworkElement.HorizontalAlignment}" VerticalAlignment="{TemplateBinding FrameworkElement.VerticalAlignment}"/>
<TextBlock TextWrapping="Wrap" FontSize="16"><Run Text="This is just a very string to see "/><LineBreak/><Run Text="what happens when we get to a size where the container should get larger than the default size"/></TextBlock>
</Grid>
<Viewbox Grid.Column="2">
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 118.714,101.678L 111.088,95.0097C 110.338,94.343 108.991,93.8719 108.088,93.9264L 108.088,101.676L 118.714,101.678 Z " UseLayoutRounding="False" d:LayoutOverrides="VerticalAlignment">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<local:FixedAspectRatioBehavior/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Path>
</Viewbox>
</Grid>
Take 1 (obsolete now, as is 2 below):
The width of a path does not push along items in a stack panel. In that respect it's width is useless except to scale the item.
To get the effect you wanted, group each path into a grid. The size problem then goes away.
Apologies for turning your rectangle horrible red to show it clearly :)
XAML below:
<StackPanel Orientation="Horizontal" Width="Auto">
<Grid>
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 97.1985,101.669L 104.824,95.0005C 105.574,94.3338 106.921,93.8627 107.824,93.9171L 107.824,101.667L 97.1985,101.669 Z " UseLayoutRounding="False" d:LayoutOverrides="Width"/>
</Grid>
<Grid Width="100" Background="#FFFF0D0D">
<Rectangle Grid.Column="1" Fill="#FFD21F1F"/>
<ContentControl Grid.Column="1" x:Name="HeaderTopSelected" FontSize="{TemplateBinding Control.FontSize}" Foreground="{TemplateBinding Control.Foreground}" IsTabStop="False" Cursor="{TemplateBinding FrameworkElement.Cursor}" HorizontalAlignment="{TemplateBinding FrameworkElement.HorizontalAlignment}" VerticalAlignment="{TemplateBinding FrameworkElement.VerticalAlignment}"/>
</Grid>
<Grid>
<Path Stretch="UniformToFill" Fill="#FF000000" Data="F1 M 118.714,101.678L 111.088,95.0097C 110.338,94.343 108.991,93.8719 108.088,93.9264L 108.088,101.676L 118.714,101.678 Z " UseLayoutRounding="False" d:LayoutOverrides="Width"/>
</Grid>
</StackPanel>
Take 2 (also obsolete now, see take 3 at the top):
If you require fixed end widths, use a grid instead of a stack panel (XAML below).
If you require something else, please provide a couple of screen shots of the desired effect.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Path Stretch="Fill" Fill="#FF000000" Data="F1 M 97.1985,101.669L 104.824,95.0005C 105.574,94.3338 106.921,93.8627 107.824,93.9171L 107.824,101.667L 97.1985,101.669 Z " UseLayoutRounding="False" d:LayoutOverrides="Width"/>
<Grid Width="Auto" Background="#FFFF0D0D" Grid.ColumnSpan="1" Grid.Column="1">
<Rectangle Grid.Column="1" Fill="#FFD21F1F"/>
<ContentControl Grid.Column="1" x:Name="HeaderTopSelected" FontSize="{TemplateBinding Control.FontSize}" Foreground="{TemplateBinding Control.Foreground}" IsTabStop="False" Cursor="{TemplateBinding FrameworkElement.Cursor}" HorizontalAlignment="{TemplateBinding FrameworkElement.HorizontalAlignment}" VerticalAlignment="{TemplateBinding FrameworkElement.VerticalAlignment}" Content="Hello there.... this is a long string to see what happens"/>
</Grid>
<Path Stretch="Fill" Fill="#FF000000" Data="F1 M 118.714,101.678L 111.088,95.0097C 110.338,94.343 108.991,93.8719 108.088,93.9264L 108.088,101.676L 118.714,101.678 Z " UseLayoutRounding="False" d:LayoutOverrides="Width" Grid.Column="2"/>
</Grid>

Resources