TabControl Width Height issue - wpf

I'm using a TabControl with no Height and Width specified.
Actually, the height of the TabControl take the height of the current tab.
I don't want the TabControl auto adjust it size. I want it take the size (Heigth and Width) of the biggest tab.
How can I do that ?
Thanks.

Because some people asked for the actual xaml, here is something that worked for me. It is based on the tips from #FWillem, #Floc and the others, so all credit goes to them.
<TabControl>
<TabItem Header="SomeTab1">
<Grid Name="MasterTabGrid">
<!-- Some content -->
</Grid>
</TabItem>
<TabItem Header="SomeTab2">
<Grid Height="{Binding ElementName=MasterTabGrid, Path=ActualHeight}" >
<!-- Some other content -->
</Grid>
</TabItem>
</TabControl>

The size of your TabControl will be being set by its parent container control, which is responsible for the layout of its children, and will specify default values for many layout properties.
If, for example, you place the TabControl inside a (vertical) StackPanel, you'll find that it takes the minimum vertical space that it can. If you have a Grid around your tabs, they'll fill the available space.
Alternatively, you can manually set VerticalAlignment="Top" with other containers, and this will typically override the behaviour you're seeing. (Most likely your layout panel is defaulting this to Stretch.)

Related

TextTrimming in panel in ScrollViewer

I am trying to set up an element within a WPF application, but cannot get the TextTrimming on the TextBlocks to work properly. This is within a ScrollViewer. I am currently using a DockPanel as the inner container.
I have searched quite a bit, but found no questions addressing this issue.
The XAML for the container:
<Grid>
<ScrollViewer>
<DockPanel Name="listedCharacters" LastChildFill="False"></DockPanel>
</ScrollViewer>
</Grid>
The XAML for the child elements (added by code):
<UserControl …>
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding FullName}" TextTrimming="CharacterEllipsis" />
</Grid>
</UserControl>
The first problem is that whether I use the DockPanel or a StackPanel, as the inner container, the child element's width appears to be dictated by its content (the TextBlocks) rather than constrained by the parent ScrollViewer.
The effect I want is for the ellipsis to truncate each TextBlock's content when the Window's grid column (not shown in code) is narrower than the bound text. Basically, a list that scrolls vertically when needed, and trims horizontally (which I thought would have been sufficiently common that the answer would be out there; alas, no).
I believe I need to use my own UserControl for this, as there is a lot more going on than shown her; right-click menus on the item in the list, etc.
The secondary issue, iff the optimal panel to use is the DockPanel, how to apply the DockPanel.Dock="Top" through code (C#) when the elements are dynamically added? Again, I cannot find anything that appears to explain this. (I know it is probably in the wrong place in the sample code above.)

WPF ContentControl width grows but doesn't shrink when wrapped in a ScrollViewer

I'm trying to figure out how to make my ContentControl to correctly scroll Horizontally (Vertically its fine at the moment). By correctly i mean i would like to see the content to stretch (expand infinitely) while having minimum sizes to which a scrollbar would appear in order for the content not to overflow behind the ContentControl's area, so here's a quick introduction:
The main window is structured in this way:
Grid (2 columns of .3* and .7*)
Border
Grid (7 rows, one set to * where ContentControl is)
ScrollViewer with StackPanel (purely for test) wrapping a ContentControl that has Auto Width
ContentControl's Template:
Grid (Width set to UserControl's ActualWidth, 6 rows with one set to Auto where ItemsControl go
ItemsControl that describes an ItemTemplate of a type DataTemplate which contains a Grid inside of which i have a DataGrid
The actual problem is that the ContentControl grows as you resize the window, but does not shrink with window resize.
Main View XAML (truncated for clarity):
<ScrollViewer Grid.Row="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ContentControl Grid.Row="5" Background="Transparent" Focusable="False" Margin="0,5,0,0"
Content="{Binding CurrentSection}" ContentTemplateSelector="{StaticResource templateSelector}/>
</ScrollViewer>
Tempate XAML (truncated for clarity):
<Grid>
...
<ItemsControl Grid.Row="4" ItemsSource="{Binding Data.QualifyingDistributionsDividends}" x:Name="QualifyingItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="DTLayoutGrid">
...
<Grid Grid.Row="1" x:Name="DataLayout" Width="{Binding ElementName=DTLayoutGrid, Path=ActualWidth}" HorizontalAlignment="Stretch">
...
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="8" HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Payments}" Style="{StaticResource DataGridStyle}" CellStyle="{StaticResource DataGridNormalCellStyle}">
</DataGrid>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
So what happens? Datagrid assumes width of the entire DataTemplate (well its underlying controls that are set to be DataTemplates size, then * column assumes all empty space. When you try to resize the entire window that holds this code it will grow correctly, expanding the * column but it seems shrinking is not "registered" and it keeps the size you expanded it to, applies a scrollbar over that and forgets about it.
What i've tried so far was to set widths for ItemsControl, its underlying parents like Grid etc, also setting size to ContentControl, StackPanel, ScrollViewer and parent Grid of that.
I've also tried using scrollviewers directly on the Datagrid which produces an epileptic "1 million resizes a second" scenario. I've also played around with HorizontalAlignments
Under certain situations i DID managed to get the horizontal scrollbar to appear correctly but unfortunately that makes my DataGrid's * column to assume Auto Width rather then Star so DataGrid starts having an empty area to the right (unacceptable unfortunately...)
I understand that in order for horizontal scrollbar to work the parent or child of the scrollviewer needs Width set, i guess i can't work out where exactly do i need to restrict it. DataGrids NEED to infinitely expand with the main window while having first column fill all the available space.
Do let me now if you need more information on this and I will gladly answer.
It seems to me that this is just another case of the dreaded StackPanel layout problem. This problem comes up again and again and I confess that I had the very same problem when I started learning WPF. The StackPanel does not take the available size of its parent into consideration whereas other Panels such as a DockPanel or a Grid (yes, that's actually a Panel too) do.
It's explained in the How to: Choose Between StackPanel and DockPanel page on MSDN:
Although you can use either DockPanel or StackPanel to stack child elements, the two controls do not always produce the same results. For example, the order that you place child elements can affect the size of child elements in a DockPanel but not in a StackPanel. This different behavior occurs because StackPanel measures in the direction of stacking at Double.PositiveInfinity; however, DockPanel measures only the available size.
The StackPanel should only really be used to align a number of items, such as Buttons or other controls in a straight line where available space is not a concern. So anyway, the solution should be simple... just remove the StackPanel from the ScrollViewer. It doesn't appear to serve any purpose there anyway.
UPDATE >>>
After looking again, it seems as though you're saying that the problem is inside the DataTemplate, right? You might be able to fix that by setting the ItemsControl.HorizontalContentAlignment property to Stretch. That would ensure that each item remains within the boundary of the ItemsControl.
I'd also remove your Binding on the Grid.Width as you don't need it... a child Grid will take up the full space of a parent Grid by default. If these ideas don't work, just simplify your problem. Seriously, if you follow the advise in the linked page from the Help Center that I gave you in the comments, then you'll either fix the problem, or be able to come back here and provide a complete, but concise example that we could test.
I've found the behavior I was looking for by using a UniformGrid as the ItemsPanel, with its rows bound to the count of the ItemsSource model:
<ScrollViewer>
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding MyCollection.Count}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
As #Sheridan pointed out above, it seems the StackPanel is causing trouble. Also, credit to https://stackoverflow.com/a/23375262/385273 for pointing out the UniformGrid option.

Control the width of child in Stackpanel

I'm trying to implement a certain layout.
I have two elements that I want to stack vertically (I need them to follow each other closely). I am currently trying to achieve it using a Stackpanel.
The problem is that I want the first element to have a limited width and the other to use all the width available in the StackPanel. Ideally, I would like that the first element have a width equals to the width of four columns from the grid that contains the StackPanel, here is my code.
<Grid>
<!-- Colums and Rows definition go here -->
<StackPanel Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="3" Grid.RowSpan="8">
//The first element
<Viewbox Name="viewbox_choix" Margin="160,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="3" Grid.RowSpan="4">
//The second element
<StackPanel Grid.Column="0" Grid.ColumnSpan="5">
<Border></Border>
etc...
</StackPanel>
</StackPanel>
</Grid>
The grid attributes are referring to the parent grid of the stackpanel. But the Grid.Column and Grid.ColumnSpans seem to have no effect when I try to use them inside the StackPanel.
The problem of that code is that the first element also uses all the width of the StackPanel but that isn't what I want...
Can anybody help me ? I precise that I'm still learning WPF and I don't really know how bindings work...
In WPF, a StackPanel does not work like a Grid. There is no maximum width... it will happily let content disappear out of its right side. If you want automatic resizing, just replace the StackPanels with `Grid
UPDATE >>>
In the Grid class, there is an attached property called IsSharedSizeScope. Add this to the parent Grid and set it to true. Then in your RowDefinitions, you can add SharedSizeGroup properties to the columns that you require.
These examples may help you:
Grid's SharedSizeGroup and * sizing (SO post)
Grid.IsSharedSizeScope Attached Property (MSDN)
You may need to experiment a bit, but you should be able to get the desired effect using these properties.

Silverlight Grid inside of TabItem header

My custom TabItem header looks like this:
<sdk:TabControl>
<sdk:TabItem >
<sdk:TabItem.Header>
<Grid Background="Gray" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- some labels go here -->
</Grid>
</sdk:TabItem.Header>
</sdk:TabItem>
</sdk:TabControl>
This creates a single-row, two-column grid inside of the TabItem header. The grid automatically sizes to fit the labels, like it should, but when the size of the actual tab button grows, the grid does not adjust to fill the space (even though I specifiy <HorizontalAlignment="Stretch">).
Why is this? Is there a way to have the grid take up all available horizontal space in the header?
The problem is that the default template for a TabItem which is used to render the tab places the content of the header in a ContentControl. Now a ContentControl has the properties HorizontalContentAlignment and VerticalContentAlignment that have the default values of "Left" and "Top". This is why your grid only occupies the space it needs rather than stretching to the full size available.
In order to avoid this you will need to make a copy of the default template for the TabItem and assign the value "Stretch" to both of those properties on the ContentControl elements in the template (there are 8 in all, 2 for each possible TabStrip placement (Top, Left, Bottom and Right) ).

How do I make an item in a toolbar fill all available space in WPF

I'm trying to make an item on ToolBar (specifically a Label, TextBlock, or a TextBox) That will fill all available horizontal space. I've gotten the ToolBar itself to stretch out by taking it out of its ToolBarTray, but I can't figure out how to make items stretch.
I tried setting Width to Percenatage or Star values, but it doesn't accept that. Setting Horizontal(Content)Alignment to Stretch in various places seems to have no effect either.
Unfortunately it looks like the default ControlTemplate for ToolBar doesn't use an ItemsPresenter, it uses a ToolBarPanel, so setting ToolBar.ItemsPanel won't have any effect.
ToolBarPanel inherits from StackPanel. By default its Orientation is bound to the parent ToolBar.Orientation, but you can override this and set its Orientation to Vertical with a Style and this will allow items to stretch horizontally:
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<ToolBar.Resources>
<Style TargetType="{x:Type ToolBarPanel}">
<Setter Property="Orientation" Value="Vertical"/>
</Style>
</ToolBar.Resources>
<ComboBox HorizontalAlignment="Stretch" SelectedIndex="0">
<ComboBoxItem>A B C</ComboBoxItem>
<ComboBoxItem>1 2 3</ComboBoxItem>
<ComboBoxItem>Do Re Mi</ComboBoxItem>
</ComboBox>
</ToolBar>
<Border Margin="10" BorderBrush="Yellow" BorderThickness="3"/>
</DockPanel>
You can then use a Grid or something in place of the ComboBox above if you want multiple items on a line.
Try putting a horizontal StackPanel in the ToolBar and then the element you want inside of that StackPanel.
Have you tried wrapping your item in a Grid, not in a StackPanel?
You need a special custom panel like auto stretched stack panel, and replace the toolbarpanel. Check this out you can find one panel there
http://blendables.com/products/productsLayoutmix.aspx
I've had this same problem for a while, and there is very little help available online.
Since it doesn't sound like you need all the extra functionality of a Toolbar (collapsible/movable trays), why not just use a Top-docked Grid, and tweak the background a little to make it look like a standard toolbar?

Resources