How to center 2 elements within a horizontal stackpanel - wpf

I have a stackpanel with a fixed width.
Within the stackpanel, I have two horizontally aligned elements: a textblock and a textbox.
Is it possible to align these two elements, such they appear side-by-side, but centered within the stackpanel?
Here is my code so far:
<StackPanel Orientation="Horizontal" Width="17cm">
<TextBlock Text="Invoice Nr:"/>
<TextBox Width="2cm" />
</StackPanel>

With StackPanel it would be difficult to achieve, but with Grid it can be done by setting HorizontalAlignment and Grid.Column on the children like below:
<Grid Width="17cm" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Right" Text="Invoice Nr:"/>
<TextBox Grid.Column="1" HorizontalAlignment="Left" Width="2cm" />
</Grid>

You could probably put the two controls within another container, and then center that container horizontally. Something like this:
<StackPanel Orientation="Horizontal" Width="17cm">
<StackPanel HorizontalAlignment="Center">
<TextBlock Text="Invoice Nr:"/>
<TextBox Width="2cm" />
</StackPanel>
</StackPanel>

Related

How to get text-alignment and stretch in the dockpanel correct?

In a xaml DataTemplate I have
<DockPanel >
<StackPanel DockPanel.Dock="Right" Orientation="Vertical">
<Button />
<Button />
</StackPanel>
<Grid VerticalAlignment="Stretch/Center">
<TextBlock HorizontalAlignment="Stretch"
TextAlignment="Right"
Text="{Binding ...}"
VerticalAlignment="Stretch"
DockPanel.Dock="Right"/>
</Grid>
</DockPanel>
The dockpanel is horizontal, i.e. stackpanel is to the right, the grid to the left.
I need the two buttons to stretch each to 50% of the vertical space of height of the dockpanel. How do I do it?
A schematic picture of want I try to achieve. The controls are meant to stretch to the borders as much as possible.
I need the textblock to stretch to 100% of the vertical space of height of the dockpanel and it's text to be vertically centered.
It doesn't work bc. in the case of Strech I get the 100% space but the text is vertically topped and in the case of Center the textblock is not stretched.
A TextBlock cannot both "stretch to 100% of the vertical space" and also be vertically centered. It's just text after all.
You should be able to get rid of the StackPanel and replace the DockPanel with a 2x2 Grid. Something like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Column="1" Content="Button1" />
<Button Grid.Column="1" Content="Button2" Grid.Row="1" />
<Grid Grid.RowSpan="2">
<TextBlock Grid.RowSpan="2"
TextAlignment="Right"
Text="Text..."
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</Grid>

TextBlock not wrapping in Grid

I have the following XAML which is meant to show an Image and two TextBlocks on top of eachother beside it:
<StackPanel Orientation="Horizontal" >
<Image Source="{Binding CoverArt}" Height="150" />
<StackPanel Orientation="Vertical">
<StackPanel>
<TextBlock FontSize="30" Text="{Binding Title}" TextWrapping="Wrap" />
</StackPanel>
<Grid Width="auto">
<TextBlock FontSize="22" Text="{Binding Summary}" TextWrapping="Wrap" />
</Grid>
</StackPanel>
</StackPanel>
My problem is getting the text to wrap. I've tried using a Grid and assigning the columns' width but it didn't work. Neither did setting the width values to auto. The only thing that works is hard-coding the width, but I do not want that. Thanks.
A Stackpanel will stretch to the size of its content, so it's not what I would use. Use a grid, as explained in the following posts:
TextBlock TextWrapping not wrapping inside StackPanel
Text in StackPanel doesn't wrap (wp7)
TextBlock inside stackpanel does not wrap text
A quick comparison:
Before with stackpanel
After with one grid (You might want to rearrange the elements a bit)
The code for the last segment:
<pre>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Fill="red" Width="150" Height="150" />
<StackPanel Grid.Column="1" Orientation="Vertical">
<StackPanel>
<TextBlock FontSize="30" Text="basdljhba dnaiks d., kasndca casn oiäc cas lkcnaso ca dxjwöbdq wkjöbdqw dkjwqb " TextWrapping="Wrap" />
</StackPanel>
<Grid Width="auto">
<TextBlock FontSize="22" Text="dewdewdewdewdewewd" TextWrapping="Wrap" />
</Grid>
</StackPanel>
</Grid>
Did you try setting the width of the columns to fractions instead? width="2*" That will give you some boundaries without a pixel set size. Some way or another you need to set a constraint for the container. If you have two columns and no size is set they will get 50% each. 2* will make give that column 2/3 of the total column with, see example below.

Set height and width of controls wihtin window size wpf

I have a following xaml file
<Window x:Class="NodeXL_Graph_Drawer.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:controls="clr-namespace:Technewlogic.Samples.WpfModalDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="NodeXL Graph" xmlns:my="clr-namespace:Smrf.NodeXL.Visualization.Wpf;assembly=Smrf.NodeXL.Control.Wpf" Loaded="Window_Loaded">
<Grid>
<Grid x:Name="ModalDialogParent" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="col1"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<my:NodeXLControl Name="nodeXLControl1" HorizontalAlignment="Left" EdgeSelectedColor="Red" VertexSelectedColor="Red" ShowVertexToolTips="True" VertexClick="nodeXLControl1_VertexClick" SelectionChanged="nodeXLControl1_SelectionChanged" MouseMode="Select" MouseAlsoSelectsIncidentEdges="False" ContextMenuOpening="nodeXLControl1_ContextMenuOpening" GraphLaidOut="nodeXLControl1_GraphLaidOut">
</my:NodeXLControl>
</StackPanel>
<!--<ComboBox Height="23" Margin="39,12,119,0" Name="comboBox1" VerticalAlignment="Top" SelectionChanged="comboBox1_SelectionChanged" />-->
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<StackPanel Grid.Column="2">
<toolkit:DataGrid AutoGenerateColumns="True" Margin="0,62,0,0" Name="grdGraphDetails" ItemsSource="{Binding GraphDetail}" IsReadOnly="True"
HorizontalAlignment="Right" Width="109" MouseLeftButtonUp="grdGraphDetails_MouseLeftButtonUp"
SelectedValuePath="Key" Height="179" />
</StackPanel>
</Grid>
<controls:ModalDialog x:Name="ModalDialog"></controls:ModalDialog>
<controls:ModalDialog1 x:Name="ModalDialog1"></controls:ModalDialog1>
</Grid>
Here i have two controls NodeXlControl1 and Datagrid1 on page seprated by grid seprator. when window loads NodeXlControl1 does not come within the grid column width and height. i want nodexlcontrol1 should be shown with in the grid column width and height. and i if it goes beyond the limits of width and height of column, scroll bar should come.
If your my:NodeXLControl internally has some scroll viewer (like some ItemsControl or ScrollViewer based child) then simply wrapping my:NodeXLControl in a Grid would do the trick.
StackPanel expands to overflow the children. Grid expands to outer's container's availability of space.
<Grid>
<my:NodeXLControl ... />
Should do the trick.
But if you my:NodeXLControl has no scroll viewer in it then you would need to wrap it inside one and provide absolute width or height to it or wrap it inside a Grid for it to bound to its avilable space and show scrollbars accordingly.
e.g.
<Grid>
<ScrollViewer ...>
<my:NodeXLControl ...>

UserControl Expand Vertically when Window is expanded

I'm having trouble getting my UserControl to expand vertically when my window is expanded.
My UserControl currently sits inside a ItemsControl which is stretching correctly by setting the VerticalAlignment="Stretch" property on the ItemsControl.
I add the following UserControl to the ItemsControl:
<UserControl MinWidth="930">
<Grid VerticalAlignment="Stretch" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="730*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="400" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Grid.Column="1" Grid.ColumnSpan="1" Grid.RowSpan="2" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Pink" LastChildFill="True">
<ItemsControl Name="itemPanelOverview" Grid.Column="1" Background="Black" Margin="0"/>
</DockPanel>
</Grid>
</UserControl>
The UserControl is called in an ItemsControl inside of a TabControl like so:
<TabItem>
<TabItem.Header>
HEADER EG
</TabItem.Header>
<ItemsControl Name="contentItems" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" Background="Blue">
<Grid Height="35" Background="{DynamicResource GrayMenuGradient}" >
<Image Source="..." Stretch="None" />
<TextBlock Text="{Binding WelcomeMessage}" />
</Grid>
</ItemsControl>
</TabItem>
It appears that the ItemsControl (contentItems) is stretching as expected, as I can see the blue background stretching correctly.
I haven't set the height for this UserControl anywhere other than the Row Definitions. Is there something I'm missing?
There are at least two aspects at play here:
The first is that when you have items in an ItemsControl, each item is actually inside an ItemContainer, so it is the container that you want to stretch.
You can design the container by declaring an ItemContainerTemplate for your ItemsControl: http://msdn.microsoft.com/en-us/library/system.windows.controls.itemcontainertemplate.aspx
The second consideration is the ItemsPanelTemplate, which determines into what type of panel the items are placed. The ability of the items in the ItemsControl to fill up the available space is going to depend on the type of container as much as on the type of ItemContainer. For example, if you use a StackPanel for the ItemsPanelTemplate, it won't fill up available space because StackPanel grows and shrinks according to its contents. A DockPanel could potentially work, but only the last child would grow to fill available space. Perhaps a UniformGrid could do the trick.

Silverlight 4: StackPanel doesn't resize, when content gets more narrow

I am using Silverlight 4 with Blend 4.
I have a (horizontal) stackpanel that includes some TextBoxes and a Button. The stackpanel is set to stretch to the size that the content uses. The TextBoxes are on autosize too.
When I add text to the Textboxes, the textbox size grows and the stackpanel grows too. So far so good.
When I remove text from the textboxes, the textbox size shrinks (as excepted), but the stackpanel size doesn't.
Is there any trick to make the stackpanel change size, when the content (textboxes) getting smaller?
Thanks in advance,
Frank
Here is the XAML for the UserControl:
<Grid x:Name="LayoutRoot">
<StackPanel x:Name="StackPanelBorder" Orientation="Horizontal">
<TextBox x:Name="TextBoxCharacteristicName" TextWrapping="Wrap" Text="Tex">
</TextBox>
<TextBox x:Name="TextBoxSep" TextWrapping="Wrap" Text="=" IsReadOnly="True">
</TextBox>
<Button x:Name="ButtonRemove" Content="-" Click="ButtonAddOrRemove_Click">
</Button>
</StackPanel>
</Grid>
If you want your StackPanel to resize horizontally with the items inside of it, you will need to change the HorizontalAlignment from the default value of "Stretch" to something else.
By default, the stackpanel stretches to fill the entire space of its parent control because the HorizontalAlignment is set to stretch. This makes it difficult for it to grow and shrink in size.
You will want to set the HorizontalAlignment to "Left", "Right" or to "Center". Then the stackpanel will only be as wide as the items inside of it. But choose wisely, because the stackpanel will then dock to that position inside of its parent control.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
Note: If this isn't fixing your problem, then you have a problem with the Parent Control and not your StackPanel.
MSDN website for HorizontalAlignment
You would be better off using a Grid for this. Just create a Grid with 3 auto columns and it will size to fit the content.
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="TextBoxCharacteristicName" TextWrapping="Wrap" Text="Tex" Grid.Column="0"/>
<TextBox x:Name="TextBoxSep" TextWrapping="Wrap" Text="=" IsReadOnly="True" Grid.Column="1"/>
<Button x:Name="ButtonRemove" Content="-" Click="ButtonAddOrRemove_Click" Grid.Column="2"/>
</Grid>
In most cases, you are much better off using a Grid. The StackPanel is a useful control, but I often feel it is overused.
I've modified your code as below. Please check.
<Grid x:Name="LayoutRoot">
<ScrollViewer x:Name="PageScrollViewer" >
<toolkit:WrapPanel x:Name="mywrapPanel" Orientation="Vertical" Width="{Binding ActualWidth, ElementName=LayoutRoot}">
<TextBox x:Name="TextBoxCharacteristicName" TextWrapping="Wrap" Text="Tex" Width="{Binding ActualWidth, ElementName=mywrapPanel}">
</TextBox>
<TextBox x:Name="TextBoxSep" TextWrapping="Wrap" Text="=" IsReadOnly="True" Width="{Binding ActualWidth, ElementName=mywrapPanel}">
</TextBox>
<Button x:Name="ButtonRemove" Content="-" Click="ButtonAddOrRemove_Click" HorizontalAlignment="Right" Width="80" Margin="2">
</Button>
</toolkit:WrapPanel>
</ScrollViewer>
</Grid>
If you use Horizontal in Orientation of WrapPanel, you may have to use the Height property binding with ActualHeight. "toolkit" can be included in header as xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
Hope this helps.
you need something like:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
Also, I don't think that have a textbox which stretches is a good idea, unless it is a requirement. You should specify the width on the textbox so it doesn't stretch.
Also, if the above solution doesn't work then you should post your xaml for letting us see the document outline.

Resources