UWP C# - Font auto size of TextBlock and RichTextBlock - c#

How to force TexBlock and RichTextBlock to change FontSize so that the text fits in the window. When changing the text, if the text is too large, then it does not fit in the window. How to make it fit completely?
viewBox is not suitable because "TextWrapping=Wrap" does not work in it
Update:
I have a TextBlock for the entire width and height of the window. The user can change the text of any length. I would like to force TextBlock to change FontSize so that all the text fits in the window. viewBox is not suitable because "TextWrapping=Wrap" does not work in it.
I wrote a temporary code. But it's a terrible code. I would like to find a more correct code:
var textBlockHeight = Convert.ToInt32(page.ActualHeight - textBlock.Margin.Bottom);
var textBlockWidth = Convert.ToInt32(page.ActualWidth - (textBlock.Margin.Right * 2));
var canvas = new CanvasTextFormat
{
FontSize = 150,
WordWrapping = CanvasWordWrapping.Wrap,
};
var device = CanvasDevice.GetSharedDevice();
var layout = new CanvasTextLayout(device, text, canvas, textBlockWidth, 0);
var textHeight = (int)layout.DrawBounds.Height;
while (textBlockHeight < textHeight)
{
layout = new CanvasTextLayout(device, text, canvas, textBlockWidth, 0);
textHeight = (int)layout.DrawBounds.Height;
canvas.FontSize--;
if (canvas.FontSize <= 3)
{
break;
}
}
textBlock.FontSize = canvas.FontSize;
textBlock.Text = text;

Related

WPF textblock resize dependant on max width and split

Hello I have a textblock within a grid row. The text outside the width of the row is not shown. How can i split the text and display it underneath?
//Actual -->
//Date: 06/06/2018 realy long text is displayed, b
//Wanted -->
//Date: 06/06/2018 realy long text is displayed,
//but not showing everything due to width
//isue
Grid DynamicGrid = new Grid();
DynamicGrid.Width = 450;
DynamicGrid.Height = 1000;
DynamicGrid.HorizontalAlignment = HorizontalAlignment.Left;
DynamicGrid.VerticalAlignment = VerticalAlignment.Top;
DynamicGrid.ShowGridLines = false;
RowDefinition gridRow;
gridRow = new RowDefinition();
gridRow.Height = new GridLength(50);
DynamicGrid.RowDefinitions.Add(gridRow);
TextBlock txtBlock1 = new TextBlock();
txtBlock1.Text = "06/06/2018 realy long text is displayed, but not showing everything due to width isue";
txtBlock1.FontSize = 20;
txtBlock1.VerticalAlignment = VerticalAlignment.Top;
Grid.SetRow(txtBlock1, 0);
Grid.SetColumn(txtBlock1, 0);
DynamicGrid.Children.Add(txtBlock1);
Setting the TextWrapping property of the TextBlock to wrap will cause the textblock to show full text.

UWP show Fullscreen Popup, ContentDialog or Flyout

I need to display a full screen dialog (in application window boundaries) in my UWP application, but can't seems to make it work. I tried with :
ContentDialog only shows vertically stretched with FullSizeDesired="True"
Popup, even trying to set the width and height in code behind its not working
Flyout Placement="Full" only stretch it vertically just like the contentdialog
Can't believe I spend so much time on that thing :(
Thanks
Have you tried something like this:
var c = Window.Current.Bounds;
var g = new Grid
{
Width = c.Width,
Height = c.Height,
Background = new SolidColorBrush(Color.FromArgb(0x20, 0, 0, 0)),
Children =
{
new Rectangle
{
Width = 100,
Height = 100,
Fill = new SolidColorBrush(Colors.White),
Stroke = new SolidColorBrush(Colors.Black),
StrokeThickness = 3
}
}
};
var p = new Popup
{
HorizontalOffset = 0,
VerticalOffset = 0,
Width = c.Width,
Height = c.Height,
Child = g
};
p.IsOpen = true; // open when ready
You should see a semi-transparent overlay with a white rectangle in the middle of your screen.
To make a popup Fullscreen I did the following. Hope this helps.
I have a user control I wanted to show as a popup. Its name "URLUserControl"
Step 1: UI of the UC (Just the first bit. Not complete code)
<UserControl>
<Grid>
<Popup x:Name="MPopup" VerticalAlignment="Center">
<Grid x:Name="MainGrid">
Step 2: UC constructor adds the following
private void InitURLUserControl()
{
MPopup.IsOpen = true;
Window.Current.SizeChanged += Current_SizeChanged;
MainGrid.Width = Window.Current.Bounds.Width;
MainGrid.Height = Window.Current.Bounds.Height;
}
Step 3:
private void Current_SizeChanged(object sender, WindowSizeChangedEventArgs e)
{
MainGrid.Width = Window.Current.Bounds.Width;
MainGrid.Height = Window.Current.Bounds.Height;
}
The above code will help the popup to be the center of the screen and display in fullscreen in size. Check it out. Happy coding!

Set focus on a Canvas created programatically, in Windows Phone 8.1

I have an image of a map inside a scrollviewer and, using 2 canvas, I place a little square (or a map pin image) after the user selects where they are.
Now, since they do not "click" on the map to do so, but they select their location from a list, I need to make that square the center of the view, in the scrollviewer, once they see the map.
In my xaml, I have just a few things since, all the information, comes from an API
<Grid x:Name="firstFloor" Margin="0,50,0,0" Visibility="Visible">
<ScrollViewer x:Name="pruebaScrollViewer1" BringIntoViewOnFocusChange="True" ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" HorizontalScrollMode="Enabled">
<Grid x:Name="myMap1stFloor">
</Grid>
</ScrollViewer>
</Grid>
and in code behind I have
private void showStorePosition2(string map_id, string name, int width, int height, int tile, int x, int y)
{
IdOfMapWhereIAm = map_id;
if (map_id == "10")
{
if (!_primerPiso)
{
//my parent canvas is defined globally
//the width and height of it come from API
myParentCanvas.Width = width;
myParentCanvas.Height = height;
myParentCanvas.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center;
myParentCanvas.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
Debug.WriteLine(width);
ImageBrush pushpin = new ImageBrush();
pushpin.ImageSource = new BitmapImage(new Uri("ms-appx:/Imagenes/mappin.png", UriKind.Absolute));
TextBlock storeName = new TextBlock();
storeName.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top;
storeName.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left;
storeName.TextAlignment = TextAlignment.Center;
storeName.FontFamily = new Windows.UI.Xaml.Media.FontFamily("Open Sans");
storeName.Height = 20;
storeName.Width = Double.NaN;
storeName.FontSize = 15;
storeName.Text = name;
storeName.Margin = new Thickness(-20, -20, 0, 0);
storeName.TextWrapping = TextWrapping.Wrap;
storeName.Foreground = new SolidColorBrush(Colors.Black);
Canvas myInititialStore = new Canvas();
myInititialStore.Background = pushpin;
myInititialStore.Height = 13;
myInititialStore.Width = 13;
Canvas.SetTop(myInititialStore, (y) * tile);
Canvas.SetLeft(myInititialStore, (x) * tile);
myInititialStore.Children.Add(storeName);
myParentCanvas.Children.Add(myInititialStore);
myMap1stFloor.Children.Add(myParentCanvas);
}
}
}
I was thinking about giving myInitialStore a dependency property, setting the focusProperty, but I do not know how to do it either.
In case someone has the same problem I had, I found a way to "focus" on the Canvas I needed to:
Instead of trying to do so, I changed the view in the scrollviewer, using the Canvas values, that way, when the Canvas is loaded inside the scrollviewer, this last one moves automatically to where the Canvas is located:
ScrollViewer1.ChangeView(((initialStore_x * tileMapToGo) - (widthMapToGo / tileMapToGo)), ((initialStore_y * tileMapToGo) - (heightMapToGo / tileMapToGo)), 1, false);
Hope it helps someone. Regards

Buttons do not show up when specifying location property in Windows Forms

I'm trying dynamically add panels within a panel dependent on the count of people in a list using the following code when the form loads:
private void Form1_Load(object sender, EventArgs e)
{
const int xConst = 2;
var people = new List<string>
{
"Person1",
"Person2",
"Person3",
"Person4",
};
var y = 2;
for (var x = 0; x < people.Count; x++)
{
var newpan = new MyPanel
{
BorderStyle = BorderStyle.None,
Height = 25,
Width = panel1.Width - 5,
Location = new Point(xConst, y)
};
var newlbl = new Label
{
BorderStyle = BorderStyle.None,
AutoSize = false,
Text = people[x],
Font = new Font("Segoe UI", 9.5F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0))),
Size = new Size(75,20),
Location = new Point(newpan.Location.X + 2, newpan.Location.Y + 2),
};
var newbtn = new Button
{
FlatStyle = FlatStyle.Flat,
FlatAppearance = { BorderSize = 0 },
UseVisualStyleBackColor = true,
Text = #"+",
Size = new Size(15,21),
Location = new Point(newpan.Width - 20,newpan.Location.Y - 1),
Font = new Font("Segoe UI", 9.0F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)))
};
newpan.Controls.Add(newlbl);
newpan.Controls.Add(newbtn);
panel1.Controls.Add(newpan);
y += 27;
}
}
The problem is that if I specify the Location property in both the button and the label, only the first iteration of the labels and buttons show up for the Person1 iteration. But, if I leave the Location property out, they all show up. The problem with that is that I have a custom panel that overrides some stuff allowing me to put a customer border and color around the panels, and if I don't specify a location, the labels and buttons aren't positioned correctly on the panel, so it covers my border and looks sloppy.
Can someone help me figure out why this is happening? I've stepped through the program completely and watched all the values I can think of increment accordingly in the watch window. All the panels show up correctly, so I don't understand why their respective labels and buttons don't show up when I specify the location.
Looking at your code I notice that you are setting your newpan height to 25, and its position is offset by 27 with each iteration. You also are using
'Location = new Point(newpan.Location.X + 2, newpan.Location.Y + 2)
to set the location of your button and label within your newpan panel. newpan.Location is referenced in the coordinates of your panel1, your button and label's location is referenced in the coordinates of your newpan panel therefore after the first iteration of your For statement your label and buttons y location value is 29 which is greater than the height of your newpan panel making it not able to be seen, the next iteration after that will be y will be 56 and so forth. Each content control, in this case your panels will have its own coordinate system, the easiest fix would be to do something like this:
'Location = new Point( 2, 2) //for your label
'Location = new Point(newpan.Width - 20, - 1) //for your button
The other alternative is to do like jmcilhinney suggests and make an UserControl with your button and label already in position, you would then create individual instances of it and assign it to your panel1.

How to Control Z Order of Grids

I have the following code:
TextBlock tmp = new TextBlock
{
Text = displayText,
Foreground = new SolidColorBrush(Colors.Red),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
FontSize = 30
};
Grid grd = new Grid();
grd.Children.Add(tmp);
// grd.Background = new SolidColorBrush(Colors.LightGray);
Viewbox vb = new Viewbox();
vb.Child = grd;
vb.Width = width;
vb.Height = height;
DrawingCvs.Children.Add(vb);
Canvas.SetLeft(vb, xpos);
Canvas.SetTop(vb, ypos);
Canvas.SetZIndex(grd, 1000);
// we need a second grid for cosmetic reasons. Due to
// how the viewbox works, when we resize we lose the full
// width of the grid which has a textblock in it
Grid cosmeticGrd = new Grid
{
Width = width,
Height = height,
Background = new SolidColorBrush(Colors.LightGray)
};
DrawingCvs.Children.Add(cosmeticGrd);
Canvas.SetLeft(cosmeticGrd, xpos);
Canvas.SetTop(cosmeticGrd, ypos);
Canvas.SetZIndex(grd, 0);
What I want is for the Grid added first in the code to be above the grid added second. What is wrong with my Z-Index property setting here? Or is it something else?
InB4 Change the order you add them in the code--yes I realize this, but as a point of understanding I want to understand the ZIndex property.
Your first SetZindex call:
Canvas.SetZIndex(grd, 1000);
incorrectly applies the setting to the Grid instead of the Viewbox. It should be:
Canvas.SetZIndex(vb, 1000);
because the Viewbox is the child of the Canvas.
Likewise, your second SetZIndex call:
Canvas.SetZIndex(grd, 0);
is applied to the wrong Grid. It should be:
Canvas.SetZIndex(cosmeticGrd, 0);
In summary, the Canvas.ZIndex attached property affects the ordering of Canvas children.

Categories