Here is the usercontrol which is used in my WP8 app. It displays current time. The fontsize is specified by the screen which uses this control. I want AM to be on top but with inline with the text.
Here is my XAML code for control. Also note that Typography.Variants is not supported in WP8
<TextBlock Text="{Binding BindingHour}" FontWeight="Bold" Name="txtHour"
Grid.Row="0" Grid.Column="0"
FontSize="{Binding BindingHourFontSize}" />
<TextBlock Text=":" FontWeight="ExtraLight"
Grid.Row="0" Grid.Column="1"
FontSize="{Binding BindingColonFontSize}" />
<TextBlock Text="{Binding BindingMinute}" FontWeight="Thin"
Grid.Row="0" Grid.Column="2"
FontSize="{Binding BindingMinuteFontSize}"/>
<TextBlock Text="{Binding BindingAmPm}" FontWeight="SemiBold" Grid.Row="0" Grid.Column="3" />
<TextBlock Grid.Row="1" HorizontalAlignment="Center" FontWeight="SemiBold"
Text="{Binding BindingFreeText}" Grid.ColumnSpan="5"/>
Here is how it looks on the screen where i use above control.
Here is how i want it to look but not able to do it in XAML. Also, superscript and subscript is not supported in WP XAML. odd.
Well, it appears that you can do it the same way it is done via WPF, through the Typography.Variants attached property.
http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.documents.typography.variants(v=vs.105).aspx
which allows you to specify superscript/subscript variants of the font. However, that's not really what you want. Your AM/PM appears vertically aligned within the grid control. If it appears too high relative to neighboring characters, simply push it down via its Margin.
Here is an example of the layout
<Grid
Width="auto"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Grid.Row="0"
FontSize="80"
Text="09"/>
<TextBlock
Grid.Column="1"
Grid.Row="0"
VerticalAlignment="Center"
FontSize="50"
Text=":"/>
<TextBlock
Grid.Column="2"
Grid.Row="0"
FontSize="80"
Text="11"/>
<TextBlock
Margin="0 20 0 0"
Grid.Column="3"
Grid.Row="0"
FontSize="20"
Text="AM"/>
</Grid>
And a snapshot of how it looks
To keep relative positions the same while stretching/compressing to fill existing space, use ViewBoxes.
If you create the following, and paste the grid into each of the following ViewBoxes
<Grid
Width="auto"
Height="auto"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Viewbox Grid.ColumnSpan="2"></Viewbox>
<Viewbox Grid.Row="1"></Viewbox>
<Viewbox Grid.Row="1" Grid.Column="1"></Viewbox>
</Grid>
you get the following
Related
In XAML, we typically have <Grid> layout which contains different elements. How do I align a control in one cell of grid to a control in a different cell like below?
(This used to be rather common in traditional applications where controls maybe in different group boxes etc but we still want to align them horizontally in one plane)
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column ="0">
<TextBox x:Name="name" Height="50"/>
<Label Content="John"/>
</StackPanel>
<StackPanel Grid.Column ="2">
<RadioButton Content="Option1"/>
</StackPanel>
</Grid>
The result is below which is ugly:
In this case, I just want to option1 to aligned centered with the TextBox (which does have custom height).
I can use margins to bring it to the desired position but that's kind of hard coded and not too WPFish.
Should I use binding to tie them directly? Is there a better way? Another way I can think of is to keep making grids within grids but seems like that will over complicate for this simple thing?
Try putting them both in another Grid or a horizontal StackPanel, and put that in one of the parent Grid cells.
The following did the trick, basically wrap the <RadioButton> around in <Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column ="0">
<TextBox x:Name="name" Height="50"/>
<Label Content="John"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Top">
<Border BorderBrush="{x:Null}" Height="50">
<RadioButton Content="Option1" Margin="10,0,0,0" VerticalAlignment="Center"/>
</Border>
</StackPanel>
</Grid>
This answer helped.
Now the result is:
Three variants.
The first - I will supplement #zar: I use size binding instead of explicitly assigning a value to the size.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column ="0">
<TextBox x:Name="name" Height="50"/>
<Label Content="John"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Top">
<Border BorderBrush="{x:Null}" Height="{Binding ActualHeight, ElementName=name, Mode=OneWay}">
<RadioButton Content="Option1" Margin="10,0,0,0" VerticalAlignment="Center"/>
</Border>
</StackPanel>
</Grid>
Second - I am implementing #Mark Feldman proposal: Delete StaskPanel and add lines to the grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="name" Height="50"/>
<Label Content="John"
Grid.Row="1"/>
<RadioButton Content="Option1" Margin="10,0,0,0" VerticalAlignment="Center"
Grid.Column="1"/>
</Grid>
The third - analogous to the first, but without the Border.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column ="0">
<TextBox x:Name="name" Height="50"/>
<Label Content="John"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Top">
<RadioButton Content="Option1" Margin="10,0,0,0" VerticalAlignment="Center" VerticalContentAlignment="Center"
Height="{Binding ActualHeight, ElementName=name, Mode=OneWay}"/>
</StackPanel>
</Grid>
I am trying to achieve the following view in downloads section of my app. But I cant seem to get it right.
I also tried to Google it but came up with nothing.
I know this is ListView and I can use a Grid but then I have to create multiple Columns in it and give them fixed width to get a good view but it doesn't seem right because it is supposed to be an adaptive view so how fixed width will help?
And if I provide * as width the Column goes to 0 and it doesn't work as I expect it to.
I also used RelativePanel mixed with StackPanel but that only worsens the view because when I resize the window the list doesn't get resized but stays at its original size.
Any help in this regard will be appreciated.
Update 13-Dec-2016
Downloads.xaml
<ListView Grid.Row="2"
x:Name="DownloadListView"
ItemsSource="{x:Bind DownloadList, Mode=OneWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
FontWeight="Bold"
TextTrimming="CharacterEllipsis"
Grid.ColumnSpan="2"/>
<TextBlock Text="{Binding Type}"
TextWrapping="Wrap"
Grid.Row="2"/>
<StackPanel Orientation="Horizontal"
Grid.Row="3"
Grid.ColumnSpan="2">
<TextBlock Text="MBs Received:"
Width="100"/>
<TextBlock Text="{Binding BytesReceived}"
HorizontalAlignment="Right"
/>
</StackPanel>
<StackPanel Orientation="Horizontal"
Grid.Row="4"
Grid.ColumnSpan="2">
<TextBlock Text="Total MBs:"
Width="100"/>
<TextBlock Text="{Binding TotalBytesToReceive, Mode=OneWay}"
HorizontalAlignment="Right"/>
</StackPanel>
<ProgressBar Value="{Binding Progress}"
Height="10"
Width="200"
HorizontalAlignment="Left"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="5"/>
<Button Grid.Column="3"
Grid.Row="1"
Grid.RowSpan="2"
HorizontalAlignment="Center"
Background="Transparent"
Width="80"
Click="PauseResumeButton_Click"
Content="{Binding PauseResume, Mode=OneWay}"/>
<Button Grid.Column="3"
Grid.Row="3"
Grid.RowSpan="2"
Width="80"
HorizontalAlignment="Center"
Background="Transparent"
Click="CancelButton_Click"
Content="Cancel"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is only the ListView part of the page.
This doesn't work as the above image but it's somewhat close to it. This list view is only wide enough to put the items in it. It is not responsive as the UI changes but it's usable on mobile (I haven't checked on mobile) and pc. As it can be seen within the XAML design interface.
I have an issue I cannot figure out. I hope I can explain things enough.
Basically, I have a usercontrol that I'm looking to use as a sort of in window modal dialog.
<Grid>
<Rectangle Opacity=".75" Fill="White"/>
<Border Width="425" BorderBrush="LightGray" BorderThickness="2" CornerRadius="20,0,20,0" Padding="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="15"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- First Name -->
<Label Grid.Row="0" Grid.Column="0" Content="First Name:"/>
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding FirstName}" Margin="3"/>
<!-- Last Name -->
<Label Grid.Row="0" Grid.Column="3" Content="Last Name:"/>
<TextBox Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="2" Text="{Binding LastName}" Margin="3"/>
<!-- Address -->
<Label Grid.Row="1" Grid.Column="0" Content="Address:"/>
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding Address}" HorizontalAlignment="Stretch" Margin="3"/>
<!-- City -->
<Label Grid.Row="2" Grid.Column="0" Content="City:"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding City}" Margin="3"/>
<!-- State -->
<Label Grid.Row="2" Grid.Column="2" Content="State:"/>
<ComboBox Grid.Row="2" Grid.Column="3" ItemsSource="{Binding States}" SelectedValue="{Binding State}" Margin="3"/>
<!-- Zip Code -->
<Label Grid.Row="2" Grid.Column="4" Content="Zip Code:"/>
<TextBox Grid.Row="2" Grid.Column="5" Text="{Binding ZipCode}" Margin="3"/>
<Button Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="6" Width="100" HorizontalAlignment="Center" Content="Save" Command="{Binding SaveCustomerCommand}"/>
</Grid>
</Border>
</Grid>
I also have a resourcedictionary containing a datatemplate to connect this usercontrol to it's viewmodel.
<DataTemplate DataType="{x:Type vm:CreateCustomerViewModel}">
<view:CreateCustomerView/>
</DataTemplate>
Finally, in the main window viewmodel, I create an instance of the control's viewmodel, and in the main window view, I am using an itemscontrol and binding it's itemssource property to the instance of the control's viewmodel.
<ItemsControl Height="600" Grid.Row="0" ItemsSource="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
Now, my issue is using the itemscontrol in the main window, I've tried a few different ways, but I cannot get the control to be the height of the window. I'm not sure if I shouldn't be using an itemscontrol, or what I'm doing wrong. Any help is very much appreciated.
ItemsControl is for collections. By default it uses a StackPanel to contain its child elements, which disallows stretching in the stack direction (Vertical by default). For a single item use ContentControl (the base of things like Button and Label) instead:
<ContentControl Height="600" Grid.Row="0" Content="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
You could try the following:
Put your ItemsControl in a Grid.
Declare your ItemsControl with VerticalContentAlignment="Stretch".
It shouldn't make any difference because it's the default setting, but declare your ItemsControl with VerticalAlignment="Stretch" and try removing the Height="600".
I have a grid in WPF which is made of 4 rows along 2 columns where column 1 holds an Image control and column 2 holds 4 Textblocks. Problem is, the Image control sizes itself to the Image size and extends the listbox's entry too much [Its in a DataTemplate] and makes everything look distorted. I dont want to manually set a max height/width because i want the Image to size itself to the size of the 4 textblocks that are alongside it. Any ideas?
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Source="{Binding Logo, Converter={StaticResource BSConverter}}" Grid.Row="0" Grid.RowSpan="4"
Grid.Column="0" Stretch="Uniform" SnapsToDevicePixels="True"/>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="{Binding Author}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="{Binding Version}" Grid.Row="2" Grid.Column="1"/>
<TextBlock Text="{Binding Description}" Grid.Row="3" Grid.Column="1"/>
</Grid>
</DataTemplate>
Thanks in advance
You can use Grid.IsSharedSizeGroup on the Parent ListBox to make sure all of your items get the same Width for the first Column like this
<ListBox ...
Grid.IsSharedSizeScope="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="GroupA"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
...
For the Image height problem, you could bind Height to the ActualHeight of the Parent Grid with a FallbackValue of 1.0 (to ensure the Height of the Image doesn't effect the Height of the Grid)
<Image Source="{Binding Logo, Converter={StaticResource BSConverter}}"
Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Stretch="Uniform" SnapsToDevicePixels="True"
Height="{Binding RelativeSource={RelativeSource AncestorType=Grid},
Path=ActualHeight,
FallbackValue=1.0}"/>
Modifying your containers slightly to make use of a StackPanel in conjunction with a Grid and referencing the StackPanel via ElementName binding should provide you the visuals you are looking for...
<DataTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,0,8,0" Source="{Binding Logo, Converter={StaticResource BSConverter}}"
Grid.Column="0" Stretch="Uniform" SnapsToDevicePixels="True"
Height="{Binding ElementName=Contents, Path=ActualHeight}"/>
<StackPanel VerticalAlignment="Top" Name="Contents" Grid.Column="1" Orientation="Vertical">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Author}"/>
<TextBlock Text="{Binding Version}"/>
<TextBlock Text="{Binding Description}"/>
</StackPanel>
</Grid>
</DataTemplate>
Ok, I'm using the grid to list various content. How can I get specific colums to resize while others stay fixed.
That is, form pops up with specifc Initial column sizes for the controls... if the user RESIZES the form... i want certain 'memo' like fields to expand. How to do that? i seem to only be able to get ALL 'second' columns to expand in height... not just 1 (last one)... or specific ones.
Thanks for any help!!
Here is the layout... how can i make the 'long' text resizeable with form resize, and keep the button glued to the bottom of the form??? tx
<DockPanel VerticalAlignment="Top">
<Grid DockPanel.Dock="Top" VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition MinHeight="80" Height="Auto"></RowDefinition>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Height="Auto" Grid.Column="1" Grid.Row="0" />
<TextBox Height="Auto" Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Height="Auto" Grid.Column="1" Grid.Row="2" />
</Grid>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" MinHeight="20" Margin=" 0,0,10,10">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</DockPanel>
(added after 1st 'answer')
Now, if i remove the bottom stackpanel (Ok, Cancel buttons) out of equation to make this easier and i set the 1st and 2nd rows to a fixed value... i seem to be able to get this working (don't want to have to set a max height though) ... oh and i need to change the verticalAlignment to 'stretch'. But as soon as i add the StackPanel for the buttons again... the stretching no longer works... so here is the next revised version...
<DockPanel VerticalAlignment="Stretch">
<Grid DockPanel.Dock="top" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="30"></RowDefinition>
<RowDefinition MinHeight="80" Height="*"></RowDefinition>
<RowDefinition MaxHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Grid.Column="1" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Grid.Column="1" Grid.Row="2" />
</Grid>
<StackPanel DockPanel.Dock="Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" MinHeight="20" Margin=" 0,0,10,10">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</DockPanel>
So I'm still having problems...
Use * for the column width instead of Auto, which tells the column to take up whatever space is left after the other columns are set.
If you need multiple columns to share the available space in different percentages, you can prefix the * with a number, as in "2*" and "3*". By default, "" means 1.
HTH,
Berryl
I seem to only be able to solve the problems by incorporting the StackPanel in its own grid row, and column. Here is my solution. Not sure if dock panel is necessary in this case... but without tinkering more ... that's my current solution. If any one can explain to me how to get it working with the stack panel OK, Cancel buttons 'outside' the grid, i'd love to know. Meanwhile, this solution is available for those of you looking into this sort of problem. As you see you need to use Auto in all the other row definitions. * where u want it to expand.
<DockPanel VerticalAlignment="Stretch">
<Grid DockPanel.Dock="top" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,10,10,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition MinWidth="150" Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition MinHeight="80" Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Test1"/>
<Label Grid.Column="0" Grid.Row="1" Content="Test2 -Long notes"/>
<Label Grid.Column="0" Grid.Row="2" Content="Test3"/>
<TextBox Grid.Column="1" Grid.Row="0" />
<TextBox Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" />
<TextBox Grid.Column="1" Grid.Row="2" />
<StackPanel Grid.Column="1" Grid.Row="3" VerticalAlignment="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" MinHeight="20" Margin=" 0,10,0,0">
<Button Content="OK" Margin="0,0,10,0" Width="75" IsDefault="True"/>
<Button Content="Cancel" Width="75" IsCancel="True" />
</StackPanel>
</Grid>
</DockPanel>
If you want to be able to re-size only one of the squares made by the Row and Column Definitions you should add a Grid or whichever container element inside of one the squares. Then you'll make the Grid inside the square re-size accordingly. This way all the Definitions won't re-size, instead the grid and it's elements inside will re-size and thus not changing the other elements. It's not common but you can have as many stack panels and grids and set their visibility when needed. Sometimes when something doesn't work stick them inside something else and experiment with it. You might just get it by accident, but you'll still get it.