WPF textbox selection vertical centering or alignment - c#

I have started to learn WPF and my first task has been to explore the most basic controls, such as the textbox. It has caught my attention as in WPF everything is much more customizable and powerful, but it has caught my attention how the design of the default textbox differs from those of Winforms, acquiring a rather ugly design.
In the following image we see a textbox with the selected text. One textbox with Winforms and one textbox with WPF.
As you can see, in Winforms the upper and lower highlighting space (highlighted in violet) of the selection is distributed equally, while in WPF the upper part is much larger giving a rather "ugly" appearance to the textboxes when the text is selected.
Edit: Seems that some users don't get the problem correctly. So I go to add the xaml of the WPF textbox is next:
<TextBox HorizontalAlignment="Left" Margin="183,172,0,0" Text="TextBox" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
When I change the property to VerticalAlignment="Center" issue is solved until you change the FontSize which makes the problem reappear. The problem is that my font size is 16px.
I would like to know if there is any way to fix this visual misalignment, because I really don't understand why they have left so much space at the top of the text selection.

Probably I should have touched on the cause of the difference between top and bottom spaces of font glyphs. In short, the top space is reserved to draw symbols (diaeresis) above alphabetic characters.
The following code produces the TextBox shown below.
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.ColumnSpan="2"
Text="0ay/AÁÊÑÖ 0ay/AÁÊÑÖ"
FontFamily="Verdana" FontSize="36"
Padding="3"/>
<Rectangle Grid.Column="0"
Stroke="DarkViolet" StrokeThickness="1" StrokeDashArray="1 3"
VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
<Rectangle Grid.Column="1"
Stroke="Red" StrokeThickness="1" StrokeDashArray="1 3"
VerticalAlignment="Center" Margin="0,3,0,0" HorizontalAlignment="Stretch"/>
</Grid>
The area highlighted blue is the font area and the purple dotted line is the actual vertical center of font. If there were no symbol, you may think the red dotted line is the vertical center but it is not true. The font glyphs are slightly aligned to the bottom to accomodate spaces for symbols.
Setting VerticalContentAlignment="Center" can adjust the vertical alignment of the font inside TextBox but can not change the placement of font glyphs inside the font itself. Therefore, I think the only way to make font glyphs (except symbols) shown truly at the vertical center of TextBox is to move the font by arbitary length so as to offset the difference inside font.
Please note that the difference inside font may vary depending on each font and if the height of top space is cut out and if the text which has these symbols is typed, these symbols can be hidden.
That said, you can adjust the inner padding by setting Padding property as follows.
<TextBox Padding="0,-2,0,0" ClipToBounds="True" ... />
Or you can lower the space between font griph and padding by setting the line height of inner text if you do not mind it affects the spacing between multiples lines.
<TextBox Padding="2" FontSize="16"
TextBlock.LineHeight="18" TextBlock.LineStackingStrategy="BlockLineHeight" ... />
Edit: Add explanation and alternative suggestion to respond to OP's comment.

To center the content, in this case the text, you can use VerticalContentAlignment.
<TextBox VerticalContentAlignment="Center"... />
If you set the Height property, try to remove it. This affects the alignment in some way. If you vary the FrontSize, similar problems arise.
To find out how the Text-Property of a TextBox is aligned, I wrote a small app. In this, various properties can be changed using Controls and you can see the result immediately.
The source code of the app comes at the bottom of the answer.
As #emoacht has already described, all glyphs of the font are taken into account when calculating the space requirement.
The reference point for aligning the Text is at the top right.
In order to center a specific text, you could adjust the Padding-Property or the Height and FontSize-Property so that the text is centered.
Please note: I would not follow this approach. Since all of these properties influence each other, inconsistent behavior occurs. It would be enough for the user to enter characters or strings of characters that you hadn't considered and the whole alignment is gone. I think it's more important that the text is presented completely and correctly. And many users wouldn't even notice that the text isn't exactly in the middle.
The source Code of the TextBox - TestApp:
<Window x:Class="TextBoxTestApp.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:TextBoxTestApp"
xmlns:clr="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="TextBox - TestApp -- MK-NEUKO" Height="450" Width="800">
<Window.Resources>
<Style x:Key="testTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border BorderBrush="Black"
BorderThickness="1"
CornerRadius="2">
<Border.Background>
<LinearGradientBrush StartPoint="0, 0" EndPoint="0, 0.25"
SpreadMethod="Repeat">
<GradientStop Color="White"
Offset="0"/>
<GradientStop Color="Gray"
Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0"
Orientation="Horizontal"
Margin="5">
<GroupBox Header="Style Options">
<ComboBox x:Name="styleOptionsComboBox"
Margin="4"
VerticalAlignment="Center"
Width="100">
<ComboBoxItem Tag="{x:Null}"
IsSelected="True"
Content="Default Style"/>
<ComboBoxItem Tag="{StaticResource testTextBoxStyle}"
Content="Custom Style"/>
</ComboBox>
</GroupBox>
<GroupBox Header="TestText"
Width="300">
<TextBox x:Name="inputTestText"
Margin="4"
VerticalContentAlignment="Center"
Text="{Binding ElementName=testTextBox, Path=Text}"/>
</GroupBox>
<GroupBox Header="FontSize">
<StackPanel Orientation="Horizontal"
Margin="5">
<ComboBox x:Name="frontSizeSelect"
Margin="0,0,5,0">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="{Binding ElementName=fontSizeSlider, Path=Value}" Content="On"/>
</ComboBox>
<Slider x:Name="fontSizeSlider"
TickFrequency="2"
Minimum="10"
Maximum="100"
TickPlacement="BottomRight"
Width="200"/>
<TextBlock Text="{Binding ElementName=fontSizeSlider, Path=Value, StringFormat=Value: {0:0}}"/>
</StackPanel>
</GroupBox>
<GroupBox Header="Height">
<StackPanel Orientation="Horizontal"
Margin="5">
<ComboBox x:Name="heightSelect"
Margin="0,0,5,0">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="{Binding ElementName=heightSlider, Path=Value}" Content="On"/>
</ComboBox>
<Slider x:Name="heightSlider"
TickFrequency="4"
Minimum="20"
Maximum="200"
TickPlacement="BottomRight"
Width="200"/>
<TextBlock Text="{Binding ElementName=heightSlider, Path=Value, StringFormat=Value: {0:0}}"/>
</StackPanel>
</GroupBox>
<GroupBox Header="VerticalAlignment">
<ComboBox x:Name="verticalAlignment"
Margin="4">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="Bottom" Content="Bottom"/>
<ComboBoxItem Tag="Center" Content="Center"/>
<ComboBoxItem Tag="Stretch" Content="Stretch"/>
<ComboBoxItem Tag="Top" Content="Top"/>
</ComboBox>
</GroupBox>
<GroupBox Header="VerticalContentAlignment">
<ComboBox x:Name="verticalContentAlignment"
Margin="4">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="Bottom" Content="Bottom"/>
<ComboBoxItem Tag="Center" Content="Center"/>
<ComboBoxItem Tag="Stretch" Content="Stretch"/>
<ComboBoxItem Tag="Top" Content="Top"/>
</ComboBox>
</GroupBox>
<GroupBox Header="HorizontalAlignment">
<ComboBox x:Name="horizontalAlignment"
Margin="4">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="Center" Content="Center"/>
<ComboBoxItem Tag="Left" Content="Left"/>
<ComboBoxItem Tag="Right" Content="Right"/>
<ComboBoxItem Tag="Stretch" Content="Stretch"/>
</ComboBox>
</GroupBox>
<GroupBox Header="HorizontalContentAlignment">
<ComboBox x:Name="horizontalContentAlignment"
Margin="4">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="Center" Content="Center"/>
<ComboBoxItem Tag="Left" Content="Left"/>
<ComboBoxItem Tag="Right" Content="Right"/>
<ComboBoxItem Tag="Stretch" Content="Stretch"/>
</ComboBox>
</GroupBox>
<GroupBox Header="Select FontFamily">
<StackPanel Orientation="Horizontal"
Margin="4">
<ComboBox x:Name="selectFontFamily">
<ComboBoxItem Tag="{x:Null}" Content="x:Null" IsSelected="True"/>
<ComboBoxItem Tag="{Binding ElementName=fontFamilyTextBox, Path=Text}" Content="On"/>
</ComboBox>
<TextBox Margin="10,0,0,0" x:Name="fontFamilyTextBox" Width="300"/>
</StackPanel>
</GroupBox>
</WrapPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<GroupBox Header="Padding Left">
<Slider x:Name="paddingLeftSlider"
Minimum="0"
Maximum="20"
TickFrequency="1"
TickPlacement="BottomRight"
IsSnapToTickEnabled="True"
ValueChanged="PaddingSliderValueChanged"/>
</GroupBox>
<GroupBox Header="Padding Top">
<Slider x:Name="paddingTopSlider"
Minimum="0"
Maximum="20"
TickFrequency="1"
TickPlacement="BottomRight"
IsSnapToTickEnabled="True"
ValueChanged="PaddingSliderValueChanged"/>
</GroupBox>
</StackPanel>
<GroupBox Grid.Column="1"
Header="Padding">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
Text="{Binding ElementName=paddingTopSlider, Path=Value}"
x:Name="paddingTopDisplay"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="Black"/>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding ElementName=paddingLeftSlider, Path=Value}"
x:Name="paddingLeftDisplay"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="Black"/>
<TextBox Grid.Column="1"
x:Name="paddingThicknesObject"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBox Grid.Column="2"
Text="{Binding ElementName=paddingRightSlider, Path=Value}"
x:Name="paddingRightDisplay"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="Black"/>
</Grid>
<TextBox Grid.Row="2"
Text="{Binding ElementName=paddingBottomSlider, Path=Value}"
x:Name="paddingBottomDisplay"
VerticalAlignment="Center"
HorizontalAlignment="Center"
BorderBrush="Black"/>
</Grid>
</GroupBox>
<StackPanel Grid.Column="2">
<GroupBox Header="Padding Right">
<Slider x:Name="paddingRightSlider"
Minimum="0"
Maximum="20"
TickFrequency="1"
TickPlacement="BottomRight"
IsSnapToTickEnabled="True"
ValueChanged="PaddingSliderValueChanged"/>
</GroupBox>
<GroupBox Header="Padding Bottom">
<Slider x:Name="paddingBottomSlider"
Minimum="0"
Maximum="20"
TickFrequency="1"
TickPlacement="BottomRight"
IsSnapToTickEnabled="True"
ValueChanged="PaddingSliderValueChanged"/>
</GroupBox>
</StackPanel>
</Grid>
<TextBox Grid.Row="2"
x:Name="testTextBox"
Style="{Binding ElementName=styleOptionsComboBox, Path=SelectedItem.Tag}"
Text="{Binding ElementName=inputTestText, Path=Text}"
FontSize="{Binding ElementName=frontSizeSelect, Path=SelectedItem.Tag}"
Height="{Binding ElementName=heightSelect, Path=SelectedItem.Tag}"
VerticalAlignment="{Binding ElementName=verticalAlignment, Path=SelectedItem.Tag}"
VerticalContentAlignment="{Binding ElementName=verticalContentAlignment, Path=SelectedItem.Tag}"
HorizontalAlignment="{Binding ElementName=horizontalAlignment, Path=SelectedItem.Tag}"
HorizontalContentAlignment="{Binding ElementName=horizontalContentAlignment, Path=SelectedItem.Tag}"
FontFamily="{Binding ElementName=selectFontFamily, Path=SelectedItem.Tag}">
</TextBox>
</Grid>
</Window>
And the Code-Behinde:
namespace TextBoxTestApp
{
public partial class MainWindow : Window
{
private double _paddingLeft;
private double _paddingRight;
private double _paddingTop;
private double _paddingBottom;
private Thickness _paddingTestTextBox;
public MainWindow()
{
InitializeComponent();
_paddingTestTextBox = new Thickness(0,0,0,0);
}
private void PaddingSliderValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
ResetPaddingDisplayBorderBrush();
var currentSlider = (Slider)sender;
switch(currentSlider.Name)
{
case "paddingLeftSlider":
_paddingLeft = currentSlider.Value;
paddingLeftDisplay.BorderBrush = Brushes.Red;
break;
case "paddingTopSlider":
_paddingTop = currentSlider.Value;
paddingTopDisplay.BorderBrush = Brushes.Red;
break;
case "paddingRightSlider":
_paddingRight = currentSlider.Value;
paddingRightDisplay.BorderBrush = Brushes.Red;
break;
case "paddingBottomSlider":
_paddingBottom = currentSlider.Value;
paddingBottomDisplay.BorderBrush = Brushes.Red;
break;
default: throw new ArgumentException("PaddingSliderValueChanged");
}
SetPaddingTestTextBox();
}
private void ResetPaddingDisplayBorderBrush()
{
paddingLeftDisplay.BorderBrush = Brushes.Black;
paddingTopDisplay.BorderBrush= Brushes.Black;
paddingRightDisplay.BorderBrush = Brushes.Black;
paddingBottomDisplay.BorderBrush = Brushes.Black;
}
private void SetPaddingTestTextBox()
{
_paddingTestTextBox.Left = _paddingLeft;
_paddingTestTextBox.Top = _paddingTop;
_paddingTestTextBox.Right = _paddingRight;
_paddingTestTextBox.Bottom = _paddingBottom;
paddingThicknesObject.Text = _paddingTestTextBox.ToString();
testTextBox.Padding = _paddingTestTextBox;
}
}
}

Related

C# WPF - Dockpanel's children collapsed not resizing the other visible childs

I'm sorry if I didn't find any relative post/questions regarding my small annoying issue.
I have a WPF window with a DockPanel (LastChildFill = True) that hosts three controls :
One Button (OK)
One label (Title)
One Border with a listbox in it
What I do is when the test in process is "pass" it has no data to push in the listbox so I make it collapsed and then I would like the Title label to be centered in the available space that is not used by the listbox and its border.
When I have a "fail" or an "error", I have data to put in the listbox and then it is visible and everything is just as expected.
I tried many things before coming here and I lost enough time on this as I need to get other stuff done by the time I'm writing here.
Can anyone point me out how to solve my issue (centering label when listbox+border is collapsed) ?
Here is my xaml code for this window :
<Window x:Class="NI.TestStand.WPFControls.Views.DisplayBannerView"
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:NI.TestStand.WPFControls"
mc:Ignorable="d"
Title="DisplayBanner" x:Name="DisplayBannerMessage" Height="500" Width="800" MinHeight="300" MinWidth="500">
<Window.Resources>
<Style x:Name="BaseWindowFont" TargetType="Window">
<Setter Property="FontFamily" Value="Arial"></Setter>
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</Window.Resources>
<Grid>
<Border BorderBrush="Black" BorderThickness="2">
<DockPanel LastChildFill="True">
<Button
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click"/>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Border>
</Grid>
</Window>
Here are the images that shows a PASS and an ERROR to show the difference.
The PASSED title message in the green lime window should go in the middle of the window as the listbox is collapsed..
Thanks for all your help and time
I would design the whole thing like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="2"
Grid.RowSpan="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToRowSpanConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border Grid.Row="1" BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border"
Visibility="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToVisibilityConverter}}">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
<Button Grid.Row="2"
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click" />
</Grid>
</Border>
</Grid>
There are two bindings to PassErrorBooleanProperty (which I've made up as something you'd use to indicate the result, you might have something else in place for this already), and you'd need two different converters, one for converting to a Visibility, and one for converting to an int (Grid.RowSpan).
When the value is true (Pass), you'd return Visibility.Collapsed and 2 from the converters. When the value is false, you'd return Visibility.Visible and 1.
Let me know if you need more info on the converters, though there is lots of information out there on using IValueConverter to create Boolean to Visibility converters, etc.

Fixed sized usable page with Template 10 with Hamburger?

I'm trying to create a drawing surface within a Template 10 UWP Hamburger template app with a template image in the background. Is there any way to force the main visual space to be non-scrollable? When I use the following XAML, the image expands off the screen as I stretch the app window wider.
<!-- content -->
<StackPanel EntranceNavigationTransitionInfo.IsTargetElement="True"
Padding="12,8,0,0"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="pageHeader">
<StackPanel Orientation="Horizontal">
<ComboBox Name="TemplateComboBox" ItemsSource="{x:Bind _templates}" SelectionChanged="TemplateComboBox_SelectionChanged" PlaceholderText="Select a template...">
<ComboBoxItem Content="{Binding}" />
</ComboBox>
<TextBlock x:Name="stateTextBox"
Margin="16,0,0,0"
Text="Current Visual State" />
</StackPanel>
<Grid Name="DrawingGrid" Margin="0,5,5,5" >
<Image Name="TemplateImage" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Uniform" />
</Grid>
</StackPanel>
There is code in the code-behind to set the Image source as the combo selection changes. I just want the image to stretch to the current viewable area.
sigh Haven't even started with the Ink yet :(
You could think about detecting the visible area's width and height, then set the width and height as your image control's width and height.
<Grid EntranceNavigationTransitionInfo.IsTargetElement="True"
Padding="12,8,0,0"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="pageHeader">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="9*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ComboBox Name="TemplateComboBox" PlaceholderText="Select a template...">
<ComboBoxItem Content="{Binding}" />
</ComboBox>
<TextBlock x:Name="stateTextBox"
Margin="16,0,0,0"
Text="Current Visual State" />
</StackPanel>
<Grid Margin="0,5,5,5" x:Name="grid" Grid.Row="1">
<ScrollViewer Name="scrollviewer" Width="{Binding ElementName=grid,Path=Width}" Height="{Binding ElementName=grid,Path=Height}" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<Image Name="TemplateImage" VerticalAlignment="Stretch" Source="/Assets/pic.jpg" HorizontalAlignment="Stretch" Stretch="Uniform" />
</ScrollViewer>
</Grid>
</Grid>
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
TemplateImage.Width = scrollviewer.ViewportWidth;
TemplateImage.Height = scrollviewer.ViewportHeight;
}

Some controls are not stretching [duplicate]

This question already has an answer here:
WPF Grid horizontalalignment doesn't work. Sizes don't changes
(1 answer)
Closed 8 years ago.
In this window I have many different controls and I want to stretch which is possible
but there are some controls by 'stackGroup', 'listBox1', 'listBox2' that don't stretching.. Why ??
Also is this way i right to do this kind of pages
<Window x:Class="TwoColumnGridSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Window_Loaded"
Title="Window1" Height="759" Width="800">
<Grid Margin="0,0,0,95">
<Grid.RowDefinitions>
<RowDefinition Height="509"></RowDefinition>
<RowDefinition Height="111"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="472" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="165" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Stretch" Margin="0,0,0,163">
<ListBox Name="listBox1" SelectedItem="{Binding SelectedItem}" Width="165" ItemsSource="{Binding Buttons}" SelectionChanged="ListBox_SelectionChanged" HorizontalContentAlignment="Left" VerticalAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding .}" Click="Button_Click" Style="{StaticResource listboxbuttons}"></Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<StackPanel Name="stackGroup" HorizontalAlignment="Stretch" Grid.Column="1" Height="457" VerticalAlignment="Top" >
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="460" Margin="0,0,10,0" >
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="24" />
<RowDefinition Height="316"/>
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Image x:Name="imageMap" Source="Resources/images.jpg" HorizontalAlignment="Stretch" Grid.Row="0" Stretch="Fill" Margin="2,0,0,0" />
<Border BorderBrush="Green" BorderThickness="3" CornerRadius="1,1,1,1" Margin="2,4,0,17" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">
<Grid Grid.Row="1" Margin="3,3,3,3">
<GroupBox Header="Club Badge" HorizontalAlignment="Left" VerticalAlignment="Top" Height="123" Width="134"/>
<GroupBox Header="Goalie" HorizontalAlignment="Left" VerticalAlignment="Top" Height="179" Width="134" Margin="0,128,0,0"/>
<GroupBox Header="Defender" HorizontalAlignment="Left" Margin="139,0,0,0" VerticalAlignment="Top" Height="307" Width="134"/>
<GroupBox Header="MidFielder" HorizontalAlignment="Left" Margin="278,0,0,0" VerticalAlignment="Top" Height="307" Width="134"/>
<GroupBox Header="GroupBox" HorizontalAlignment="Left" Margin="417,0,0,0" VerticalAlignment="Top" Height="307" Width="155"/>
</Grid>
</Border>
<ProgressBar BorderBrush="#FF6081B0" HorizontalAlignment="Stretch" Margin="2,303,0,43" Value="45" Grid.Row="2" Foreground="#FF6081B0" Grid.RowSpan="2" />
</Grid>
</StackPanel>
</Grid>
<ListBox Height="96" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Bottom" Name="listBox2" Width="782" Grid.RowSpan="2">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="30 0 30 0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Vertical Item 1" />
<ListBoxItem Content="Vertical Item 2" />
<ListBoxItem Content="Vertical Item 3" />
<ListBoxItem Content="Vertical Item 4" />
<ListBoxItem Content="Vertical Item 5" />
</ListBox>
</Grid>
</Window>
Same answer as in this question. StackPanel will not respect stretch alignments in the same direction as its orientation. So a StackPanel whose orientation is vertical will not respect a VerticalAlignment of stretch for a child.
listBox1 doesn't stretch because it's VerticalAlignment is stretch and it's container StackPanel has an orientation of Vertical (that's its default). You could change that StackPanel to be horizontal, replace it with another container (such as a DockPanel), or remove it entirely since it only contains one element.
Similar reasoning can be applied to your other issues

ComboBox push the controls under it

Like any combobox in WP when the combobox is opened (expanded) it pushes the controls under it down.
In my app when it is opened some of it is hidden because another control is over it.
How can i make all the controls goes down when the combo box is opened.
I want to make like this
What i have is like this
--EDIT
My xaml Code is
<Grid x:Name="addingBabyGrid" HorizontalAlignment="Center" Height="412" VerticalAlignment="Center" Width="323">
<Grid.Background>
<SolidColorBrush Color="White" Opacity="0.9"/>
</Grid.Background>
<StackPanel Orientation="Vertical">
<TextBox HorizontalAlignment="Center" Height="41" TextWrapping="Wrap" Text="Name" VerticalAlignment="Top" Width="303"/>
<ComboBox HorizontalAlignment="Center" Height="53" Width="298" RequestedTheme="Light" Background="Black">
<ComboBoxItem Content="Male"/>
<ComboBoxItem Content="Female"/>
</ComboBox>
<DatePicker Width="293" HorizontalAlignment="Center" Foreground="White" Background="Black" BorderBrush="#FF7E7E7E" RequestedTheme="Light"/>
</StackPanel>
</Grid>
I think what you should be using is the ListPicker from the Silverlight Toolkit for Windows Phone for the task you need. Also, your issue is mostly that you have set the height of the ComboBox explicitly, which does not allow it to show the other items.
See my code that works as you want:
<Grid x:Name="addingBabyGrid" HorizontalAlignment="Center" Height="412" VerticalAlignment="Center" Width="323">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" HorizontalAlignment="Center" Height="41" TextWrapping="Wrap" Text="Name" VerticalAlignment="Top" Width="303"/>
<wpToolkit:ListPicker Grid.Row="1" HorizontalAlignment="Center" Width="298">
<ComboBoxItem Content="Male"/>
<ComboBoxItem Content="Female"/>
</wpToolkit:ListPicker>
<DatePicker Width="293" HorizontalAlignment="Center" Foreground="White" Background="Black" BorderBrush="#FF7E7E7E" RequestedTheme="Light"/>
</Grid>
Generally, when using controls like StackPanel and Grid, you do not want to set the height and width of an element, but leave them to be automatically set by either the container, the controls content or both.

Failing To Set The Wrap Panel Functionailty On Dynamically generated Groupboxes

Hi buddies :) I am working on a wpf app which deals with groupboxes and wrap panel. Looking at the title, it seems to be simple but after dynamically generating set of groupboxes I am finding it difficult. Here is the scenario:
I have 2 xaml files in my project. One is CodecView.xaml and CodecWidgetView.xaml. I have dynamically generated 4 groupboxes on startup as follows:
CodecView.xaml:
<UserControl.Resources>
<DataTemplate x:Key="CWDataTemplate">
<WrapPanel>
<TextBlock Text="{Binding Description}" Margin="0,0,0,0"/>
<local:CodecWidgetView Margin="5,10,5,5"/>
</WrapPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Grid.Row="0" >
<Grid Name="NumberofCodecs" >
<ItemsControl ItemTemplate="{StaticResource CWDataTemplate}" ItemsSource="{Binding CodecWidgets}"/>
</Grid>
</Grid>
CodecWidgetView.xaml:
<Grid>
<GroupBox Height="Auto" HorizontalAlignment="Stretch" Margin="5,5,5,5" Name="groupBox1" VerticalAlignment="Stretch" Width="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton Name="FrequencyBox" Content="Master" Grid.Column="1" Height="25" Width="50" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0" />
<ComboBox Grid.Column="2" ItemsSource="{Binding ModesList}" SelectedItem="{Binding SelectedModesList, Mode=OneWayToSource}" SelectedIndex="2" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox2" VerticalAlignment="Center" Width="80" />
<ComboBox Grid.Column="0" ItemsSource="{Binding FrequencyList}" SelectedItem="{Binding SelectedFrequencyList, Mode=OneWayToSource}" SelectedIndex="0" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox1" VerticalAlignment="Center" Width="80" />
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Command="{Binding OneSixBitCommand}" Margin="0" Content="16 Bit" Name="OneSixBit" Height="25" Width="45" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" />
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Command="{Binding TwoZeroBitCommand}" Margin="0" Content="20 Bit" Name="TwoZeroBit" Height="25" Width="45" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Command="{Binding TwoFourBitCommand}" Margin="0" Content="24 Bit" Name="TwoFourBit" Height="25" Width="45" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Command="{Binding ThreeTwoBitCommand}" Margin="0" Content="32 Bit" Name="ThreetwoBit" Height="25" Width="45" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="2">
<Label Name="BitDelay" Content="Bit Delay" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,205,0" Height="25" Width="55" />
<Slider Height="23" HorizontalAlignment="Center" Minimum="0.0" Maximum="255.0" TickFrequency="1.0" Margin="95,0,0,0" Name="bitdelayslider" VerticalAlignment="Center" Width="160" />
<TextBox Name="BitDelayValue" IsReadOnly="True" Text="{Binding ElementName=bitdelayslider,Path=Value, StringFormat=0.0}" Width="40" Height="20" Margin="0,0,110,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="3">
<Label Name="DBGain" Content="DB Gain" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,205,0" Height="25" Width="55" />
<TextBox Name="DBGainValue" IsReadOnly="True" Text="{Binding ElementName=dbgainslider,Path=Value, StringFormat=0.0}" Width="40" Height="20" Margin="0,0,110,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Slider Height="23" HorizontalAlignment="Center" Minimum="0.0" Maximum="59.5" TickFrequency="0.5" Margin="95,0,0,0" Name="dbgainslider" VerticalAlignment="Center" Width="160" />
</Grid>
</Grid>
</GroupBox>
</Grid>
CodecViewModel.cs: is a viewmodel class of CodecView.xaml
public ObservableCollection<CodecWidgetViewModel> CodecWidgets { get; set; }
public CodecViewModel()
{
CodecWidgets = new ObservableCollection<CodecWidgetViewModel>();
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 8 - Dig Mic A" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 9 - Dig Mic B" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 10 - PCM A 3P3V" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 11 - PCM B 3P3V" });
}
CodecWidgetViewModel.cs: is a viewmodel class of CodecWidgetView.xaml
private string _description;
public string Description
{
get
{
return _description;
}
set
{
_description = value;
OnPropertyChanged("Description");
}
}
This on startup dynamically generates 4 groupboxes one below the other. Since my windowsize is minheight = 300 and minwidth = 300, I have set scrollviewer. Since I have used Wrappanel, When i stretch it, it should behave as expected. That's when width is stretched 2nd groupbox should go to the right side of 1st row and same happens below.
On Startup:
When Width is Stretched:
Expected behaviour:
Thus looking at the expected behaviour, I want to achieve how wrappanel behaves :) Even though I have used wrappanel but it doesn't wrk as expected. Please help :)
You have used a WrapPanel as the panel of each individual item in the ItemsSource, which is not doing what you want.
Instead you have to explicitly tell the ItemsControl to use a WrapPanel as the panel for all of its children.
<ItemsControl ItemTemplate="{StaticResource CWDataTemplate}" ItemsSource="{Binding CodecWidgets}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

Categories

Resources