WPF positioning take full height of window - wpf

Here's my layout.
<Window>
<StackPanel Orientation="Vertical">
<StackPanel HorizontalAlignment="Stretch" Height="30">
</StackPanel>
<Canvas HorizontalAlignment="Center" Width="1020">
<!--i want this to take the remaining full height of the screen-->
<Canvas x:Name="bottomInfoBar" Canvas.Bottom="0" Width="720" Height="39">
<!--I want this at the very bottom of the screen-->
</Canvas>
</Canvas>
</Window>
I want the canvas to take the full height of the window so that the 'bottomInfoBar' always remains at the very bottom of the user's screen. However if i don't specify a height for the canvas 'bottomInfoBar' appears at the very top. How do i achieve this? Please help.

Easiest way:
<Window>
<DockPanel>
<Whatever x:Name="bottomInfoBar" DockPanel.Dock="Bottom"/>
<PrimaryContent/>
</DockPanel>
</Window>
Based on your question, you really should read about WPF's layout system before you write another line of code. You'll save yourself a world of pain if you understand that before proceeding.

Related

Helix3d WPF draw text at the top/left of HelixViewport3D

I want to show some text information at the top/left of HelixViewport3D like "ShowCameraInfo" does, which display camera information at the bottom/left of the Viewport. BillboardTextVisual3D requires a 3D point, but what I want is just like TextBlock on Canvas, which just need a 2D coordinate.
I can use TextBlock, but it cannot be captured as part of HelixViewport3D.
Any idea?
Literally a Textblock placed over the HelixViewport3D should be what you need.
There is only one problem: Viewport will not recognize if you try to manipulate the camera by initiating the mouse click on the Stackpanel.
<Grid>
<hx:HelixViewport3D>
<hx:DefaultLights/>
<hx:CubeVisual3D SideLength="7"/>
<hx:CubeVisual3D SideLength="5" Fill="Red" Center="-5,3,0"/>
</hx:HelixViewport3D>
<StackPanel Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel.Background>
<SolidColorBrush Color="#FFB6B6B6" Opacity="0.4"/>
</StackPanel.Background>
<TextBlock Text="asdhfasdvfmnas" Margin="5,2"/>
<TextBlock Text="mvcbnxcvjhbkdaf" Margin="5,2"/>
<TextBlock Text="vbkjsdvj" Margin="5,2"/>
</StackPanel>
</Grid>

Horizontal scrolling a row of ViewBox images in Xaml

I'm working on a UWP Windows 10 app with a XAML UI. One of my pages requires that images fill the height of the window (or screen in tablet mode) and uniformly scale as one long row of images from left to right (going off-screen). I've got this set up perfectly using ViewBoxes for the images inside of a StackPanel set to a Horizontal Orientation like so:
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
The intention is for the images to flow off-screen with a horizontal scroll that allows the user to pan from left to right to see the gallery of images as one long row.
I've tried enabling HorizontalScrollMode on the parent StackPanel like so:
<StackPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollMode="Enabled">
But this did not enable any scrolling at all.
I also tried to wrap everything inside of a ScrollViewer like so:
<ScrollViewer HorizontalScrollMode="Enabled">
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
</ScrollViewer>
But this completly breaks my ViewBox layout by shrinking all the images so they fit within a small portion of the screen and no longer fill the window/tablet height.
I've tried a number of other variations with similar results. Does anyone have some suggestions for solving this? Let me know if you need more info.
You do need a ScrollViewer to enable scrolling, although you might need to set a few properties to make it only scroll horizontally as mentioned in Windows 8 ListView with horizontal item flow
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.ZoomMode="Disabled"
Now the Viewbox is not the most controllable... control. You could try using the
SquareGrid panel from my toolkit instead of the Viewboxes. Maybe simplify it a bit. If that isn't enough - you could add some bindable properties that would update when the size of your window changes and bind the Width and Height of these images to these properties. Note that you can't use ActualWidth or ActualHeight because these don't raise change notifications on size changes.
<GridView x:Name="ImageGridView"
SelectedItem="{x:Bind ViewModel.SelectedLocation, Mode=TwoWay}"
Margin="10,0"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.HorizontalScrollMode="Auto"
Grid.Row="4" Grid.ColumnSpan="5"
ItemsSource="{x:Bind ViewModel.CheckedLocations}"
ItemContainerStyle="{StaticResource PinsGridViewItemStyle}"
ItemTemplate="{StaticResource ImageOverlayGalleryFolderDataTemplate}" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
This is my code to show 1 row of photos. You can adjust by the MaxiumRowsOrColumns. Also note that both HorizontalScrollBarVisibility and HorizontalScrollMode are present to custom as you want to.

WPF: Using Grids

I created a grid and inside this grid it contains a TextBlock. When I maximize or adjust the size of the window the content of the TextBlock doesn't stay in the center of the Grid.
Tried to keep this as short as possible. :>
<Grid>
<Grid HorizontalAlignment="Left" Height="46" VerticalAlignment="Top" Width="515">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Welcome! Use the functionalities below.</TextBlock>
</Grid>
</Grid>
Grids, by default, auto expand. That is, they take up as much area as they are allowed. Your outer grid will take up the entire client area of the window while the inner grid will stick to the top left of the outer grid, just as you have coded it to. If you want the inner grid to be centered, then do something like
<Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="46" Width="515">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Welcome! Use the functionalities below.</TextBlock>
</Grid>
</Grid>
You don't even have to include the horizontal and vertical alignment as grids will automatically centre.
If you just want to centre the TextBlock ...
<Grid>
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Height="46" Width="515">Welcome! Use the functionalities below.</TextBlock>
</Grid>
</Grid>
The text can be centred using the TextAlignment property.
I hope this helps

Perfect Center on WPF Canvas

Since the canvas requires a Top/Left for placement, if you want to center something, is adding a grid at the proper Canvas.Top with HorizontalAlignment="Center" the best way to do it, or is there a better way?
This snip is a 150X300 canvas, with some content centered in a grid ....
<Canvas Width="150" Height="300">
<Grid Canvas.Top="75" Width="106" HorizontalAlignment="Center">
{whatever you want centered}
</Grid>
</Canvas>
Guy's solution works, but you may have to tweak z-order and visibility if you're juggling hit testing.
Another alternative is having the Grid inside the Canvas (as you've specified in your XAML) with the Height/Width set to (or bound to) the Height/Width of the Canvas. Then setting HorizontalAlignment/VerticalAlignment to Center for the contents of your Grid.
I'm not sure if this will meet your exact requirement, but if you put both the canvas and the content inside a grid as peers, it will get you a centered result:
<Grid>
<Canvas Width="150" Height="300"/>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Width="106" Content="Click"/>
</Grid>

Window sizing related to contents

I've got two sizing issue regarding a Window I've got. The basic layout is like this
<Window MaxHeight="{DynamicResource {x:Static SystemParameters.VirtualScreenHeight}}"
MaxWidth="{DynamicResource {x:Static SystemParameters.VirtualScreenWidth}}"
>
<StackPanel>
<DockPanel LastChildFill="False">
<StackPanel DockPanel.Dock="Left"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
</DockPanel>
<ScrollViewer>
<WrapPanel x:Name="Container">
</WrapPanel>
</ScrollViewer>
</StackPanel>
</Window>
1) How do I made the Window not get smaller horizontally than the DockPanel's width?
2) How do I make the ScrollViewer be restricted to the limits of the Window? It is sizing itself to its contents, extending past the bounds of the Window.
It sort of used to work when I had
<Window><ScrollViewer/></Window>
, but I really don't want the DockPanel inside the scroller. In the current form, it is even forcing the Window to break its MaxHeight.
I would recommend you to use Grid with * Lenght instead of DockPanel and StackPanel.
Just get rid of those StackPanels. Replace them with Grids and you should be good. The layout logic of the StackPanel is such that it will give children as much room in a certain direction (perpendicular to the StackPanels orientation) as they ask for. That's why you're seeing the odd layout issues.

Resources