Can i use stack panel to design the following layout - wpf

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>

Related

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

Why is expander designed to hold one content only?

I'm trying to add few contents to expander however, it throws following error
<Expander Name="myExpander" Background="Tan"
HorizontalAlignment="Left" Header="my expander"
ExpandDirection="Down" IsEnabled="True" Width="100" IsExpanded="True">
<Rectangle Width="10" Height="10" Fill="Red"/>
<Rectangle Width="10" Height="10" Fill="blue"/>
</Expander>
The object 'Expander' already has a child and cannot add 'Rectangle'. 'Expander' can accept only one child.
I thought I can use Expander as a container holding few elements but it seems it only can hold on to one! any work around?
Thank you.
Amit
This is the case with many elements. You would nest a panel, such as a Grid or StackPanel, in order to layout multiple children.
Example:
<Expander Name="myExpander" Background="Tan"
HorizontalAlignment="Left" Header="my expander"
ExpandDirection="Down" IsEnabled="True" Width="100" IsExpanded="True">
<StackPanel>
<Rectangle Width="10" Height="10" Fill="Red"/>
<Rectangle Width="10" Height="10" Fill="blue"/>
</StackPanel>
</Expander>
This gives you unlimited flexibility on how to layout the children.
Expander is a ContentControl, which means it holds a single piece of content. Most containers are this way.
The way to handle this is to put your rectangles within their own panel, such as a Grid, and make the Grid the content of the Expander.
<Expander Name="myExpander" Background="Tan"
HorizontalAlignment="Left" Header="my expander"
ExpandDirection="Down" IsEnabled="True" Width="100" IsExpanded="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Width="10" Height="10" Fill="Red"/>
<Rectangle Grid.Column="1" Width="10" Height="10" Fill="blue"/>
</Grid>
</Expander>
You can use any layout mechanism you want here - such as a Canvas, Grid, StackPanel, WrapPanel, etc.
Be careful nesting an expander in a window where you already have a grid
remember to use Header="texthere" instead of Content=
because the expander content will conflict with the grid content

How to leave margin between elements in the stack panel

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>

Fill panel with rectangles

I want to fill a panel with rectangles, and when the panel is resized, the rectangles should resize as well.
Why doesn't the following work?
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle Fill="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Green" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Blue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</StackPanel>
</Page>
I would prefer not to use a Grid because of the pain of adding/removing columns and rearranging the children. (I was looking forward to StackPanel because if I wanted to add a yellow Rectangle at the beginning, I just declare it. I don't have to re-order the others by hand.)
Or a UniformGrid:
<UniformGrid Columns="1">
<Rectangle Fill="Red"/>
<Rectangle Fill="Green"/>
<Rectangle Fill="Blue"/>
</UniformGrid>
You're using a StackPanel whose behavior is to take the size of its children. Use a Grid which takes the whole available size:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Fill="Red" Grid.Row="0" />
<Rectangle Fill="Green" Grid.Row="1" />
<Rectangle Fill="Blue" Grid.Row="2" />
</Grid>

Display a line after a TextBlock in Silverlight

I'm working on a dataform in Silverlight 4 and would like to group elements by section, with a title for each. The title consists of a TextBlock followed by a horizontal line. The line runs until the edge of the form.
I've tried the following (from this thread: http://forums.silverlight.net/forums/p/77813/183885.aspx), without success:
<StackPanel Orientation="Horizontal"/>
<TextBlock Text="Section title" />
<Line X1="0" Y1="0" X2="1" Y2="0" Stretch="Fill" Stroke="Black" />
</StackPanel>
Any idea why this isn't working?
Thanks!
How about using Border instead with a height of 1
I was curious about your post, so I tried it for myself. I was unable to get the line to stretch also when using a StackPanel. Although, I was able to get it to work with a Grid:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Section title" HorizontalAlignment="Right" VerticalAlignment="Center" />
<Line Grid.Row="0" Grid.Column="1" X1="0" Y1="0" X2="1" Y2="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" />
</Grid>

Resources