How to anchor controls in WPF? - c#

I have a a TreeView that fills the top part of the application, but since the number of items in the TreeView changes, my Apply button changes its position vertically. Is there a way to anchor it to the bottom part of the window, so it's always on the right bottom part of the window, i.e. 10x10 distance from the right bottom edge.

You can either set the HorizontalAlignment and VerticalAlignment on the TreeView or Button (I cannot tell which control you are trying to anchor), or you could place the control inside a DockPanel.
To space the control away from others use the Margin.
Margin="0 0 10 10"
will give you the margin only on the right and bottom
I hope this makes it a bit clearer:
<Window>
<DockPanel VerticalAlignment="Stretch">
<TreeView DockPanel.Dock="Top" />
<Button DockPanel.Dock="Bottom" Margin="0 0 10 10" />
</DockPanel>
</Window>

To achieve anchoring, Set following properties:
Width="auto"
Height="auto"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Set margins as needed.
Example:
<TabControl
Name="tabControl1"
HorizontalAlignment="Stretch"
Margin="40,40,40,40"
Width="auto"
Height="auto"
VerticalAlignment="Stretch">

I think you need this in the XAML of your button:
HorizontalAlignment="Right" VerticalAlignment="Bottom"

Related

DockPanel is not visible even though it is set to visible

I have a DockPanel inside another DockPanel the first one is set to be docked on the whole form, but the second one is set on the top of the form and it has three buttons inside it, the background color of it is set to grey, and I can see the content blue border in the editor but it doesn't have a color or a text in it, and when I run the application there is nothing no button no colors nothing.
Here is the XAML code:
<Grid Background="White">
<DockPanel Name="MainBackground">
<DockPanel Name="Top" Height="32" Background="#FF707070" DockPanel.Dock="Top" Margin="0, 0, 0, 1000">
<Button
Width="46"
Height="32"
DockPanel.Dock="Right"
Margin="687,0,0,398"
Background="White" Click="Button_Click_1">
<StackPanel Orientation="Horizontal">
<Image Source="Res/RDI.png" Width="20" Height="20"/>
</StackPanel>
</Button>
<Button
Width="46"
Height="32"
Content="×"
FontSize="20" DockPanel.Dock="Right" Click="Button_Click" Margin="734,0,0,398" Background="White"/>
</DockPanel>
</DockPanel>
</Grid>
The issue is that you try to position all controls using Margin, which defeats the purpose of a DockPanel. You can select each of the buttons in XAML and look at the designer in Visual Studio. They are all positioned way off. Do not every use this kind of brittle positioning in WPF. There are lots of panels that already take care of that way easier and responsive to resizing.
For example, try the code below. I removed all the Margins and just set the DockPanel.Dock to Right for the buttons. Please note, that you have to set the LastChildFill to false, otherwise the last control placed in the DockPanel will take up the remaining space and is centered in there, regardless of setting a DockPanel.Dock value on it.
If you set the LastChildFill property to true, which is the default setting, the last child element of a DockPanel always fills the remaining space, regardless of any other dock value that you set on the last child element. To dock a child element in another direction, you must set the LastChildFill property to false and must also specify an explicit dock direction on the last child element.
For the outer DockPanel, I just added a new last Grid that takes up the remaining space. If it was not there, you would also have to set the LastChildFill, otherwise the bar would be centered in the window.
<Grid Background="White">
<DockPanel Name="MainBackground">
<DockPanel Name="Top" Height="32" Background="#FF707070" DockPanel.Dock="Top" LastChildFill="False">
<Button
Width="46"
Height="32"
DockPanel.Dock="Right"
Background="White" Click="Button_Click_1">
<StackPanel Orientation="Horizontal">
<Image Source="Res/RDI.png" Width="20" Height="20"/>
</StackPanel>
</Button>
<Button
Width="46"
Height="32"
Content="×"
FontSize="20" DockPanel.Dock="Right" Click="Button_Click" Background="White"/>
</DockPanel>
<StackPanel>
<TextBlock Text="This is where your content would be placed."/>
<TextBlock Text="Alternatively, set the last child fill of the dock panel to false."/>
</StackPanel>
</DockPanel>
</Grid>
Now the buttons are automatically positioned to the right, next to each other.
Of course, you could create the same layout with other panels as well, but since it is not clear what your final layout should look like, I can only provide this example using your structure.
It's here quite sure but with a margin of Margin="0, 0, 0, 1000" propably it's anywhere.
I think this is the issue.
[EDIT] And I see more of these "3 digit margins". Avoid that, it's not how WPF is meant to be used. Use margins as "a little bit of space around the element"

UWP AutoCompleteBox in ContentDialog not sizing correctly - text area larger than drawn

I have an AutoCompleteTextBox in UWP is exhibiting a really odd behavior, and I can't figure out what's causing it. The TextBox is in a Grid, but the user can type past the bounds of the TextBox, so the first and last characters of each line are hidden behind the surrounding border. I've taken some screenshots to hopefully make this make more sense, as it's difficult to describe.
I've tried everything I can think of, but can't seem to get it to stop doing this. The only effect I had at all was in changing the HorizontalAlignment of the TextBox. Originally it was Stretch, and only the right side of the TextBox had cutoff letters. When I changed it to Center, it divided the cut-off section between both the left and right.
Does anybody have any ideas as to what's going on?
In the 1st picture, the actual TextBox area is defined by the box on the far outer edges of the ContentDialog [with the drag handles left of the (116)].
TextBox in VS Designer
In the second picture, the letters typed in the TextBox are 2 W's. If you look closely, you can just see the very right of the 1st W to the left of the full W there.
TextBox during execution
XAML:
<ContentDialog
x:Class="FlipPanelTest2.ComposeTweet"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FlipPanelTest2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
RequestedTheme="Dark"
Title="{Binding SendTo}"
Foreground="Gray"
Width="600"
PrimaryButtonText="Cancel"
SecondaryButtonText="Tweet!"
SecondaryButtonStyle="{StaticResource TweetContentDialogButtonStyle}"
PrimaryButtonStyle="{StaticResource CancelButtonStyle}"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">
<Grid Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox x:Name="tweetText" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Stretch" Background="White" TextWrapping="Wrap" Margin="2" TextChanged="TextBox_TextChanged" MaxHeight="180" MinHeight="112" Width="540" />
<StackPanel x:Name="characterCount" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center">
<TextBlock x:Name="currentChars" HorizontalAlignment="Right" Grid.Row="1" FontSize="10" Text="{Binding TweetCharacters}" />
<TextBlock x:Name="charsDivider" HorizontalAlignment="Right" Grid.Row="1" FontSize="10" Text="/" />
<TextBlock x:Name="maxChars" HorizontalAlignment="Right" Grid.Row="1" FontSize="10" Text="{Binding MaxCharacters}" />
</StackPanel>
</Grid>
Well some more searching found the answer apparently. I hadn't thought to search for a max size on the ContentDialog, hence the reason I didn't find this before. Providing a link to the answer though for future people to use:
Quoted from ContentDialog max width:
In your App.xaml, try setting the ContentDialogMaxWidth to say, 800.
The default is 548. You might want to increase the height too.
<Application.Resources>
<x:Double x:Key="ContentDialogMaxWidth">800</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
</Application.Resources>
ContentDialog max width
It's the last answer listed there, for some reason not the accepted answer. :)

how to give height of a parent to child in UWP

I have a stack panel and it has one grid and I'd like the grid to have same height as stack panel.
I tried playing with VerticalAlignment stretch or height 100% nothing works
I tried setting the values programatically OnNavigatedTo but it doesn't have the effect
Any suggestions to resolve this are welcome
Please find the code below
<StackPanel Grid.Row="0" Grid.RowSpan="4" Background="#CFFF" Visibility="Visible" Orientation="Vertical" Name="ProgressOverlay">
<Grid Name="Overlaygrid"">
<StackPanel VerticalAlignment="Center" Grid.Row="0">
<ProgressBar
IsIndeterminate="True"
IsEnabled="True" Foreground="Black"/>
<TextBlock Visibility="Visible" Foreground="Black" FontSize="25” T HorizontalAlignment="Center" Text="Loading"/>
</StackPanel>
</Grid>
</StackPanel>
A StackPanel takes by default the size needed by its content and shrinks to the size required, while a container control like Grid stretches to the full size available (e.g full page).
If you want to keep the outer StackPanel, you will have to set VerticalAlignment="Stretch" on the StackPanel, not on the Grid.
But since the Grid is the only single content item in your outer StackPanel, you can remove it and move the properties Grid.RowSpan="4" Background="#CFFF" Visibility="Visible" to the Grid. Always try to keep your XAML structure as simple as possible.

XAML WP8 and making a 'TextBlock' scroll down

Alright, so I have a XAML page with a TextBlock in a Windows Phone 8 application. My dilemma is this:
I pragmatically add more content (formatted lines with Inlines.Add(new Run...) to the TextBlock. The text block is currently filled from bottom to up because of the ScrollViewer in the sense that a line appears in the bottom after another. I would also be fine with them starting to appear from the top as long as the TextBlock would continue to scroll down (actually this might look better) once it is full. My TextBlock is inside a ScrollViewer as below:
<Popup x:Name="send_message_xaml" Grid.Row="1" VerticalOffset="0" Width="750" Height="auto">
<StackPanel Orientation="Vertical" Margin="0,0" Width="auto" Height="auto">
<ScrollViewer Height="345" HorizontalAlignment="Left" Margin="0,0,0,0" Name="scrollViewer1" VerticalAlignment="Bottom" Width="420" VerticalScrollBarVisibility="Auto">
<TextBlock x:Name="message_log" Margin="40,50,0,0" TextWrapping="Wrap" Width="420" VerticalAlignment="Top" FontSize="22"/>
</ScrollViewer>
<TextBox x:Name="message_to_send" InputScope="Chat" Width="480" KeyDown="message_to_send_KeyDown" Margin="15,0"/>
</StackPanel>
</Popup>
How can I get the textblock to scroll so that the newest appended message is always at the bottom? I found a bunch of these threads but none seem to solve my problem so far. Do I need to add some code somewhere with the appending?
You need to update the VerticalOffset based on the ScrollableHeight. When you add new inlines to the TextBlock, its height is going to change and that will notify the parent ScrollViewer. So, after you add new items to the inlines, run the Measure method and update the VerticalOffset.
Here is an example.

WPF controls do not align

NOTE: This is one of the first time I'm using WPF.
I am trying to align a certain control, let's say a button for now, in the bottom right corner. But when I debug my application, it misses 8 pixels to the bottom and right. I will attach 2 pictures to show you what happens.
How do I keep the button in place?
My XAML code:
<Window x:Class="Plugin_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Plugin Manager" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid x:Name="GridMain">
<Button Content="Refresh" Margin="432,288,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75"/>
<ListView HorizontalAlignment="Left" Height="273" Margin="10,10,0,0" VerticalAlignment="Top" Width="497">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
If you choose to use Grid layout you should try to avoid placing objects via Margin. Margin should be used to create buffer around an object, not move it to a specific point in the window. Use the layout manager's power to your advantage!
Here is a Grid example that does what you are looking for.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0" />
<Button Grid.Row="1" HorizontalAlignment="Right" Content="Push Me" />
</Grid>
I would also read up on Layout Manager in WPF. There are several; each having its own advantages & disadvantages.
Here is a DockPanel version.
<DockPanel>
<Button DockPanel.Dock="Bottom" HorizontalAlignment="Right" Content="Push Me" />
<ListView />
</DockPanel>
To create your buffer between the button and the window chrome you could do a few different things:
<Grid Margin="10"> will apply a 10 pixel space between all content and the window chrome on all side.
<Grid Margin="0,0,10,10"> would indent all content, but only on the right & bottom.
<Grid Margin="10,0,10,10"> indents all around, except the top (I commonly do this one, with a different margin value).
<Button Margin="0,0,10,10"> would indent only the button from the chrome (this is the direct answer to your comment question).
Replace the Grid above with DockPanel for the second example, or whatever other Layout Manager you are using.
A usability side note: Your confirmation buttons (I'm assuming your button will be an Ok/Cancel type button) should not be indented differently from the rest of your content. All controls that butt up against the right margin should do so at the same point (i.e., you can draw a vertical line down the right side of them all).
So, using your question's example: your button should not be indented 10 pixels to the right while your list box is not. Keeping things lined up will improve the overall look to your application.
(this ends my "usability and look-and-feel is important" side note) :)
<Button VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"/>
Some code example will help. Try using the alignment in xaml for your button as shown below. Ensure that the margins on the button are 0.
<Button Margin="0" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
Looking at the sample code, it is your margins and the alignment you have that are probably causing that.
Just some pointers that may help. Instead of using large margins to align the controls, I find it much easier to work with Column and Row definitions on the grid. This way you can align your controls using the grid and they will size properly as you resize your window. I attached an example in hopes it helps in your new adventures with WPF!
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Version Date" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding DateSubmitted}" Margin="3"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="Report" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding ReportName}" Margin="3"/>
</Grid>

Categories

Resources