How to align TextBlock and TextBox text on one baseline - layout

I am trying to figure out a nice layout for a group of controls with labels. If i have a label on the left of a textbox for example, the base line of the label and the textbox are not on the same vertical position. An often workaround ist to just vertically center both controls but that doesn't look nice if you have multi line textbox controls.
I got a few combinations.
I hoped a relative panel would provide the option to align the baseline like it does with the android relative layout panel. Unfortunately it doesn't.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel>
<TextBlock Text="Name:" Name="t1"></TextBlock>
<TextBox Text="Content" RelativePanel.RightOf="t1" ></TextBox>
</RelativePanel>
</Grid>
A grid does not help as well.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" HorizontalAlignment="Stretch"></TextBox>
</Grid>
</Grid>
Obviously a horizontal stackpanel has no magic as well.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" VerticalAlignment="Top"></TextBox>
</StackPanel>
</Grid>
A vertical stackpanel would avoid the problem, but i'd prefer the label on the left of the control.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Vertical">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" ></TextBox>
</StackPanel>
</Grid>
Do you have any ideas how to align baselines which is / or maybe a nice layout idea for a lot of input controls and labels?

I had a quick look through the docs and I don't think there is any equivalent to Android's baseline alignment in UWP. Text controls don't expose the position of their baseline for panels to make use of, as it is highly dependent on the template of the control (which can be completely changed, unlike in Android where the visual appearance of views are sort of hard-coded).
Anyway, by inspecting the visual tree of a textbox, I found that the innermost TextBoxView (the control which actually displays and handles text input for the TextBox control) renders text in the same way that a TextBlock does (meaning the padding and such is the same). So as long as we can align the top edges of the TextBlock to the TextBoxView, then the text for both controls will be at the same vertical position. Of course, the font and font size for both controls needs to be the same (which it is by default).
The TextBoxView is pushed down by its parent ScrollContentPresenter by 3px (effective pixels), and the text box border by 2px. So you just need to add 5px of top margin to the TextBlock and the text for both controls will align.
FYI this is based on the default TextBox template provided by SDK version 14393 which I am using. Microsoft can change these styles with new SDK versions.
Looking at the Android docs, the View class has a method getBaseline; in UWP, UIElement (or FrameworkElement) has no such equivalent. Searching the visual tree and trying to determine the baseline of the first text element you see mightn't work in every case (some elements have more than one text element).
If you're going to have lots of these left-labelled-elements, some suggestions:
Create a UserControl with the label and textbox in the correct position. That way you only have the margin hardcoded in one place in your code and if you need to change it you only need to change one piece of code.
The TextBox control (like many others) has a Header property where you can specify text which will be displayed immediately above the textbox. You can change the template so that the header will be to the left of the textbox instead.
It seems that the recommended way is to use the Header property and have the label on top. Most UWP apps do this (in Groove when you edit song info, Edge's settings pane, etc). This is probably because when displayed on a mobile device, there isn't much horizontal space.

The easiest way to achieve what you want is to not create a TextBlock and a TextBox, but simply two TextBox elements with any of the layouts you have suggested at the top. Then apply the following Style to the TextBox element which should only show the label to make it look like a TextBlock:
<Style x:Key="TransparentTextBoxStyle" TargetType="TextBox">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="IsTapEnabled" Value="False" />
<Setter Property="IsTabStop" Value="False" />
</Style>
I think setting IsReadOnly, IsTapEnabled and IsTabStop should be enough to disable all potential interactions (just made a quick test), but to be sure you could also simply set IsEnabled to false and modify the template to look the same like if it would be enabled (you can get the default template in VS2015 by opening the Document Outline window (if you don't have it visible, you can find it in View > Other windows) open the visual tree to get to your item, then right-click, Edit Template and Edit a Copy...).

Related

Showing a diagram within a scrollable area

Imagine I wish to have an area of my screen (eg. a box that is 500px by 500px) contain my diagram. If my diagram has a width or height large than this, I would like scroll bars to appear to allow me scroll the diagram. I tried to achieve this by placing my diagram within a sized <div> element but it seems that the diagram ignores this and it simply "spills out". Has anyone tried to achieve this and may be able to share a recipe?
By using the Chrome developer tools, I see that I do indeed have a <div> that is 500px by 500px which appears to contain an <svg> that has a width of 1082 and the whole width of the <svg> is shown even though the <svg> is contained withing the <div>.
When a <div> is created to hold the diagram and it is given a width and height, set its overflow css property to scroll. For example:
<div style="width: 500px; height: 500px; overflow: scroll;" />
See also this Stack Exchange answer that was the core of this jointjs solution about adding scroll bars to an <svg>.
How to get ScrollBars in SVG?

CQ rich text field editor enable bold, italic and underline styles, plus bullet and numbered lists only

I have a rich text field editor widget,
What I need is to activate functions (bold, italic and underline styles, plus bullet and numbered lists only.)
Here is the xml of my widget:
<richtextfield
jcr:primaryType="cq:Widget"
fieldLabel="this is rich text field"
name="./richtextfield"
xtype="richtext">
<rtePlugins jcr:primaryType="nt:unstructured">
<subsuperscript
jcr:primaryType="nt:unstructured"
features="*"/>
</rtePlugins>
</richtextfield>
as you can see i have all features enabled here,,,but this is not i need, as i just need bold, italic and underline styles, plus bullet and numbered lists enabled only.
any suggestions?
Thanks
You need to add nodes for the feature category and enable or disable features of this category. Have a look at the documentation:
http://dev.day.com/docs/en/cq/current/administering/configuring_rich_text_editor.html
Here is an example of a rather restricted RTE I am using:
<text
jcr:primaryType="cq:Widget"
externalStyleSheets="[/etc/designs/rtg/clientlibs/author/style/source/rte.css]"
hideLabel="{Boolean}true"
name="./text"
xtype="richtext">
<rtePlugins jcr:primaryType="nt:unstructured">
<format
jcr:primaryType="nt:unstructured"
features="[bold,italic]"/>
<justify
jcr:primaryType="nt:unstructured"
features=""/>
<lists
jcr:primaryType="nt:unstructured"
features="[ordered,unordered]"/>
<styles
jcr:primaryType="nt:unstructured"
features="*">
<styles jcr:primaryType="cq:WidgetCollection">
<f125
jcr:primaryType="nt:unstructured"
cssName="f125"
text="Font Size 125% (15px)"/>
<f150
jcr:primaryType="nt:unstructured"
cssName="f150"
text="Font Size 150% (18px)"/>
</styles>
</styles>
</rtePlugins>
</text>

Fit control to height of Windows 8 Hub (XAML)

I'm using the Hub control in a Windows 8.1 XAML app and I've got a Canvas control that I want to fit to the available height of its HubSection. In HTML I can just set heights to 100%, but I'm stumped on how to do it in XAML. Any clues?
In general for XAML if you want any UIElement to fill out it's parent horizontally and/or vertically you use the HorizontalAlignment and VerticalAlignment properties. By setting these two properties to stretch, the element will fill out it's parent entirely.
However, some controls determines their size based on their content (such as StackPanel). If you have say a empty Grid inside a StackPanel then the resulting size of the StackPanel is (0,0).
It can messy to figure out what is preventing your content from displaying itself as desired. The best way to figure out what is going on is to dig into the templates for the controls you are using.
In your case pertaining to the Hub/HubSection you need to tell the HubSection that the content it hosts should stretch vertically. You can then manually control the width of the element and set it's VerticalAlignment to Stretch.
<Hub>
<HubSection VerticalContentAlignment="Stretch">
<DataTemplate>
<Canvas
Background="Red"
Width="500">
</Canvas>
</DataTemplate>
</HubSection>
</Hub>

How to make GridView control scrolling vertically or Horizontally

Test in Simulator mode, the GridView wont scroll vertically even I have 100 records to show, it show a vertical bar but can not be used to scroll. What I need to do to make it scrolling vertically or horzontally?
Your help is appreciated for this problem. Thanks
<GridView x:Name="CustomersGridView"
Grid.Row="1"
Margin="37,174,73,89"
Foreground="White"
SelectionMode="Single"
IsSwipeEnabled="True"
IsItemClickEnabled="True"
ItemsSource="{Binding Mode=OneWay, Source={StaticResource CustomersViewSource}}"
ItemTemplate="{StaticResource CustomerTemplate}"
ItemClick="CustomersGridView_ItemClick"
// Horizontal or vertical here:
ScrollViewer.HorizontalScrollBarVisibility="Auto"
SelectionChanged="CustomersGridView_SelectionChanged">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Wrap the control in a ScrollViewer
For example:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="ScrollViewer Sample">
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary.
Resize the window, making it larger and smaller.</TextBlock>
<Rectangle Fill="Red" Width="500" Height="500"></Rectangle>
</StackPanel>
</ScrollViewer>
</Page>

Metro App Customised ListView Mouse Scroll

I have a Metro application with a ListView that has this definition:
<ListView Grid.Row="0" x:Name="lvData" CanDragItems="True" CanReorderItems="True" SelectionMode="Extended">
<ListView.ItemTemplate>
<DataTemplate>
<Border Padding="4,0,0,0">
<Grid Width="{Binding ElementName=lvData, Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Right"/>
<TextBlock Grid.Column="2" HorizontalAlignment="Right"/>
<TextBlock Grid.Column="3" HorizontalAlignment="Right"/>
<TextBlock Grid.Column="4" HorizontalAlignment="Right"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" TextTrimming="WordEllipsis"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Right"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Once this ListView is filled, how do I Scroll this ListView with a mouse? Can't seem to work it out. Any help would be appreciated.
I had a control on the page that was constantly stealing focus through other events that were being triggered, as such this event was NOT being fired. Things are working well now.
Specifically, it was the WebView control. See this article for workaround:
[WinRT Trick] Scrolling

Resources