Docking Top/Bottom/Left/Right/Filling in WPF - wpf

i am win form developer. whenever i want to set any control at top/Bottom/Left/Right position in its container then we just play the controls dock property in winform. so just guide me how can i place a control in its container top/Bottom/Left/Right position in such a way as a result when contain size change then control position will not change in wpf.
after searching google i came to know how filling works with Dock property and it is like
<Window ...Other window props... >
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- Canvas items here... -->
</Canvas>
</Window>
So guide me how to set any control at top/Bottom/Left/Right position in its container with code snippet.
UPDATE
i just come to know dock panel can be use for my requirement like this way
<DockPanel LastChildFill="True">
<Button Content="Dock=Top" DockPanel.Dock="Top"/>
<Button Content="Dock=Bottom" DockPanel.Dock="Bottom"/>
<Button Content="Dock=Left"/>
<Button Content="Dock=Right" DockPanel.Dock="Right"/>
<Button Content="LastChildFill=True"/>
</DockPanel>
any other way can i achieve this without using DockPanel. thanks

You can use a Grid, (note the star sizing)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- If not specified, then Grid.Column="0" Grid.Row="0" are defaults-->
<Button Content="Dock=Top" Grid.ColumnSpan="3"/>
<Button Content="Dock=Bottom" Grid.Row="2" Grid.ColumnSpan="3"/>
<Button Content="Dock=Left" Grid.Row="1"/>
<Button Content="Dock=Right" Grid.Column="2" Grid.Row="1" />
<Button Content="LastChildFill=True" Grid.Column="1" Grid.Row="1"/>
</Grid>
You can use margins and alignments (margins are approximate here)
<Grid>
<Button Content="Dock=Top" VerticalAlignment="Top"/>
<Button Content="Dock=Bottom" VerticalAlignment="Bottom"/>
<Button Content="Dock=Left" HorizontalAlignment="Left" Margin="0,35"/>
<Button Content="Dock=Right" HorizontalAlignment="Right" Margin="0,35" />
<Button Content="LastChildFill=True" Margin="75,35"/>
</Grid>
You can use StackPanels (this one needs more work to make it fill the space)
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="Dock=Top" />
<StackPanel Orientation="Horizontal" >
<Button Content="Dock=Left" />
<Button Content="LastChildFill=True" />
<Button Content="Dock=Right" />
</StackPanel>
<Button Content="Dock=Bottom" />
</StackPanel>

<DockPanel>
<Button DockPanel.Dock="Left" Content="Left"></Button>
<Button DockPanel.Dock="Right" Content="Right"></Button>
<Button DockPanel.Dock="Top" Content="Top"></Button>
<Button DockPanel.Dock="Bottom" Content="Bottom"></Button>
<Button DockPanel.Dock="Left" Content="Center" HorizontalAlignment="Center"></Button>
</DockPanel>

Related

fluid layout in wpf is rendering enormous controls

EDIT
Having removed the <ViewBox Stretch="UniformToFill"> from the xaml, it renders better - the size of the controls are more appropriate, however, as the Frame is empty when I'm loading the window, the whole app appears as a band across the center of my screen.
When I do load content into the frame, the rest of the window fits width to the frame, rather than to the screen resulting in empty space on the left and right of the Frame's content.
ORIGINAL QUESTION
I've never done a fluid layout before so what I've done is based entirely on what I've gleaned from answers to other questions on SO and around the interwebz.
So the following XAML, I figured, should be "responsive" which is to say that it would render much the same on every screen resolution without using fixed widths.
Unfortunately, the controls are rendering at enormous scale. What should be a 30x30 button looks to be rendering around 10x that size (see the screenshots below - the second one is the app maximized to fullscreen).
How can I change my xaml to make these controls render to the row heights and to the width of the display?
<Grid>
<Viewbox Stretch="UniformToFill">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="50"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Titlebar -->
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Background="#2d2d30">
<StackPanel Name="spTitlebar1" FlowDirection="LeftToRight" Orientation="Horizontal" MouseDown="spTitlebar_MouseDown">
<Label Name="lblTitle" HorizontalAlignment="Left" BorderThickness="0" Foreground="White">IHS Towers SCADA</Label>
</StackPanel>
<StackPanel Name="spTitleBar2" FlowDirection="RightToLeft" Orientation="Horizontal" MouseDown="spTitlebar_MouseDown">
<Button Name="btnClose" Content="X" Click="btnClose_Click" Style="{StaticResource TitleButton}" />
<Button Name="btnMinimize" Content="_" Click="btnMinimize_Click" Style="{StaticResource TitleButton}" />
<Border BorderThickness="1,0,0,0" BorderBrush="#686868">
<Button Name="btnSettings" Click="btnSettings_Click" Style="{StaticResource TitleButton}" ToolTip="Settings">
<Image Source="Images/settings-icon.png" Height="20" Width="20"/>
</Button>
</Border>
<Button Name="btnReports" Click="btnReports_Click" Style="{StaticResource TitleButton}" ToolTip="View reports">
<Image Source="Images/reports-icon.png" Height="20" Width="20"/>
</Button>
</StackPanel>
</StackPanel>
<!-- Towers Bar across the top Height="50" -->
<StackPanel Grid.Row="1" Grid.Column="0" Name="spTowers" Background="#2d2d30" VerticalAlignment="Top" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,0">
<Border BorderThickness="5,0,0,0" BorderBrush="#686868" VerticalAlignment="Top"></Border>
</StackPanel>
<!-- Alert Window in the center -->
<Frame Name="frmBody" Grid.Row="2" Grid.Column="0" Margin="0" Background="#1e1e1e" NavigationUIVisibility="Hidden" />
<!-- Actions Bar across the bottom Height="60" -->
<StackPanel Grid.Row="3" Grid.Column="0" Name="spActions" Height="60" Background="#2d2d30" VerticalAlignment="Top" FlowDirection="RightToLeft" Orientation="Horizontal">
<Button Name="btnSMS" Click="btnSMS_Click" Height="30" Width="66" Margin="10,10,10,10" Style="{StaticResource RoundedButtonGreen}">Send SMS</Button>
</StackPanel>
</Grid>
</Viewbox>
</Grid>

window resize when textbox resize

Here is the code for Textbox available in my window(form1.xaml),My requirement is when i am resizing my window i want to resize the textbox width also, How can i able to achieve this....
<TextBox Width="500" HorizontalAlignment="Left" Margin="5,0,0,5" TextWrapping="Wrap" AcceptsReturn="True" Text="{Binding Result,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" IsEnabled="{Binding OpenMode,Converter={StaticResource EnableModeConverter}}" Height="70" />
In WPF you typically place TextBox control within layout Grid control and set the ColumnDefinition Width property of that Grid cell to some relative value "*", so it will resize with the Window. Do NOT use a fixed Width="500" as per your sample: also, remove that "HorizontalAlignment="Left" (the default value is HorizontalAlignment="Stretch", so you can just omit it to simplify your XAML). See the following sample code snippet:
<Grid Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<TextBox Name="TextBox1" Grid.Row="0" Grid.Column="0" Height="70" Margin="5,0,0,5" TextWrapping="Wrap" AcceptsReturn="True" (...Rest of Your code) />
</Grid>
Note: The same technique could be applied to a vertical "Height" property in case you need to make it also resizable.
Hope this will help. Best regards,
Set HorizontalAlignment to Stretch, and don't set the Width
<Grid>
<TextBox HorizontalAlignment="Stretch"
Margin="5,0,0,5"
TextWrapping="Wrap"
AcceptsReturn="True"
Height="70" />
</Grid>
Layout in WPF is heavily depend on the parent container. For example, create a form with labels and input fields, consider using a Grid panel. Controls in WPF by default resize according to the layout behavior of their parent. Here is an example of a window with two labeled text boxes and two buttons that resize along with the window.
<Window>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Content="Contact Name" Grid.Row="0" Grid.Column="0" />
<TextBox Grid.Row="0" Grid.Column="1" />
<Label Content="Contact Location" Grid.Row="1" Grid.Column="0" />
<TextBox Grid.Row="1" Grid.Column="1" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Grid.Row="2" Grid.Column="1">
<Button Content="OK" Width="75" Height="24" Margin="3" />
<Button Content="Cancel" Width="75" Height="24" Margin="3" />
</StackPanel>
</Grid>
</Window>

WPF - can't see a button in th View design

I wrote a simple WPF window that shows a customers grid.
in the bottom of the grid I added a button "Add a new Customer, but it blended into the background of the window, and I can't see it in View design.
this is the code:
<Window x:Class="NihulMlay._1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title=" Customers " Height="120" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Button FontWeight="Bold">Customer name</Button>
<Button Grid.Column="1" FontWeight="Bold">Name</Button>
<Label Grid.Row="1"></Label>
<Label Grid.Column="1" Grid.Row="1"></Label>
<Button Grid.ColumnSpan="2" Content="Add a new Customer" HorizontalAlignment="Left" Height="100" Margin="270,114,0,-173" Grid.Row="1" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
thanks.
Your Problem is the Window height of 120, once you resize it to say 350, you can see the Button.
The margin on your Button is:
Margin="270,114,0,-173"
which makes a Top-Margin of 114, the Button height is 100 and the row above is set to 40. This values alone would make a total required height of 254 to see all contents.
I think you are mistaking a Grid with a DataGrid. Grid is an area that contains other controls while DataGrid Represents a control that displays data in a tabular form. Looking at your code sample, I think DataGrid is what you wanted.
Assuming you did really mean Grid, then you can move your Button out by placing the entire Grid in another container (e.g. a DockPanel) like this:
<DockPanel>
<Button DockPanel.Dock="Bottom" Content="Add a new Customer" Height="100" Width="139"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Button FontWeight="Bold">Customer name</Button>
<Button Grid.Column="1" FontWeight="Bold">Name</Button>
<Label Grid.Row="1"></Label>
<Label Grid.Column="1" Grid.Row="1"></Label>
</Grid>
</DockPanel>

How to share between all buttons a width of the widest button within a StackPanel?

For instance, I have this markup:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="PreviousPage"
Content="Previous" />
<Button x:Name="Info"
Content="Information" />
<Button x:Name="InetTicket"
Content="Internet ticket" />
<Button x:Name="FindStation"
Content="Find station" />
<Button x:Name="NextPage"
Content="Next" />
</StackPanel>
</Grid>
How to determine the widest button and share it's size with the other buttons. So the buttons should be of the same width at the end. How to accomplish such a task using xaml?
Try to use Grid with IsSharedSizeScope, instead of StackPanel, like below:
<Grid Grid.IsSharedSizeScope="true" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="buttons"/>
<ColumnDefinition SharedSizeGroup="buttons"/>
<ColumnDefinition SharedSizeGroup="buttons"/>
<ColumnDefinition SharedSizeGroup="buttons"/>
<ColumnDefinition SharedSizeGroup="buttons"/>
</Grid.ColumnDefinitions>
<Button x:Name="PreviousPage" Content="Previous" Grid.Column="0"/>
<Button x:Name="Info" Content="Information" Grid.Column="1"/>
<Button x:Name="InetTicket" Content="Internet ticket" Grid.Column="2"/>
<Button x:Name="FindStation" Content="Find station" Grid.Column="3"/>
<Button x:Name="NextPage" Content="Next" Grid.Column="4"/>
</Grid>
You could also use a uniform grid which will make sure all the buttons are the same size.
Use a UniformGrid:
<UniformGrid Rows="1">
<Button x:Name="PreviousPage"
Content="Previous" />
<Button x:Name="Info"
Content="Information" />
<Button x:Name="InetTicket"
Content="Internet ticket" />
<Button x:Name="FindStation"
Content="Find station" />
<Button x:Name="NextPage"
Content="Next" />
</UniformGrid>

Relative positioning in WPF xaml

Is it possible to position a control in the XAML definiton relative to another control?
for example if I want to place a control exactly in the middle of another wider control.
and if so - how?
If you want to center the controls you could wrap them in a grid:
<Grid>
<TextBox Height="132" Width="229" VerticalAlignment="Center" HorizontalAlignment="Center" />
<Button Content="Button" Height="23" Width="75" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
Other positioning can be accomplished by other panels like StackPanel etc. Grid beeing the most flexible choice.
Edit: updated with grid and columns for controlling position:
<Grid Height="50" Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="75*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Background="Red" />
<Button Content="Button" Grid.Column="2" />
</Grid>

Resources