I have a window in wpf that looks like this with no code-behind:
Now that my form looks like I want it to, I use the following to get data from my SQL Server database and load it into the form:
Private Sub winVehicleExpenses_Loaded(sender As Object, e As RoutedEventArgs) Handles winVehicleExpenses.Loaded
taVehicleExpenses = New PIMDataSetTableAdapters.taVehicleExpenses
taVehicleExpenses.Fill(dsPIM.VehicleExpenses) 'Load all the Expense data into the PIM dataset
Dim dvTypes As DataView = New DataView(dsPIM.Tables("StandardEntries"), "CategoryID = 13", "Entry", DataViewRowState.CurrentRows) 'CategoryID = 13 are the Vehicle Expense Types
With cboTypes
.ItemsSource = dvTypes
.SelectedIndex = 0 'Move to the first entry
End With
End Sub
Now when I run the application, here is what the form looks like:
Note the gap between the "Notes" label and the notes textboxes that was not there before the data were loaded.
How can the simple process of loading data into a listbox and some textboxes change the form layout?
ADDED: Here's the XAML
<Window
x:Class="VehicleExpenses"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="VehicleExpense"
xmlns:local="clr-namespace:PIM"
x:Name="winVehicleExpenses"
Height="490"
Width="440"
ShowInTaskbar="False"
Background="#FFE8FFFD"
IsTabStop="False">
<Window.Resources>
<local:DisplayDateFormatter x:Key="FormatDisplayDate" />
<local:DisplayCurrencyFormatter x:Key="FormatCurrency" />
<local:DisplayFixedFormatter x:Key="FormatSingle" />
<Style x:Key="ItemHeaders" TargetType="Label">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Grid.Row" Value="1" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Bottom" />
</Style>
<Style x:Key="ItemLabels" TargetType="Label">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Width" Value="80" />
<Setter Property="Margin" Value="0,5,0,0" />
</Style>
<Style x:Key="PreviousTextBoxes" TargetType="TextBox">
<Setter Property="Height" Value="26" />
<Setter Property="Margin" Value="0,5,0,0" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Width" Value="80" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="Cornsilk" />
</Style>
<Style TargetType="Button">
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="60" />
<Setter Property="Margin" Value="60,0,0,0" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="30" />
<RowDefinition Height="225" />
<RowDefinition Height="100" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="3"
Orientation="Horizontal"
HorizontalAlignment="Center">
<Label
Height="26"
FontWeight="Bold"
Content="Expense Type:" />
<ComboBox
Name="cboTypes"
Height="26"
Width="120"
FontSize="13"
DisplayMemberPath="Entry"
SelectedValuePath="EntryID"
Background="White" />
</StackPanel>
<Label
Grid.Column="0"
Content="Item"
Width="80"
Style="{StaticResource ItemHeaders}" />
<StackPanel
Grid.Column="0"
Grid.Row="2"
Height="220"
VerticalAlignment="Top">
<Label
Name="lblChargeDate"
Content="Charge Date:"
Style="{StaticResource ItemLabels}" />
<Label
Name="lblMileage"
Content="Mileage:"
Style="{StaticResource ItemLabels}" />
<Label
Name="lblGallons"
Content="Gallons:"
Style="{StaticResource ItemLabels}" />
<Label
Name="lblCharge"
Content="Charge:"
Style="{StaticResource ItemLabels}" />
<Label
Name="lblStartDate"
Content="Start Date:"
Style="{StaticResource ItemLabels}" />
<Label
Name="lblEndDate"
Content="End Date:"
Style="{StaticResource ItemLabels}" />
</StackPanel>
<Label
Content="Previous"
Grid.Column="1"
Width="93"
Style="{StaticResource ItemHeaders}" />
<Label
Content="Current"
Grid.Column="2"
Width="93"
Style="{StaticResource ItemHeaders}" />
<StackPanel
Name="pnlPrevious"
Grid.Column="1"
Grid.Row="2"
Height="220"
VerticalAlignment="Top">
<TextBox
Text="{Binding Path=ChargeDate, Converter={StaticResource FormatDisplayDate}}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<TextBox
Name="txtPreviousMileage"
Text="{Binding Path=Mileage}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<TextBox
Name="txtPreviousGallons"
Text="{Binding Path=Gallons, Converter={StaticResource FormatSingle}, ConverterParameter=3}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<TextBox
Text="{Binding Path=Charge, Converter={StaticResource FormatCurrency}}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<TextBox
Name="txtPreviousStartDate"
Text="{Binding Path=StartDate, Converter={StaticResource FormatDisplayDate}}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<TextBox
Name="txtPreviousEndDate"
Text="{Binding Path=EndDate, Converter={StaticResource FormatDisplayDate}}"
Style="{StaticResource PreviousTextBoxes}"
Focusable="False" />
<Label
Name="lblNotes"
Content="Notes:"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0,0,30,0"
Style="{StaticResource ItemLabels}" />
</StackPanel>
<StackPanel
Grid.Column="2"
Grid.Row="2"
Height="220"
VerticalAlignment="Top">
<DatePicker
Name="dprCurrentChargeDate"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
<TextBox
Name="txtCurrentMileage"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
<TextBox
Name="txtCurrentsGallons"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
<TextBox
Name="txtCurrentCharge"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
<DatePicker
Name="dprCurrentStartDate"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
<DatePicker
Name="dprCurrentEndDate"
HorizontalAlignment="Left"
Height="23"
VerticalAlignment="Top"
Width="120" />
</StackPanel>
<StackPanel
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="3"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Orientation="Horizontal">
<TextBox
Name="txtPreviousNotes"
VerticalAlignment="Stretch"
Width="175"
Text="{Binding Notes}"
Background="Cornsilk"
Focusable="False"
Margin="10,0,0,0"/>
<TextBox
Name="txtCurrentNotes"
VerticalAlignment="Stretch"
Width="175"
Margin="55,0,0,0" />
</StackPanel>
<StackPanel
Grid.Column="0"
Grid.Row="4"
Grid.ColumnSpan="3"
Orientation="Horizontal">
<Button
Name="btnCancel"
Content="Cancel"
IsTabStop="False" />
<Button
Name="btnClose"
Content="Close"
IsTabStop="False" />
<Button
Name="btnView"
Content="View"
IsTabStop="False" />
</StackPanel>
</Grid>
Well, after you posted your code and explained further what you're doing, it's pretty clear what's going on. Label lblNotes is in the pnlPrevious StackPanel, which has its VerticalAlignment property set to Top. It makes no difference that you set the VerticalAlignment in the Label to Bottom, since it's a relative property, which makes little difference in a StackPanel. So, when you collapse some of your controls, the content in the pnlPrevious StackPanel rearranges and occupies only as much space as it needs.
The only way to get content to align to the bottom of the StackPanel, without inserting other panels in it, is to align the StackPanel itself to the Bottom. However, that would be a poor decision for your layout.
To save yourself headache and frustration, move lblNotes out of pnlPrevious and into its own row, just above the StackPanel containing notes textboxes.
There a many ways to create the LayOut in XAML.
Without the actual XAML it is a guessing exercition on how the Lay Out changed.
Related
I started doing the UI for an app in WinForm but I just read about WPF and I decided to re-do my work on it. But since is a new think I ran in a small problem:
As you can see in the screenshot bellow I have 3 vertical buttons that are centered on the main form. How can I achieve the same thing in WPF? I've tried any value I could find to change position but all of them failed.
Here is my main form XAML:
<Window x:Class="YouTubeMusicPlayerWpf.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:YouTubeMusicPlayerWpf"
xmlns:fa="http://schemas.fontawesome.io/icons/"
mc:Ignorable="d" Height="500" Width="900" Background="Black" WindowStyle="None" AllowsTransparency="true" WindowStartupLocation="CenterScreen" Name="mainWindow">
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="6" CornerRadius="0" GlassFrameThickness="0">
</WindowChrome>
</WindowChrome.WindowChrome>
<StackPanel Background="#FF201E2B">
<!-- TitleBar buttons -->
<Grid HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<Button fa:Awesome.Content="WindowMinimize" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="minButton" Click="MinButton_OnClick"></Button>
<Button fa:Awesome.Content="WindowMaximize" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="maxButton" Click="MaxButton_OnClick"></Button>
<Button fa:Awesome.Content="WindowClose" Background="Transparent" Foreground="White" VerticalAlignment="Stretch" Padding="8" BorderThickness="0" WindowChrome.IsHitTestVisibleInChrome="True" Name="closeButton" Click="CloseButton_OnClick"></Button>
</StackPanel>
</Grid>
<!-- Menu Buttons-->
<Grid HorizontalAlignment="Left" VerticalAlignment="Center">
<StackPanel Orientation="Vertical">
<Button fa:Awesome.Content="Youtube" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<Button fa:Awesome.Content="Music" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
<Button fa:Awesome.Content="Download" FontSize="40" Background="#00000000" Foreground="White" BorderBrush="Transparent" Width="80" Height="80" VerticalAlignment="Center" HorizontalAlignment="Center"></Button>
</StackPanel>
</Grid>
</StackPanel>
</Window>
The problem is your root element. Replace the StackPanel by a grid and problem solved.
Bonus : if you are new to WPF, I show you how to refactorize your styles.
<Grid Background="Black">
<Grid.Resources>
<!-- Exemple of a style with a key to reuse -->
<Style x:Key="LeftButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="40" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="Background" Value="#00000000" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Grid.Resources>
<!-- TitleBar buttons -->
<StackPanel
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<StackPanel.Resources>
<!-- Exemple of a implicit styles that will be set to each child with a matching type -->
<!-- Notice there is no x:Key -->
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</StackPanel.Resources>
<Button Content="b1" />
<Button Content="b2" />
<Button Content="b3" />
</StackPanel>
<!-- Menu Buttons -->
<StackPanel
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Vertical">
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
</StackPanel>
</Grid>
Notice there is neither RowDefinitions nor ColumnDefinitions.
Here is how to do the same thing with place to set the content (a red box for exemple).
<Grid Background="Black">
<Grid.Resources>
<!-- Exemple of a style with a key to reuse -->
<Style x:Key="LeftButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="40" />
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="Background" Value="#00000000" />
<Setter Property="Foreground" Value="White" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!-- TitleBar buttons -->
<StackPanel
Grid.Column="1"
HorizontalAlignment="Right"
Orientation="Horizontal">
<StackPanel.Resources>
<!-- Exemple of a implicit styles that will be set to each child with a matching type -->
<!-- Notice there is no x:Key -->
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="8" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</StackPanel.Resources>
<Button Content="b1" />
<Button Content="b2" />
<Button Content="b3" />
</StackPanel>
<!-- Menu Buttons -->
<StackPanel
Grid.RowSpan="2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Orientation="Vertical">
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
<Button Content="icon" Style="{StaticResource LeftButtonStyle}" />
</StackPanel>
<Grid Background="Red" Grid.Row="1" Grid.Column="1"/>
</Grid>
I have a problem with nested template bindings.
Having an ItemsControl with a template, which works great. This template contains a tooltip as well (which shows perfectly).
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
But inside the itemscontrol template, I have a ToggleButton with another template inside it. And I can't seem to show the text over there as well since the binding isn't correct.
Code inside the toggle button
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
What kind of binding or syntax should I put in between the Text tags? I tried several options but none of them seemed to work yet. Currently out of guesses.
Thanks
Complete code snippet
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0" >
<Button Command="{x:Static CobraInfrastructure:Commands.NavigateFromBreadcrumb}" CommandParameter="{Binding Path=Current}" Tag="{Binding DetailPaneText}" x:Name="TextBlock_Detail" Style="{DynamicResource BreadcrumbButton}">
<Button.Resources>
<Style BasedOn="{StaticResource {x:Type ToolTip}}" TargetType="ToolTip">
<Setter Property="Background" Value="#F8F8F8" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Padding" Value="15" />
<Setter Property="MinWidth" Value="300" />
<Setter Property="MinHeight" Value="150" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Button.Resources>
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="HyphenTextBlock" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Path=EntityTitle}" FontSize="12" FontWeight="Bold" Foreground="White" Grid.Row="0" Grid.Column="0"/>
<TextBlock VerticalAlignment="Stretch" Text="{Binding Path=Text, NotifyOnTargetUpdated=True, Mode=OneWay}" FontSize="10" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
</Grid>
</Button>
<ToggleButton Focusable="False" Style="{DynamicResource BreadcrumbOpenButton}" VerticalAlignment="Stretch" HorizontalAlignment="Center" Tag="{Binding Path=DetailPaneText}">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<Border Width="13" Background="#293344">
<fa:FontAwesome Icon="CaretRight" Foreground="White" FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Width" TargetName="DetailTab" Value="200"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Width" TargetName="DetailTab" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsOverview}" Value="True">
<Setter Property="Style" TargetName="TextBlock_Detail" Value="{DynamicResource LinkButton}" />
<Setter Property="FontWeight" TargetName="TextBlock_Detail" Value="Bold" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
You should reference on TemplatedParent in Binding:
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.DetailPaneText}" Foreground="White" />
</StackPanel>
If you trying to bind a tooltip text of a button to the Text property of textblock, you may bind it using the ElementName.
First name your button using x:Name
<Button x:Name="XButton">
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
</Button>
Bind it to text block text using the ElementName.
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding ElementName=XButton, Path=ToolTip.Text}" />
</StackPanel>
I have this:
<Border Background="Gray">
<TextBlock x:Name="Text"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
It looks like this: (There are three of those)
I want it to look like this:
(Border stretching to end of the space + some control over the height of the border.)
p.s. I do not have to use borders, anything that will achieve the same effect will do.
update: This is part of a DataTemplate for a ListBoxItem. It's defined in a style like this:
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border>
<TextBlock x:Name="Text"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
I tried to set the HorizontalAlignment to "Stretch" and it didn't work. Any ideas?
A StackPanel will work if your TextBlock numbers are fixed:
<StackPanel Grid.Column="1">
<StackPanel.Resources>
<Style x:Key="style1" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,5" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
</Style>
</StackPanel.Resources>
<TextBlock Text="Text 1" Style="{StaticResource style1}" />
<TextBlock Text="Text 2" Style="{StaticResource style1}" />
<TextBlock Text="Text 3" Style="{StaticResource style1}" />
</StackPanel>
Or if the TextBlock is generated base on some data source, use an ItemsControl:
<ItemsControl ItemsSource="{Binding}" >
<ItemsControl.Resources>
<Style x:Key="style1" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,5" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="Text" Style="{StaticResource style1}" Text="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The easiest approach is to use grid rows.
Here is an example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="text 1" Background="gray"/>
<TextBlock Grid.Row="2" Text="text 2" Background="gray"/>
<TextBlock Grid.Row="4" Text="text 3" Background="gray"/>
</Grid>
try this...
<Border Background="Gray" HorizontalAlignment="Stretch">
<TextBlock x:Name="Text"
HorizontalAlignment="Left"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"/>
</Border>
At last I found this as the easiest solution to accomplish exactly what I wanted:
I create a grid (with one column and one row)
I create a Rectangle inside (which automatically stretches to the grid space)
I create a textBox (which automatically renders on top of the Rectangle)
Here's how it looks like:
<Grid>
<Rectangle x:Name="fillColor" Fill="..."/>
<TextBox ... />
</Grid>
Okay, so I created a user control for a keypad. It looks like this:
The code for this is:
<DockPanel DockPanel.Dock="Left">
<StackPanel DockPanel.Dock="Left">
<Button Content="1"
Height="60"
Width="60"
Margin="8"
Name="bttnOne" />
<Button Content="4"
Height="60"
Width="60"
Margin="8"
Name="bttnFour" />
<Button Content="7"
Height="60"
Width="60"
Margin="8"
Name="bttnSeven" />
<Button Content="0"
Height="60"
Width="60"
Margin="8"
Name="bttnZero" />
</StackPanel>
<StackPanel DockPanel.Dock="Left">
<Button Content="2"
Height="60"
Width="60"
Margin="8"
Name="bttnTwo" />
<Button Content="5"
Height="60"
Width="60"
Margin="8"
Name="bttnFive" />
<Button Content="8"
Height="60"
Width="60"
Margin="8"
Name="bttnEight" />
<Button Content="."
Height="60"
Width="60"
Margin="8"
Name="bttnDecimal" />
</StackPanel>
<DockPanel DockPanel.Dock="Left">
<StackPanel DockPanel.Dock="Bottom">
<Button Content="Del"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Width="Auto"
Margin="8"
Height="60"
Name="bttnDelete" />
</StackPanel>
<StackPanel DockPanel.Dock="Left">
<Button Content="3"
Height="60"
Width="60"
Margin="8"
Name="bttnThree" />
<Button Content="6"
Height="60"
Width="60"
Margin="8"
Name="bttnSix" />
<Button Content="9"
Height="60"
Width="60"
Margin="8"
Name="bttnNine" />
</StackPanel>
<StackPanel DockPanel.Dock="Left"
Orientation="Horizontal">
<Button Content="Ent"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
Width="60"
Margin="8"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Center"
Height="Auto"
Name="bttnEnter" />
</StackPanel>
</DockPanel>
</DockPanel>
Now, when I added the keypad to the window, the window changes the size of the buttons, like this:
The code for that is:
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<Label Content="New Item"
Style="{StaticResource MyLabel2}"
FontStyle="Italic" />
</StackPanel>
<StackPanel DockPanel.Dock="Left"
Margin="0,20,0,0">
<Label Content="BHA Description"
HorizontalContentAlignment="Right"
FontSize="20" />
<Label Content="" />
<Label Content="OD"
HorizontalContentAlignment="Right"
FontSize="20" />
<Label Content="" />
<Label Content="Length"
HorizontalContentAlignment="Right"
FontSize="20" />
<Label Content="" />
<Button Name="bttnSave"
Content="Save"
Margin="2,14,2,2" />
</StackPanel>
<StackPanel DockPanel.Dock="Left"
Margin="10,20,25,0">
<ComboBox Name="cmbDesc"
HorizontalContentAlignment="Right"
FontSize="23" />
<Label Content="" />
<ComboBox Name="cmbOd"
HorizontalContentAlignment="Right"
FontSize="23" />
<Label Content="" />
<TextBox Text="Length"
HorizontalContentAlignment="Right"
FontSize="25"
MaxLength="10" />
<Label Content="" />
<Button Name="bttnCancel"
Content="Cancel"
Click="bttnCancel_Click"
Margin="2,14,2,2" />
</StackPanel>
<StackPanel DockPanel.Dock="Left">
<UserControls:Keypad />
</StackPanel>
</DockPanel>
Now, I do have a default button style, who's code is:
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="Margin"
Value="2" />
<Setter Property="FontFamily"
Value="Calibri" />
<Setter Property="FontSize"
Value="16px" />
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Height"
Value="75" />
<Setter Property="Width"
Value="150" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
MappingMode="RelativeToBoundingBox"
StartPoint="0.5,0">
<GradientStop Color="#FFF5EFEF"
Offset="0" />
<GradientStop Color="#FFA09C9C"
Offset="0.808" />
<GradientStop Color="#FFA09C9C"
Offset="1" />
<GradientStop Color="#FFF5EFEF"
Offset="0.192" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="2"
Padding="4,2"
BorderBrush="Black"
CornerRadius="7"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Name="contentShadow"
Style="{StaticResource ShadowStyle}">
<ContentPresenter.RenderTransform>
<TranslateTransform X="1.0"
Y="1.0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Name="content" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="border"
Property="BorderBrush"
Value="Red" />
<Setter Property="Foreground"
Value="Red" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Foreground"
Value="#FFFDFDFD" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1"
MappingMode="RelativeToBoundingBox"
StartPoint="0.5,0">
<GradientStop Color="Red"
Offset="0" />
<GradientStop Color="Red"
Offset="1" />
<GradientStop Color="Black"
Offset="0.573" />
<GradientStop Color="Black"
Offset="0.402" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter TargetName="content"
Property="RenderTransform">
<Setter.Value>
<TranslateTransform Y="1.0" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My question is, why are the buttons reverting to the default setting, when I'm hardcoding height/width values in the user control itself? How can I fix it so that it doesn't do that?
I'd use a Grid based layout:
I'd imagine DockPanel and the StackPanel instances are doing some weird stuff - and to be honest if you want a uniform grid such as a keypad, it's the way to go
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="8" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0">1</Button>
<Button Grid.Column="1" Grid.Row="0">2</Button>
<Button Grid.Column="2" Grid.Row="0">3</Button>
<Button Grid.Column="3" Grid.Row="0" Grid.RowSpan="3">Ent</Button>
<Button Grid.Column="0" Grid.Row="1">4</Button>
<Button Grid.Column="1" Grid.Row="1">5</Button>
<Button Grid.Column="2" Grid.Row="1">6</Button>
<Button Grid.Column="0" Grid.Row="2">7</Button>
<Button Grid.Column="1" Grid.Row="2">8</Button>
<Button Grid.Column="2" Grid.Row="2">9</Button>
<Button Grid.Column="0" Grid.Row="3">0</Button>
<Button Grid.Column="1" Grid.Row="3">.</Button>
<Button Grid.Column="2" Grid.Row="3" Grid.ColumnSpan="2">Del</Button>
</Grid>
It will also scale perfectly no matter how big or small you want to make it - if needs be you can do some template bindings to set properties such as the button margins etc. via the usercontrol properties
I don't really ever use DockPanel if I can help it - I don't think it's the most intuitive of controls
Edit: I added your calc layout and the one above side by side in a 400 x 400 area - this is the result
(ignore the 1 button on the grid layout, I explicitly set the width to 150 while I was testing styles and forgot to set it back! If you remove the explicit width it scales perfectly like the other buttons)
You have don't have your LastChildFill property set to False on your top DockPanel. This is the reason "Ent" is changing size and moving your screen.
You also have the HorizontalAlignment on "Del" set to stretch. Try setting that to Left, but might be moot with the LastChildFill correction.
The overall resizing is do to HorizontalAlignment set to Stretch set that to Left.
I have VirtualizingStackPanel in ListBox ItemsPanel. If I set Margin="0,0,0,50" then margin is not showed but if I set left margin (or top or right) Margin="50,0,0,0" then margin works correct.
If I change VirtualizingStackPanel for StackPanel then bottom margin works well.
This Is my code:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<ListBox x:Name="TasksListBox"
Margin="0"
ItemsSource="{Binding Tasks}"
HorizontalAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<!--<StackPanel Margin="0,0,0,14" />-->
<VirtualizingStackPanel Margin="0,0,0,100"
Height="Auto" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Background="White"
Width="455"
Height="105"
Tag="{Binding Id}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Click="Button_Click_1">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="24" />
</Grid.RowDefinitions>
<TextBlock Grid.ColumnSpan="4"
Text="{Binding Name}"
FontSize="24"
Foreground="#400000" />
<Image Grid.Row="1"
Visibility="{Binding Project, Converter={StaticResource StringToVisibilityConverter}}"
Source="/Images/ProjectIcon.png"
Width="20"
Height="18"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,0,5,0" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Visibility="{Binding Project, Converter={StaticResource StringToVisibilityConverter}}"
Text="{Binding Project, Converter={StaticResource ToUppercaseConverter}}"
FontSize="16"
Foreground="#666666"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,-2,9,0"
LineStackingStrategy="BlockLineHeight" />
<Image Grid.Row="1"
Grid.Column="2"
Visibility="{Binding Context, Converter={StaticResource StringToVisibilityConverter}}"
Source="/Images/ContextIcon.png"
Width="20"
Height="18"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="-3,1,1,0" />
<TextBlock Grid.Row="1"
Grid.Column="3"
Visibility="{Binding Context, Converter={StaticResource StringToVisibilityConverter}}"
Text="{Binding Context, Converter={StaticResource ToUppercaseConverter}}"
FontSize="16"
Foreground="#666666"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,-2,0,0"
LineStackingStrategy="BlockLineHeight" />
</Grid>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Flick="GestureListener_Flick_1" />
</toolkit:GestureService.GestureListener>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="False"
BorderBrush="#9c0605"
Foreground="#400000">
<toolkit:MenuItem Header="dokonĨeno"
Foreground="#400000"
Tag="{Binding Id}"
Click="MenuItem_Click_1" />
<toolkit:MenuItem Header="upravit"
Foreground="#400000"
Tag="{Binding Id}"
Click="MenuItem_Click_2" />
<toolkit:MenuItem Header="odstranit"
Foreground="#400000"
Tag="{Binding Id}"
Click="MenuItem_Click_3" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Code Behind
ObservableCollection<string> data = new ObservableCollection<string>();
for (int i = 0; i < 40; i++)
{
data.Add("Item" + i);
}
lbTest.ItemsSource = data;
Xaml
<Grid x:Name="LayoutRoot"
Background="Transparent">
<ListBox x:Name="lbTest">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="{StaticResource PhoneForegroundBrush}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Auto" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="Padding"
Value="0,0,0,150" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer x:Name="ScrollViewer"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</Grid>