Just starting to play around with the Windows 8 SDK.
Trying to create a TextBox that fills up the whole screen. Unfortunately at different resolutions the TextBox does not fill up the screen.
How do I bind the width and height of the TextBox to the width and height of the screen?
Thanks!
Don't set the width and height of the TextBox in the xaml. Instead, set HorizontalAlignment and VerticalAlignment to Stretch.
I got it to bind properly like this:
<Grid x:Name="MyGrid">
...
</Grid>
...
<TextBox x:Name="MainContent" Height="{Binding ActualHeight, ElementName=MyGrid}" HorizontalAlignment="Right" Width="{Binding ActualWidth, ElementName=MyGrid}" TextWrapping="Wrap" VerticalAlignment="Top" Foreground="#FF7A7A7A" FontSize="18.667"><TextBox>
Which is binding it to the size of the grid in the layout. This works by binding the Height and Width properties of the TextBox to the ActualHeight and ActualWidth values of the Grid. The ElementName of the binding links to the grid's x:Name property.
Try binding to Window.Current.Bounds. It has Height, Width, X, and Y among other properties.
Related
does anyone know how to set text of textbox in vertical center of the box? I'm trying to make my universal app responsive, and textbox size adapts as it should, but I would need text in to be always in vertical center.
Thanks for all your time and help in advance!
My code:
<TextBox
x:Name="textBox"
Margin="10"
TextWrapping="Wrap"
Text=""
Grid.Column="1"
PlaceholderText="Website"
TextAlignment="DetectFromContent"
FontSize="20"
FontFamily="Segoe UI Light"
VerticalContentAlignment="Center"
d:LayoutOverrides="TopPosition, BottomPosition" />
There's a little more to it than that. Inside the template for TextBox are several elements. Including presenters for the placeholder text and a delete button etc.
You could add an attached property to target the embedded ScrollViewer and achieve most of what you want like this;
<TextBox ScrollViewer.VerticalContentAlignment="Center" ..../>
Except if you're using placeholder "watermark" text and stuff, you may have to make a copy of the template and vertical position everything in there.
Hope this helps, cheers.
I have a Canvas /RelativePanel which I'm using as background "image" in my uwp app.
How can I position a child in the canvas at the bottom? There is no canvas.bottom AP like in wpf. I also didn't find any proper attached property in the relativepanel to position the child at the bottom of the relative panel.
<RelativePanel>
<ContentControl ContentTemplate="{StaticResource AsterioidTemplate}" />
<Canvas x:Name="mountain_to_bottom" HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<Path Width="126.389" Height="326.227" Canvas.Left="272.433" Canvas.Top="28.3291" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</Canvas>
</RelativePanel>
How can I position a child in the canvas at the bottom?
Canvas is a layout panel that supports absolute positioning of child elements relative to the top left corner of the canvas in uwp.You control the positioning of elements inside the Canvas by specifying x and y coordinates.Since canvas is absolute positioning , child content is not constrained by the bounds of the panel, so we may not define the child at the bottom of canvas directly. But we can try to calculate the position manually to let the child position at the bottom of canvas. For example, the following demo can show the image at the bottom of the canvas.
XAML Code
<Canvas Background="Pink" x:Name="mountain_to_bottom" Height="600">
<Path x:Name="pathelement" Width="126.389" Height="326.227" VerticalAlignment="Bottom" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</Canvas>
<Button x:Name="btnbottom" Click="btnbottom_Click" Content="to bottom"></Button>
Code behind
private void btnbottom_Click(object sender, RoutedEventArgs e)
{
double canvasheight = mountain_to_bottom.ActualHeight;
if (pathelement.ActualHeight < canvasheight)
{
double top = canvasheight - pathelement.ActualHeight;
pathelement.SetValue(Canvas.TopProperty, top);
}
}
I also didn't find any proper attached property in the relativepanel to position the child at the bottom of the relative panel.
Inside relative panel, elements are positioned using a variety of attached properties. Relative panel provides RelativePanel.AlignBottomWithPanel attached property for position the child at the bottom of the panel.
<RelativePanel BorderBrush="Gray" BorderThickness="10">
<Path x:Name="pathelement" RelativePanel.AlignBottomWithPanel="True" Width="126.389" Height="326.227" VerticalAlignment="Bottom" Stretch="Fill" StrokeThickness="1.33333" StrokeLineJoin="Round" Stroke="#FF23232D" Fill="#FF23232D" Data="F1 M 398.155,353.889L 273.099,186.024L 315.298,28.9958L 398.155,353.889 Z "/>
</RelativePanel>
If canvas and relative panel can not meet your requirements well you can consider about other containers. What container to use depend on your layout. For example, relativePanel is a layout container that is useful for creating UIs that do not have a clear linear pattern; that is, layouts that are not fundamentally stacked, wrapped, or tabular, where you might naturally use a StackPanel or Grid. More details please reference Layout panels.
Background
I'm trying to put a textBlock control at the bottom of the screen (with a small margin below it), and I also wish to set a background for it, so that no matter what is shown behind the textBlock, it will be easy to read.
On Android, you could simply set the background to it, and tell it to have the width and height to be WRAP_CONTENT, so that it will take only the space it needs, but I can't find a similar thing on WP8.
Current status
This is the xaml I've created:
...
<Grid >
<Image x:Name="fullScreenImage" Stretch="Fill"
Visibility="Collapsed" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Bottom"
Margin="0,0,0,200" FontSize="40" x:Name="pictureLabel" TextWrapping="Wrap"
Foreground="#ff000000" />
</Grid>
The problem
Since the textBlock doesn't have a background property, I had to use something that wraps it. However, since its content changes dynamically, I can't simply set a size for it.
The question
For now, I would like to simply set its background color.
I would also very appreciate if it would be possible to use a rounded corners rectangle for the background, or a 9-patch image.
How can I achieve setting a background for the textBlock?
The solution is very simple. Just set the HirizontalAlignment to Left. Hope this will work in your case.
<StackPanel HorizontalAlignment="Left">
<Border Background="#66FFFFFF">
<TextBlock/>
</Border>
</StackPanel>
According to this question (which is for Silverlight - but is xaml nonetheless), there is no way to explicitly set a background color for a TextBlock. Your best bet is to wrap your TextBlock in a Grid or Border.
If a Grid does not work, this article suggests a Border will do the trick:
A simple border will do, and by not setting its width and height
properties, it will shrink/grow based on the size of the TextBlock.
I've come up with the next solution , which works quite fine , but what i really would like to also have is a way to set a min font and max font size , so that if there is a single word , the font might need to be of some size, and if the text is too long , the font will be of a smaller size , all in a dynamic way.
code:
label.Text = label;
label.Measure(new Size(RenderSize.Width, RenderSize.Height));
border.Width = label.DesiredSize.Width + border.Padding.Left + border.Padding.Right + border.BorderThickness.Left + border.BorderThickness.Right;
border.Height = label.DesiredSize.Height + border.Padding.Top + border.Padding.Bottom + border.BorderThickness.Bottom + border.BorderThickness.Top;
and the xaml:
<Border BorderBrush="#ff000000" BorderThickness="2" CornerRadius="8" Visibility="Collapsed" Padding="5" Background="#bfff0000" Margin="10,0,10,200" VerticalAlignment="Bottom" x:Name="border">
<StackPanel>
<TextBlock FontSize="40" x:Name="pictureLabel" TextWrapping="Wrap" Foreground="#ff000000" />
</StackPanel>
</Border>
I'm using a ListBox with its DataTemplate containing a Canvas. I then bind the Left/Top of the Grid containing that Canvas to move it to a certain point.
I want to then have the child Grid centred at the X,Y coordinates I've specified, where the size of the child Grid is variable based on its content. I was planning on achieving this by using a TranslateTransform to move the Grid by half of its width.
I can't see how I can set that TranslateTransform however as ElementName binding doesn't work within a DataTemplate. Any ideas how I can achieve this?
<ItemsControl ItemsSource="{TemplateBinding SomeCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Grid x:Name="Container"
Canvas.Left="{Binding X}"
Canvas.Top="{Binding Y}"
Background="#88000000">
<Grid.RenderTransform>
<TranslateTransform X="{Binding ActualWidth, ElementName=Container, Converter={StaticResource NegativeHalfConverter}}"
Y="{Binding ActualHeight, ElementName=Container, Converter={StaticResource NegativeHalfConverter}}" />
</Grid.RenderTransform>
<TextBlock Text="{Binding SomeValue}" FontSize="36" Foreground="White" />
</Grid>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
`
I think ElementName binding should work in the name scope of a DataTemplate, but I have seen people complaining about bindings not updating correctly when binding to ActualWidth/Height properties. Perhaps instead of doing the complicated setup you have you could just implement an attached behavior that takes a Point parameter and updates the Canvas.Left/Top properties whenever the parameter or size of the associated object (your grid) changes.
Looks like the fault wasn't with the binding itself, but with a feature that means the ActualWidth/ActualHeight properties aren't bindable. Thanks Filip.
To fix this I created a derived Grid with a couple of new dependency properties that I update in the SizeChanged events to have the ActualWidth/Height. I then use my DataTemplate as above, binding to these new DPs to translate and centre my Grid on a point. Seems to work a treat.
To move an object by half of its size you can use 2 rotations or scales: first is over 0.25,0.25 relative point, second is over the enter point 0.5,0.5. If you use rotations then angels are 180 degrees and -180 degrees. If you use scales then scale factors are -1,-1 and -1,-1.
Do not forget about RenderTransformOrigin property. And to apply two transforms you can apply them to two nested elements.
How would I set the number of characters a user is allowed to input in a TextBlock in xaml?
Would I do it on the Model or create some sort of custom attribute to handle it?
TextBlock doesn't have a MaxLength, neither does Label. TextBox does. Users cannot input into a TextBlock unless you have modified it.
Is it really a TextBlock you want to limit or did you mean a TextBox? If it is a TextBox you can simply use the MaxLength property.
<TextBox Name="textBox1" MaxLength="5" />
If it really is a TextBlock you are using and somehow allowing a user to input data into it, then switch to use a TextBox. If it is the TextBlock style you are after, you can style the TextBox to look like a TextBlock.
Without creating a custom control, you have a few options.
You could try to size the TextBlock to fit your expected text exactly, but that gets ugly fast trying to account for varying input or different font sizes.
Instead, you can verify the character length of the string to be assigned to the TextBlock.Text property and limit it if necessary.
string s = "new text";
if (s.Length > maxLen)
textBlock1.Text = s.Substring(0, maxLen);
else
textBlock1.Text = s;
Another option is to use the TextWrapping and TextTrimming properties. The following attributes could be added to your TextBlock xaml to add line wrapping and "..." to denote that text exists beyond the size of the TextBlock.
<TextBlock ... TextWrapping="Wrap" TextTrimming="CharacterEllipsis" />
You can use 'TextTrimming' Property of a Textblock. Set TextTrimming = "CharacterEllipsis". You might need to play with Width to manage how many characters you really want to display.
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding Subject}"/>
Either Set MaxHeight = "SomeHeight" and trim the overflow with
<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding LongText}"
Or Use TextBox like Textblock by setting
<TextBox IsReadOnly="True" Background="Transparent" BorderThickness="0"
MaxLength="100"