Stretch items to fill canvas - wpf

I have a Dockpanel with items inside a Canvas. The Dockpanel and any other items (Grid etc) that I place inside the Canvas, only take up their minimum required space. How do I stretch these items to fill the entire Canvas?
<Canvas x:Name="InfoCanvas" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="72,53,0,0">
<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="ReferenceInfo" Canvas.Left="0" Canvas.Top="0">
<TextBox x:Name="ReferenceAuthor" GotFocus="FieldEnter" LostFocus="FieldLeave" FontSize="16" FontFamily="Segoe UI Light" Text="Author" Foreground="Gray" Background="Transparent" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0,2,0,2"/>
<TextBox x:Name="ReferenceTitle" GotFocus="FieldEnter" LostFocus="FieldLeave" FontSize="16" FontFamily="Segoe UI Light" Text="Title" Foreground="Gray" Background="Transparent" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0,2,0,2"/>
<TextBox x:Name="ReferenceDate" GotFocus="FieldEnter" LostFocus="FieldLeave" FontSize="16" FontFamily="Segoe UI Light" Text="Date" Foreground="Gray" Background="Transparent" DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Stretch" BorderThickness="0" Margin="0,2,0,2"/>
</DockPanel>
</Canvas>
Thank you!

The Canvas panel doesn't really support that.
It's very basic - it just allows you to position children absolutely by using Top, Bottom, Left and Right, and it always gives them just the space they need.
So usually you would use a Grid with just 1 column and 1 row instead.
You can however bind the width and height of the DockPanel to the width and height of the Canvas. That way the DockPanel will always fill the Canvas.
<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Margin="0,0,0,0" x:Name="ReferenceInfo" Canvas.Left="0" Canvas.Top="0"
Width="{Binding ActualWidth, ElementName=InfoCanvas}"
Height="{Binding ActualHeight, ElementName=InfoCanvas}">

What you can do is:
<Grid>
<Canvas x:Name="InfoCanvas">
<!--Elements with canvas layout here-->
</Canvas>
<DockPanel x:Name="ReferenceInfo">
<!--Elements with dockpanel layout here-->
</DockPanel>
</Grid>
By wrapping both panels in a grid like this you can place elements that you cant to position relative to left, top etc in the canvas. Both the canvas and the dockpanel will fill available space. Note that the elements in the dockpanel will be rendered above the elements in the canvas when the dockpanel is defined after in xaml.
I'm assuming the code you posted is pseudo code, if not you should just remove the canvas.

Related

cannot display the slider of a scrollviewer

I can't get the slider for a scrollviewer to display. I have a listbox in a wrappanel. The listbox has a list of numbers. The list can be long enough to extend off of the bottom of the screen, so a scrollviewer is needed, but no matter how I set scrollviewer properties, or even if I put the listbox inside a scrollviewer inside the wrappanel, the slider doesn't appear. What am I doing wrong? Here's the XAML:
<WrapPanel Grid.Row="5" Grid.ColumnSpan="2">
<ListBox x:Name="lstBxCollisions"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="auto" Width="auto"
ItemsSource="{Binding MainWindow.lstBxCollisions}"
ScrollViewer.VerticalScrollBarVisibility="Auto"/>
<FlowDocumentReader Grid.Row="5" Grid.Column="1" Document="{Binding SingleAccidentFlowDocument}">
</FlowDocumentReader>
</WrapPanel>
Since your ListBox is inside WrapPanel, all its sizes are selected automatically and it begins to expand as the content size increases.
If you want it to appear ScrollBar, you need to fix the size of the ListBox by setting the actual height and width.
For example:
<WrapPanel Grid.Row="5" Grid.ColumnSpan="2">
<ListBox x:Name="lstBxCollisions"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="100" Width="100"
ItemsSource="{Binding MainWindow.lstBxCollisions}"
ScrollViewer.VerticalScrollBarVisibility="Auto"/>
<FlowDocumentReader Grid.Row="5" Grid.Column="1" Document="{Binding SingleAccidentFlowDocument}">
</FlowDocumentReader>
</WrapPanel>

Silverlight 4 TextBlock inside ScrollViewer is clipping the text on the right

I have this very simple ChildWindow:
<Grid x:Name="LayoutRoot" Margin="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
<Button x:Name="OKButton" Content="OK" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
<ScrollViewer Width="378">
<StackPanel>
<TextBlock x:Name="txtFracture" HorizontalAlignment="Left" Margin="10,10,10,10" TextWrapping="Wrap" VerticalAlignment="Top" Width="358"/>
</StackPanel>
</ScrollViewer>
</Grid>
My problem is that the text in the TextBlock is getting clipped on the right side. (I originally didn't have the StackPanel in there - that was just an experiment.) I have added more and more to the Margin.Right, but it doesn't help. The Scroll bar itself isn't stepping on the text, the text just drops a bunch of pixels as it gets to the right of the block. Sometimes, it isn't even whole letters that are getting clipped. See anything?
Also, if I change the HorizontalAlignment from Left to Center, I get the pixel-clipping on both sides of the block.
Also, if I remove the ScrollViewer altogether, the clipping is still there, so it isn't his fault, either.
I notice you have texblock width as constant and you need margin of 10 on all side. In this case ScrollViewer ScrollBar clips your TextBlock.
Possible solution is
1. Remove width on textblock and set alignment stretch.
try this
<ScrollViewer Width="378" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<TextBlock x:Name="txtFracture" HorizontalAlignment="Stretch" Margin="10,10,10,10" TextWrapping="Wrap" VerticalAlignment="Stretch"
Text="Testing"/>
</ScrollViewer>
Turns out that this works:
<ScrollViewer Width="378" >
<StackPanel>
<TextBlock x:Name="txtFracture" Margin="10,10,10,10" TextWrapping="Wrap" />
</StackPanel>
</ScrollViewer>
As far as I can tell, the actual culprit was the explicitly set TextBlock Width.

VerticalAlignment="Stretch" stretches out of my container

I have a parent container that is used to hold all of my user controls. The issue is that I use VerticalAlignment="Stretch" to stretch contents to the full height and get a vertical scroll bar the user control gets stretched too much. The vertical scrollbar appears but there is no way to scroll. I know this because the down arrow for the scroll bar isn't visible.
I have <ContentControl Content="{Binding Workspace}" /> which is where a variety of controls can be assigned. For example, here is the XAML that is not working property in regards to stretching.
<StackPanel>
<TextBlock Text="{Binding FoundCount}" FontSize="13" Foreground="#666" Margin="0 0 0 8" />
<ScrollViewer VerticalAlignment="Stretch">
<TreeView
ItemsSource="{Binding Listing}"
Grid.Row="1"
BorderThickness="0"
VirtualizingStackPanel.IsVirtualizing="True" />
</ScrollViewer>
</StackPanel>
I only want to the TreeView to stretch and display a vertical scrollbar.
Any ideas?
I suspect the height of the StackPanel is not contrained so it grows to accomodate the ScrollViewer. You can check this by putting a border on the StackPanel.
<Border>
<StackPanel>
<TextBlock Text="{Binding FoundCount}" FontSize="13" Foreground="#666" />
<ScrollViewer VerticalAlignment="Stretch">
<TreeView ItemsSource="{Binding Listing}" BorderThickness="0"
VirtualizingStackPanel.IsVirtualizing="True" />
</ScrollViewer>
</StackPanel>
</Border>

ScrollViewer enveloping a Grid not working properly

I am facing a strange problem with the ScrollViewer
I have a ScrollViewer with a Grid inside. The height of the Grid requires a vertical scrollbar. At runtime, the scrollbar is visible, but appears disabled and has no scroll indicator between the two arrows.
However, just above this scrollviewer is another set of controls enveloped by a scroll viewer, actually just the wayas the above, but here the scroll viewer is working just fine
here's the code
<Grid><Canvas Height="250" Width ="400" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Background="White" Name="ModeCanvas">
<Rectangle Width="{Binding ElementName=ModeCanvas,Path=ActualWidth}" Height="{Binding ElementName=ModeCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2"/>
<Grid Height="244" Width ="394" Margin="3,3,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Name="ModeParent">
<ScrollViewer VerticalScrollBarVisibility="Visible" >
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="ModeGrid" >
</Grid>
</ScrollViewer>
</Grid>
</Grid>
</Canvas>
<Canvas Height="250" Width="400" Margin="0,255,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White" Name="InputDataCanvas">
<Rectangle Width="{Binding ElementName=InputDataCanvas,Path=ActualWidth}" Height="{Binding ElementName=InputDataCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2"/>
<Grid Margin="5,5,5,5" Width="390" Height="240" Name="InputDataParent">
<ScrollViewer VerticalScrollBarVisibility="Visible" >
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="InputDataGrid" >
</Grid>
</ScrollViewer>
</Grid>
</Canvas>
<Canvas Margin="0,510,0,0" Height="250" Width ="400" VerticalAlignment="Top" HorizontalAlignment="Left" Background="White" Name="OutputDataCanvas">
<Rectangle Width="{Binding ElementName=OutputDataCanvas,Path=ActualWidth}" Height="{Binding ElementName=OutputDataCanvas,Path=ActualHeight}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2" />
<Grid Margin="5,5,5,5" Width="390" Height="240" Name="OutputDataParent">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Name="OutputDataGrid">
</Grid>
</ScrollViewer>
</Grid>
</Canvas>
In this code - the first 2 Canvas render the scrollbar just fine, but for some reason the third one is creating a problem
Any Ideas ??
EDIT
Finally got the mistake in the code. The probelm was in the code behind.
The basic probelm was that when we resize the window at that time some code behind code was changing the heights of the first 2 Grids but not of the third Grid. Initially the data that was inserted in each Grid(dynamically) was such that, the first 2 Grids used to overflow but not the 3rd one, . So, now when i resized the window the third Grid still did not have a scroll viewer even though now the data was overflowing the space,giving an impression that the scroll viewer was not activating.
However, i missed the simple fact, that the height of the 3rd grid was not changing, whereas the first 2 Grids height was changing, thus the scroll viewer for the first 2 grids was properly working but not the 3rd.
The Grid inside the ScrollViewer is empty. What the scrollviewer is expect to scroll?

WPF layout issue with nested StackPanel straying outside parent StackPanel

I have a horizontal StackPanel with an image and another StackPanel. The inner StackPanel is vertical with two TextBlocks both of which have TextWrapping set to Wrap. However when the text gets wide the inner StackPanel increases in width so that the TextBlocks don't wrap. The outer StackPanel is staying with the grid layout space it has been given. How can I make the inner StackPanel stay within the bounds of the outer StackPanel?
Here's the relevant section of XAML:
<StackPanel Name="_imageAndNameStackPanel"
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
Orientation="Horizontal" Margin="12,12,12,0">
<Image Name="_applicationImage" Source="{Binding Path=ImageUri}"
Stretch="Fill" Height="64" Width="64" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="0,0,12,0" />
<StackPanel Name="_nameStackPanel">
<TextBlock Name="_nameTextBlock" Text="{Binding Path=AppName}"
FontSize="24" VerticalAlignment="Top" TextWrapping="Wrap"/>
<TextBlock Name="_subtitleTextBlock" Text="{Binding Path=Subtitle"
FontSize="18" VerticalAlignment="Top" Margin="0,6,0,0"
TextWrapping="Wrap"/>
</StackPanel>
</StackPanel>
You're probably better off with a DockPanel instead of StackPanel.
<StackPanel Name="_imageAndNameStackPanel"
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
Orientation="Horizontal" Margin="12,12,12,0">
<Image Name="_applicationImage" Source="{Binding Path=ImageUri}"
Stretch="Fill" Height="64" Width="64" HorizontalAlignment="Left"
VerticalAlignment="Top" Margin="0,0,12,0" />
<DockPanel Name="_nameStackPanel">
<TextBlock Name="_nameTextBlock" Text="{Binding Path=AppName}"
FontSize="24" VerticalAlignment="Top" TextWrapping="Wrap"
DockPanel.Dock="Top" />
<TextBlock Name="_subtitleTextBlock" Text="{Binding Path=Subtitle"
FontSize="18" VerticalAlignment="Top" Margin="0,6,0,0"
TextWrapping="Wrap" DockPanel.Dock="Top"/>
</DockPanel>
</StackPanel>
Lately I'm finding that 2 out of 3 times that I start with StackPanel I end up changing it to DockPanel.
But… are you sure that the outer StackPanel is not expanding beyond the bounds of its grid cell? You might want to make that one a DockPanel as well, with both the Image and the inner DockPanel having DockPanel.Dock="Left".
You could bind your inner StackPanel's width to the Parent StackPanel's width. Something like:
{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=Width}
Give your inner stackpanel or textblock's a fixed width.

Resources