Xaml and docking - wpf

I have this XAML:
<Window .....>
<DockPanel VerticalAlignment="Stretch">
<StackPanel DockPanel.Dock="Top">.....</StackPanel>
<StackPanel Height="200" DockPanel.Dock="Bottom">....</StackPanel>
</DockPanel>
</Window>
The idea is the second StackPanel to be always on the bottom of the windows and the first StackPanelto be always on the top of the window and to take any acces space (i.e. stretch to the second StackPanel), but I cannot seem to achieve this. Can anyone help me?

Try switching the position of the two StackPanels and add LastChildFill="True" to your DockPanel:
<Window .....>
<DockPanel VerticalAlignment="Stretch" LastChildFill="True">
<StackPanel Height="200" DockPanel.Dock="Bottom">....</StackPanel>
<StackPanel DockPanel.Dock="Top">.....</StackPanel>
</DockPanel>
</Window>

Related

Why TextBlock is not sizing to its content?

Why is the following TextBlock not sizing to its content? Its width (as shown with blue backgroud) is covering the width of the entire window.
What am I missing here and how can I fix it?
I have set Width="Auto" for the textblock. NOTE: I don't want to set the entire window to SizeToContent="WidthAndHeight" since it would have other controls that we don't need to use this setting for. This is just a minimal demo for this post only:
<Page x:Class="WPTEST.HomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPF_TEST"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="HomePage">
<Grid>
<StackPanel VerticalAlignment="Center">
<TextBlock Width="Auto" FontSize="16" Background="Blue" Foreground="White" FontWeight="Bold" Text="Welcome To Home Page. Your home page to perform main tasks"/>
</StackPanel>
</Grid>
</Page>
MainWindow Display:
Set HorizontalAlignment="Left". The default value is "Stretch", which means that the control should be stretched to fill the space available in the containing element. Setting to "Left" will disable that behavior and allow the TextBlock to grow only as much needed to fit the text:
<Grid>
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Left"
FontSize="16" Background="Blue" Foreground="White" FontWeight="Bold"
Text="Welcome To Home Page. Your home page to perform main tasks"/>
</StackPanel>
</Grid>

Displaying a large image in ScrollViewer in WPF

I want to display a large image in a Window where the Image will have scroll bars if it too big for the area of the screen it is in.
Underneath the image I want a button panel. For this I have put the Image inside a ScrollViewer in a DockPanel that contains a StackPanel to contain the Buttons in the Bottom part. The idea is to click the Browse button to set the image (from code behind handling Button Click)
The following example I put together will just keep the image size (2144 x 1424) and I cannot see the lower button panel.
<Window x:Class="WpfIssues.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfIssues"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DockPanel>
<TextBlock Text="Test Image" FontSize="30" DockPanel.Dock="Top"></TextBlock>
<StackPanel Orientation="Vertical">
<DockPanel x:Name="PhotoPanel">
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Click="Button_Click">Browse...</Button>
</StackPanel>
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<Image x:Name="PhotoImage"
Stretch="None"
Source="Resources/bear grills.png"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>
</ScrollViewer>
</DockPanel>
</StackPanel>
</DockPanel>
</Grid>
</Window>
I cant figure out why.
Try putting the button before the scrollviewer, like this:
<DockPanel>
<TextBlock Text="Test Image" FontSize="30" DockPanel.Dock="Top" />
<Button Content="Browse..." DockPanel.Dock="Bottom" />
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Image x:Name="PhotoImage"
Stretch="None"
Source="http://images6.fanpop.com/image/photos/33600000/Bear-Grylls-bear-grylls-33656894-3504-2336.jpg"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</ScrollViewer>
</DockPanel>

Dock a resizable wpf DataGrid at bottom of window

In a WPF project, I want to dock a DataGrid to the bottom of a window so that if the window resizes, I will be able to utilize more of the DataGrid. Like this:
How do I do that? All my DockPanel attempts have failed.
The current attempt is here:
<Window x:Class="Foo.SQLDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Foo.Controls"
Title="test" ResizeMode="CanResize" Width="400" Height="400">
<StackPanel Orientation="Vertical" Height="Auto" Width="Auto">
<StackPanel Orientation="Vertical">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left"/>
<ScrollViewer Width="Auto" Height="180" DockPanel.Dock="Right,Bottom"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</StackPanel>
</Window>
The height of the scrollviewer+datagrid will not adapt however.
First of all, using DockPanel.Dock without having a DockPanel as a parent doesn't do much...
In my example I changed your root StackPanel to a DockPanel so it will work as you want.
I also used DockPanel.LastChildFill property which makes sure the last child of the DockPanel will get all the remaining space:
<DockPanel LastChildFill="True">
<StackPanel Orientation="Vertical" DockPanel.Dock="Top">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left" DockPanel.Dock="Top"/>
<ScrollViewer DockPanel.Dock="Bottom,Right"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</DockPanel>
Finally, to make it really stretch on all the remaining space, I removed the Height property you set, as this blocked it from stretching.
Not sure if useful or if i understand you question the right way but have you tried this:
<DataGrid DockPanel.Dock="Right, Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Right" ></DataGrid>

xaml layout introduction for Qt programmer

I am used to Qt and its Qt Designer.
XAML with its layout controls 'grid' and 'StackPanel' are somehow similar, but I still miss or do not find some of the most common properties of designs in Qt. Since I am completely new to XAML I would like to know the answers or further available documentations.
For example I want to add 2 elements (lets say buttons) either horizontal or vertical with their default height and a minimum height and minimum width. If aligned horizontal they shall be pushed to the left side and the remaining side on the right should be free. That means that the size of the buttons does not increase if the windows size is increased. In Qt this is realized by a grid in combination with a spacer (see for example this tutorial for an example).
My first XAML is far away from what I expect. The definition of RowDefinition is copied from a tutorial. However I do not understand its meaning...
<Window x:Class="SpectrumViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Spectrum Viewer" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="8" VerticalAlignment="Top">
<Button MinWidth="75" MaxHeight="23" Margin="10" HorizontalAlignment="Left" Width="100" Name="buttonTest">test</Button>
<TextBox MinWidth="75" MaxHeight="23" Margin="10" HorizontalAlignment="Left" Width="150" Name="textBoxValue"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="8" >
<Button MinWidth="75" MaxHeight="23" Margin="10" HorizontalAlignment="Left" Width="100" Name="button1">button 1</Button>
<Button MinWidth="75" MaxHeight="23" Margin="10" HorizontalAlignment="Left" Width="100" Name="button2">button 2</Button>
</StackPanel>
</Grid>
</Window>
The next image shows that the elements are pushed to the left side, but the two stacked panels above each other are not pushed to the top. If I set them both with VerticalAlignment="Top" they overlap which is also wrong.
If I resize the window one can see that the elements are not resized and that the second StackPanel overlaps with the first:
Instead the elements should be resized to the minimum width and any further resizing of the windows should be prohibited.
The first problem of the two stack panels overlapping when you set both VerticalAlignment to Top is because since you haven't specified in which Grid.Row they should be, the default would be both in Grid.Row = 0. Specify the row index and they won't overlap :
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="8" VerticalAlignment="Top">
....
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="8" VerticalAlignment="Top">
....
</StackPanel>
There is no way the window would stop resizing when the minimum size of the buttons is reached. You could set the MinWidth of the Grid and ask the window to stop right there :
<Window x:Class="SpectrumViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Spectrum Viewer" Height="350" Width="525"
MinWidth="{Binding RelativeSource={RelativeSource Self}, Path=Content.MinWidth}">
<Grid MinWidth="350">
.......
</Grid>
</Window>
Or set the MinWidth of the Window itself :)

WPF: how to get remaining width in a StackPanel?

Given the code below:
<Window x:Class="Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window3" Height="300" Width="300">
<StackPanel Background="Yellow" Orientation="Horizontal">
<TextBlock Background="Green" Text="some text" Width="200"/>
<TextBox Width="{Binding ???}" />
<TextBlock Background="Red" Text="some text" Width="50"/>
</StackPanel>
</Window>
how do you bind second textbox's width as to fill the remaining space?
Please keep in mind I'm looking for a binding solution: I know how to do it using other layouts (like DockPanel or grid) but I'm not interested in that. Also, using ElementName is not of interest.
Thanks.

Resources