how to fit a long text into a UITextView or UILabel - c#

i'm developing an ios app with xamarin.
i need to fit a long text into a content (UILabel or UITextView).
this is the code i used:
var descStrLabel = new UITextView(new CGRect(0, 250, w, 550));
descStrLabel.BackgroundColor = UIColor.Black;
descStrLabel.Font = UIFont.SystemFontOfSize(10.0f);
descStrLabel.TextAlignment = UITextAlignment.Center;
descStrLabel.TextColor = UIColor.LightGray;
descStrLabel.Text = #"HERE THE LONG TEXT...";
//descStrLabel.Lines = 0;
descStrLabel.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
View.Add(unified);
View.Add(subtitle);
View.Add(descStrLabel);
When i debug the application, the last part of the text is missing...
maybe i need to set the width at runtime...
thanks in advance for your help

I don't really know how you want to "fit" the text. If you want to show the text all in one line, try calling SizeToFit():
desc.SizeToFit();
documentation for SizeToFit():
Moves and resizes the UIView so that it tightly encloses its UIView.Subviews
If you want the UITextView to wrap lines, then you don't need to do anything! Line wrapping is enabled by default. If it doesn't for you, try setting LineBreakMode:
desc.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
documentation for WordWrap:
Wraps at the first word that does not fit.

Related

How to programmatically correctly set drawable padding on button?

I'm having trouble setting the padding for a button to center the content (text + drawable).
Here is where I've gone so far:
Button done = new Button(this)
{
Text = GetText((int)typeof(Resource.String).GetField("goalreached").GetValue(null))
};
done.LayoutParameters = doneButtonParams;
done.SetBackgroundResource(Resource.Drawable.DoneGreenYakaButton);
done.Typeface = Typeface.CreateFromAsset(Assets, "fonts/Ubuntu-Medium.ttf");
done.SetTextColor(Color.White);
done.SetTextSize(Android.Util.ComplexUnitType.Sp, 12);
doneButtonParams.ColumnSpec = GridLayout.InvokeSpec(0, 2); // Setting colspan = 2
var check = GetDrawable(Resource.Drawable.ic_check_16px);
check.SetBounds(0, 0, 32, 32); // Set the image size
check.SetTint(Color.White); // Set the image color
done.SetCompoundDrawables(null, null, check, null);
The result is this:
Obviously I want the check mark to be nearer the text and have the same padding as the one for the text on the left of the button.
What Am I missing here ?
Thanks in advance.
I'm not familiar with xamarin for mobile development but the native Android way of doing this is setting the drawable padding on the button itself. setCompoundDrawablePadding(int) is the native method to accomplish adjusting the distance between text and the drawable.
Ex:
done.setCompoundDrawablePadding(15);
Edit: I realized you are looking to add padding on the outside of the checkmark, this would be accomplished with plain old setPadding(int, int, int, int).
Ex:
setPadding(0,0,15,0);

Compress text to fit within a control's displayed width

In my C# WinForms application, I have a control in which I display some text to the user on screen. For time being, assume it is a TextBox.
My requirement is if the text does not fully fit within the displayed width of the control, I want to keep reducing the font size or compress the text in some other way to fit the displayed width of the control.
I understand in extreme situations, the text may not be readable at all. But that's fine.
Can I get a code example how to achieve this?
To measure the width of the font you'll have to determine it using TextRenderer. The following code illustrates how to achieve this, and to resize the font in the textbox.
var text = "Some unnecessarily long, long, long string.";
var size = default(SizeF);
// SizeF size; // Use this if you're on an older version of C# without default
do
{
using (var font = new Font(textBox1.Font.Name, textBox1.Font.SizeInPoints))
{
size = TextRenderer.MeasureText(text, font);
if (size.Width <= textBox1.Width)
textBox1.Text = text;
else
{
textBox1.Text = "Won't fit";
textBox1.Font = new Font(font.Name, font.SizeInPoints - 1f);
}
}
} while (size.Width > textBox1.Width);
You may want to adjust the by how much the font size decreases if it ends up too small for your liking.

How to create a smooth animated text marquee?

I know that there are lot of different threads about horizontal text animation/text scrolling, but unfortunately none of them give smooth scrolling with repeatable text. I have tried double/thickness animation using various WPF controls containing text. Also tried animating with visual brush which gives me by far the most elegant scrolling compared to other approaches (for e.g. playing with Canvas.Left property etc.) but that too goes blur the text, if the text length or the animation speed is too high.
I'm over to a pure DirectX C# implementation using SharpDX library. Should also mention that I'm a beginner with DirectX programming. Here is the code:
public void RunMethod()
{
// Make window active and hide mouse cursor.
window.PointerCursor = null;
window.Activate();
var str = "This is an example of a moving TextLayout object with no snapped pixel boundaries.";
// Infinite loop to prevent the application from exiting.
while (true)
{
// Dispatch all pending events in the queue.
window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);
// Quit if the users presses Escape key.
if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
{
return;
}
// Set the Direct2D drawing target.
d2dContext.Target = d2dTarget;
// Clear the target.
d2dContext.BeginDraw();
d2dContext.Clear(Color.CornflowerBlue);
//float layoutXOffset = 0;
float layoutXOffset = layoutX;
// Create the DirectWrite factory objet.
SharpDX.DirectWrite.Factory fontFactory = new SharpDX.DirectWrite.Factory();
// Create a TextFormat object that will use the Segoe UI font with a size of 24 DIPs.
textFormat = new TextFormat(fontFactory, "Verdana", 100.0f);
textLayout2 = new TextLayout(fontFactory, str, textFormat, 2000.0f, 100.0f);
// Draw moving text without pixel snapping, thus giving a smoother movement.
// d2dContext.FillRectangle(new RectangleF(layoutXOffset, 1000, 1000, 100), backgroundBrush);
d2dContext.DrawTextLayout(new Vector2(layoutXOffset, 0), textLayout2, textBrush, DrawTextOptions.NoSnap);
d2dContext.EndDraw();
//var character = str.Substring(0, 1);
//str = str.Remove(0, 1);
//str += character;
layoutX -= 3.0f;
if (layoutX <= -1000)
{
layoutX = 0;
}
// Present the current buffer to the screen.
swapChain.Present(1, PresentFlags.None);
}
}
Basically it creates an endless loop and subtracts the horizontal offset. Here are the challenges: I need repeatable text similar to HTML marquee without any gaps, Would probably need to extend it to multiple monitors.
Please suggest.
I don't know neither how to use DirectX nor sharpdx, but if you want you can consider this solution
I had a similar problem a while ago, but with the text inside a combobox. After a bounty i got what i was looking for. I'm posting the relevant piece of code as an example, but you can check the complete answer here
Basically, whenever you have a textblock/textbox that contain a string that cannot be displayed completely, cause the length exceed the textblock/box lenght you can use this kind of approach. You can define a custom usercontrol derived from the base you need (e.g. SlidingComboBox : Combobox) and define an animation for you storyboard like the following
_animation = new DoubleAnimation()
{
From = 0,
RepeatBehavior = SlideForever ? RepeatBehavior.Forever : new RepeatBehavior(1), //repeat only if slide-forever is true
AutoReverse = SlideForever
};
In my example i wanted this behaviour to be active only when the mouse was on the combobox, so in my custom OnMouse enter i had this piece of code
if (_parent.ActualWidth < textBlock.ActualWidth)
{
_animation.Duration = TimeSpan.FromMilliseconds(((int)textBlock.Text?.Length * 100));
_animation.To = _parent.ActualWidth - textBlock.ActualWidth;
_storyBoard.Begin(textBlock);
}
Where _parent represent the container of the selected item. After a check on the text lenght vs combobox lenght i start the animation and end it at the end of the text to be displayed
Note that in the question i mentioned there are also other soltions. I'm posting the one that worked for me

Barcode with horizontal white lines crossing in WPF

I have an issue with a Barcode that I'm trying to print. It has horizontal white lines and I couldn't read the code with a barcode reader.
I'm using Telerik RadControls for WPF.
I generate the object in code-behind like that:
public RadBarcode128 CrearBarCode(Guia guia)
{
RadBarcode128 barcode = new RadBarcode128();
barcode.Text = guia.TipoFactura.ToString() + guia.AgenciaOrigenId.ToString() + "-" + guia.CodigoGuiaNumerico;
barcode.Height = 40;
barcode.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
return barcode;
}
That object is part of a FlowDocument, here is the code that calls CrearBarCode method:
RadBarcode128 barCode = CrearBarCode(bulto.Guia);
BlockUIContainer bl = new BlockUIContainer();
bl.Margin = new Thickness(0);
bl.Child = barCode;
flowDocument.Blocks.Add(bl);
Then, when I send that to the printer, it looks like this (the image is not mine, but the problem is the same). Look the lines that cross the Barcode:
I tried to adjust barcode heigth (as you can see in CrearBarcode) but I couldn't remove the white lines. Also, I tried setting the FlowDocument.LineHeigth property with a larger number, but it didn't work. The problem persists.
Do you know what should I try to remove the lines?
Thanks.

How to get the HEIGHT of the Run or Paragraph

I found the Run or Paragraph in FlowDocument and now I need to know the HEIGHT of it.
i.e.
while (navigator.CompareTo(flowDocViewer.Document.ContentEnd) < 0)
{
TextPointerContext context = navigator.GetPointerContext(LogicalDirection.Backward);
Run run = navigator.Parent as Run;
// I need to get HEIGHT of Run in pixels somehow
Is it possible to do in fact?
Thank you!
A little function i am using. The input is a string containing a Section. You can easily render other blockelements like Paragraph.
You also can omit the second parameter of the Parse method.
The trick is not to measure the Paragraph, but the ViewBox which contains a RichTextBox. This is needed to actually render the Flowdocument. The ViewBox dynamically gets the size of the rtb. Maybe you even can do this without the ViewBox. I spent some time to figure this out and it works for me.
Note that Width of the RichTextBox is set to double.MaxValue. This means when you want to measure a single paragraph it has to be very long or everything is in one line. So this only makes sense when you know the Width of your output device. As this is a FlowDocument there is no Width, it flows ;)
I use this to paginate a FlowDocument where i know the paper size.
The returned Height is device independent units.
private double GetHeaderFooterHeight(string headerFooter)
{
var section = (Section)XamlReader.Parse(headerFooter, _pd.ParserContext);
var flowDoc = new FlowDocument();
flowDoc.Blocks.Add(section);
var richtextbox = new RichTextBox { Width = double.MaxValue, Document = flowDoc };
var viewbox = new Viewbox { Child = richtextbox };
viewbox.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
viewbox.Arrange(new Rect(viewbox.DesiredSize));
var size = new Size() { Height = viewbox.ActualHeight, Width = viewbox.ActualWidth };
return size.Height;
}

Categories