How to leave margin between elements in the stack panel - wpf

I use the stack panel. It looks like every elements inside is stacking tightly. How to leave some margin between them.

Easiest way is to give each item it's own Margin

<StackPanel Grid.Row="1" Orientation="Horizontal">
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" StrokeThickness="5" Margin="5,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" StrokeThickness="5" Width="100" Height="35" Margin="5,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" Margin="5,0,0,0" StrokeThickness="5"/>
</StackPanel>

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>

Is WPF StackPanel freezable

I'm using StackPanel in WPF just for easy layouting horizontally aligned boxes and lines, but it seems the performance of application is getting slower when using StackPanel.
All the Microsoft tutorials seems to talk only about freezing some SolidColorBrush etc. objects, but can StackPanel be freezed after first layout so the CPU doesn't have to layout it all the time, just once?
Or am I just forced to use the very fast Canvas object and layout all the objects inside it one by one?
Example 1: Very easy to layout in designer, but lacks performance:
<StackPanel Height="35" Canvas.Left="49" Canvas.Top="874" Width="395" Orientation="Horizontal">
<TextBox Text="test" Width="65"/>
<Rectangle Stroke="Black" Width="1" />
<TextBox Text="test" Width="55"/>
<Rectangle Stroke="Black" Width="1" />
<TextBox Text="test" Width="75"/>
<Rectangle Stroke="Black" Width="1" />
<TextBox Text="test" Width="35"/>
<Rectangle Stroke="Black" Width="1" />
<TextBox Text="test" Width="95"/>
<Rectangle Stroke="Black" Width="1" />
<TextBox Text="test" Width="65"/>
<Rectangle Stroke="Black" Width="1" />
</StackPanel>
Example 2: Good performance, making layout in designer is a pain:
<Canvas Height="35" Canvas.Left="49" Canvas.Top="914" Width="395">
<TextBox Text="test" Width="65" Height="35"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="65"/>
<TextBox Text="test" Width="55" Canvas.Left="66" Height="35"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="195"/>
<TextBox Text="test" Width="75" Height="35" Canvas.Left="122"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="121"/>
<TextBox Text="test" Width="35" Height="35" Canvas.Left="198"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="197"/>
<TextBox Text="test" Width="95" Height="35" Canvas.Left="234"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="329"/>
<TextBox Text="test" Width="65" Height="35" Canvas.Left="330"/>
<Rectangle Stroke="Black" Width="1" Height="35" Canvas.Left="233"/>
</Canvas>
No, StackPanel is not Freezable, however you mentioned that your GPU is having trouble rendering Animations at 60fps, Try dropping the Animation fps
In you main Windows constructor you can override the defualt framerate for Animations
I usally use 30fps as it is still smooth and users with low-end GFX cards will be able to run your application a lot smotther.
Example:
public MainWindow()
{
InitializeComponent();
Timeline.DesiredFrameRateProperty.OverrideMetadata(typeof(Timeline)
, new FrameworkPropertyMetadata { DefaultValue = 30 }); // 30 = 30fps
}
Give it a try and see if it helps

combine elements on form

I've got two rectangles and an ellipse. How to combine them and use the same animation on new combined element?
<Rectangle Height="100" HorizontalAlignment="Left" Margin="220,235,0,0" Name="rectangle2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="38" Fill="LightGreen" />
<Ellipse Height="23" HorizontalAlignment="Left" Margin="227,269,0,0" Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="24" Fill="Yellow" />
<Ellipse Height="17" HorizontalAlignment="Left" Margin="12,266,0,0" Name="ellipse2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="17" Fill="#FF58FF00" />
If you want fixed size elements, moved relative to each other, then place them in a canvas and use canvas coordinates to position them.
A canvas has a low overhead for rendering as it displays nothing but its child elements, in pixel offsets, and has no complex calculation of margins or rows.
The equivalent of your example is:
<Canvas HorizontalAlignment="Left" Margin="12,235,0,145" Width="246">
<Rectangle Height="100" x:Name="rectangle2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="38" Fill="LightGreen" Canvas.Left="208" />
<Ellipse Height="23" x:Name="ellipse1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="24" Fill="Yellow" Canvas.Left="215" Canvas.Top="34" />
<Ellipse Height="17" x:Name="ellipse2" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="17" Fill="#FF58FF00" Canvas.Top="31" />
</Canvas>
Group into T:Panel.
Usually I'm grouping in Canvas first, then in Viewbox (Fill ot Fit) second.

Vertical aligning content of PathListBox

I have a control containing a PathListBox from Blend SDK (see XAML below). The items inside are of identical width and various height. Currently, the midpoint of the items follow the arc's path (see the picture) i.e. they are clearly vertically arranged 'center'. However, I would like the items 'top' vertically aligned, so their top follows the arc's path. How can I do that?
<Grid x:Name="LayoutRoot">
<ec:PathListBox Margin="160,290,-30,-250">
<ec:PathListBox.LayoutPaths>
<ec:LayoutPath SourceElement="{Binding ElementName=arc}"
Padding="-25" FillBehavior="NoOverlap"
Distribution="Even" Span="0.5"/>
</ec:PathListBox.LayoutPaths>
<Rectangle Fill="#FFF4F4F5" Height="103" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="120" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="140" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="265" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="100" Width="100"/>
<Rectangle Fill="#FFF4F4F5" Height="265" Width="100"/>
</ec:PathListBox>
<ed:Arc x:Name="arc"
ArcThickness="10" ArcThicknessUnit="Pixel" Margin="160,290,-30,-250"
Stretch="None" Stroke="Transparent" StartAngle="-7"
RenderTransformOrigin="0.5,0.5" StrokeThickness="3"
Opacity="0.155" Fill="LightGray">
<ed:Arc.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="1" ScaleX="-1"/>
<SkewTransform AngleY="-17" AngleX="-16"/>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</ed:Arc.RenderTransform>
</ed:Arc>
</Grid>
Just change margins of your rects:
...
<Rectangle Fill="Green" Height="103" Width="100" Margin="0,130,0,0"/>
<Rectangle Fill="Green" Height="120" Width="100" Margin="0,120,0,0"/>
<Rectangle Fill="Green" Height="140" Width="100" Margin="0,140,0,0"/>
<Rectangle Fill="Green" Height="265" Width="100" Margin="0,265,0,0"/>
<Rectangle Fill="Green" Height="100" Width="100" Margin="0,100,0,0"/>
<Rectangle Fill="Green" Height="265" Width="100" Margin="0,265,0,0"/>
...
I'm after trying it myself on Blend4 and it works.

Can i use stack panel to design the following layout

I am wondering If I can use stack panel to get the following layout
one will not be enough, but you can certainly do with two:
<StackPanel Orientation="Vertical">
<BigBoxOnTop />
<StackPanel Orientation="Horizontal">
<SmallBox_1 />
<SmallBox_2 />
<SmallBox_3 />
....
</StackPanel>
</StackPanel>
use margin and padding to place your boxes inside the panels
Yes. The outer one looks like a vertical stackpanel. The smaller boxes (controls or panels) can be placed with explicit margins to lay them out as shown above.
Looks to me like you need to nest a gridpanel inside each of the vertical stack panel's top and bottom halves... but I'm just a beginner at WPF.
try something like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle Fill="White" Stroke="Black" Margin="5" StrokeThickness="2"/>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" StrokeThickness="5" Margin="25,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" StrokeThickness="5" Width="100" Height="35" Margin="20,0,0,0"/>
<Rectangle Fill="White" Stroke="Black" Width="100" Height="35" Margin="25,0,0,0" StrokeThickness="5"/>
</StackPanel>
</Grid>

Resources