Font Size change KerningAdjustment, why? - c#

I solved the problem, I created a function where I just pass the value of the spacing I need and the TextField
public static void ChangeSpaceBetweenCharacters(this UITextField textField, float space)
{
textField.WeakDefaultTextAttributes.SetValueForKey(NSObject.FromObject((nfloat)space), UIStringAttributeKey.KerningAdjustment);
}
Best regards,
Rafael Santos

I think the problem may be caused by the font method you use, I can't make it work with:
UIFont("ArialMT", 13)
Instead, you can use :
Font = UIFont.FromName("ArialMT", 13),
Or
Font = UIFont.SystemFontOfSize(10),
I test below sample code and it works for me:
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
NSMutableAttributedString mtText = new NSMutableAttributedString("testTextfield", new UIStringAttributes
{
Font = UIFont.SystemFontOfSize(10),
KerningAdjustment = 8.0f
});
UITextField textField = new UITextField();
textField.Frame = new CoreGraphics.CGRect(10,20,350,50);
textField.AttributedText = mtText;
Add(textField);
}

Related

Set Navigation Title color in Xamarin(Ios)

I want set navigation Bar Title color in Xamarin(Ios) using C#.
I set below way but it not work.
this.NavigationController.NavigationBar.BarTintColor = UIColor.Clear.FromHexString("#0072BA", 1.0f);
this.NavigationController.NavigationBar.TitleTextAttributes = UIColor.Magenta;
the BarTintColor work but TitleTextAttributes not work.. I also see documentation but in document the title text color not mention.
Any help be Appreciated..
After Spending 1 Hour I got the solution.
Type UIKit.UINavigationBar does not contain a definition for SetTitleTextAttributes and no extension method SetTitleTextAttributes of type UIKit.UINavigationBar could be found. and it give below error :
Are you missing an assembly reference ?
So Instead of calling SetTitleTextAttributes, do the following:
this.NavigationController.NavigationBar.TitleTextAttributes = new UIStringAttributes()
{
ForegroundColor = UIColor.White
};
Hope this will help other.
You can use a custom view as the navigation bar's title view, then you can modify it easily.
In your "ViewDidLoad" method, using this code:
public override void ViewDidLoad()
{
//Normal way
//this.Title = "Normal";//or this.NavigationItem.Title = "Normal;
//Using custom view
UILabel lbTitle = new UILabel(new CoreGraphics.CGRect(0, 0, 50, 30));
lbTitle.Text = "CustomView";
lbTitle.TextColor = UIColor.Red;
lbTitle.Font = UIFont.SystemFontOfSize(15);
this.NavigationItem.TitleView = lbTitle;
//Using a picture
//this.NavigationItem.TitleView = new UIImageView();
}
Hope it can help you.

Changing Xamarin Label in ListCell does not work

I have a problem with a ListView. I want each Cell to have a label and a switch but the text of the label does not appear.
Here is my code:
public class FilterPage : ContentPage
{
public FilterPage()
{
List<FilterCell> listContent = new List<FilterCell>();
foreach(string type in Database.RestaurantTypes)
{
FilterCell fc = new FilterCell();
fc.Text = type;
listContent.Add(fc);
}
ListView types = new ListView();
types.ItemTemplate = new DataTemplate(typeof(FilterCell));
types.ItemsSource = listContent;
var layout = new StackLayout();
layout.Children.Add(types);
Content = layout;
}
}
public class FilterCell : ViewCell
{
private Label label;
public Switch CellSwitch { get; private set; }
public String Text{ get { return label.Text; } set { label.Text = value; } }
public FilterCell()
{
label = new Label();
CellSwitch = new Switch();
var layout = new StackLayout
{
Padding = new Thickness(20, 0, 0, 0),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { label, CellSwitch }
};
View = layout;
}
}
If I enter a fixed Text in the FilterCell-Constructor it works fine (e.g.: label.Text = "Hello World")
When I create a Method for the ItemSelected-Event and read out the SelectedItem.Text Property I get the text I assigned as Value but it's never displayed. Only the switch is displayed when I try to run this Code.
Thanks for your help
Niko
Ohh boy. This code looks like a rape (sorry I had to say this).
Now let's see what's wrong:
The reason is you are mixing up data and view heavily.
The line
types.ItemTemplate = new DataTemplate(typeof(FilterCell));
means: "For each item in the list (ItemsSource) create a new filter cell". The FilterCells that you create in the loop are never displayed.
The easy fix
public class FilterPage : ContentPage
{
public FilterPage()
{
var restaurantTypes = new[] {"Pizza", "China", "German"}; // Database.RestaurantTypes
ListView types = new ListView();
types.ItemTemplate = new DataTemplate(() =>
{
var cell = new SwitchCell();
cell.SetBinding(SwitchCell.TextProperty, ".");
return cell;
});
types.ItemsSource = restaurantTypes;
Content = types;
}
}
There is a standard cell type that contains a label and a switch SwitchCell, use it.
As ItemsSource of your list, you have to use your data. In your case the list of restaurant types. I just mocked them with a static list.
The DataTemplate creates the SwitchCell and sets the Databinding for the Text property. This is the magic glue between View and data. The "." binds it to the data item itself. We use it, because our list contains items of strings and the Text should be exactly the string. (read about Databinding: https://developer.xamarin.com/guides/xamarin-forms/getting-started/introduction-to-xamarin-forms/#Data_Binding )
I striped away the StackLayout that contained the list. You can directly set the list as Content of the page.
Lesson
use standard controls, if possible
You should always try to remember to keep data and view apart from each other and use data binding to connect to each other.
Try to avoid unnecessary views.

Xamarin forms binding Label

Basically I want to make functionality, when I input text to my Editor it will appear inserted data to my label. And if I will swipe page to another page, that data should be bind'ed to that label in previous page where I entered data.
So I have portable class. In that class I have method public ContentPage CreatePage(MyObject thing) here I define many Labels, boxes , buttons and etc. But I will indicate most important things: Here I am define my Label and Editor:
public partial class CoolPage: CarouselPage
{
public CoolPage()
{
foreach (MyObject p in things)
{
Children.Add(CreatePage(p));
}
}
public ContentPage CreatePage(MyObject thing) {
var emptyLabel = new Label
{
Text = "Text",
WidthRequest = 50,
HeightRequest = 50,
BackgroundColor = Color.White
};
((StackLayout)page.Content).Children.Add(emptyLabel);
var inputNumb = new Editor
{
Text=thing.Number,
TextColor = Color.Black,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
IsVisible = true,
BackgroundColor = Color.White
};
inputNumb.SetBinding(Label.TextProperty, "Text");
inputNumb.BindingContext = thing.Number;
((StackLayout)page.Content).Children.Add(inputNumb);
}
}
I have tried to impelemnt such a event:
inputNumb.Completed += (sender, args) =>
{
inputNumb.SetBinding(Label.TextProperty, "Text");
inputNumb.BindingContext = thing.Number;
};
but it is not working. And I think because it is on same method. Also I tried to do out of method scope, by implementing such a line on CreatePage method inputCarNumb.Completed += InputCarNumb_Completed; But then when you define your variable inputNumb it doesn't recognize and I don't know how to implement in other case. I know it is very simple, but I think I miss something by doing SetBinding / BindingContext .
I solved this problem like this:
emptyLabel.SetBinding(Label.TextProperty, "Text");
emptyLabel.BindingContext = inputNumb;
Make sure your MyObject inherits from and implements INotifyPropertyChanged so that PropertyChanged fires whenever Number changes. I generally inherit from XLabs's ViewModel, and use their SetProperty method. Don't bother setting the binding in the event. But the 2nd parameter of SetBinding should be "Number" which is MyObject's property name. Also the BindingContext should = thing.

Set Text to the lowest right edge of a label?

Easy example, lets say I'm creating a Label like that:
Label label = new Label();
label.Text = "Hello" + "20.50";
label.Width = 250;
label.Height = 100;
panel1.Controls.Add(label);
How could I say that the "20.50" should appear in the lowest right edge of the label?
For clarity I made a little example in word:
How could I achieve this? Any help appreciated!
There's no built-in support for this with a Label control. You'll need to inherit from Label to create a custom control, and then write the painting code yourself.
Of course, you'll also need some way to differentiate between the two strings. The + sign, when applied to two strings, is concatenation. The two strings are joined together by the compiler, so all you get is this: Hello20.50. You will either need to use two separate properties, each with their own strings, or insert some sort of delimiter in between the two strings that you can use to split them apart later. Since you're already creating a custom control class, I'd go with the separate properties—much cleaner code, and harder to get wrong.
public class CornerLabel : Label
{
public string Text2 { get; set; }
public CornerLabel()
{
// This label doesn't support autosizing because the default autosize logic
// only knows about the primary caption, not the secondary one.
//
// You will either have to set its size manually, or override the
// GetPreferredSize function and write your own logic. That would not be
// hard to do: use TextRenderer.MeasureText to determine the space
// required for both of your strings.
this.AutoSize = false;
}
protected override void OnPaint(PaintEventArgs e)
{
// Call the base class to paint the regular caption in the top-left.
base.OnPaint(e);
// Paint the secondary caption in the bottom-right.
TextRenderer.DrawText(e.Graphics,
this.Text2,
this.Font,
this.ClientRectangle,
this.ForeColor,
TextFormatFlags.Bottom | TextFormatFlags.Right);
}
}
Add this class to a new file, build your project, and then drop this control onto your form. Make sure to set both the Text and Text2 properties, and then resize the control in the designer and watch what happens!
Here is what you need, a custom label:
public class CustomLabel : Label
{
public CustomLabel()
{
TopLeftText = BottomRightText = "";
AutoSize = false;
}
public string TopLeftText {get;set;}
public string BottomRightText {get;set;}
protected override void OnPaint(PaintEventArgs e)
{
using (StringFormat sf = new StringFormat() { LineAlignment = StringAlignment.Near})
{
using(SolidBrush brush = new SolidBrush(ForeColor)){
e.Graphics.DrawString(TopLeftText, Font, brush, ClientRectangle, sf);
sf.LineAlignment = StringAlignment.Far;
sf.Alignment = StringAlignment.Far;
e.Graphics.DrawString(BottomRightText, Font, brush, ClientRectangle, sf);
}
}
}
}
//use it:
//first, set its size to what you want.
customLabel1.TopLeftText = house.Name;
customLabel2.BottomRightText = house.Number;

How to print information programmatically on a doc template?

I have an application in C# that would print invoices and payslips. The client have sent me a template which would be used for the day to day operations. I don't know how to print to it, though I already know how to print a programmatically made text file which contains the information from an access database.
How do I print the information on this kind of template? (This is only something I [found on Google][1] and is a good candidate for a simple invoice printing) The document template I have also have a LOGO..
Do it by mail merge in Word. Using this technique you create Word document. Inside document you create placeholders for text. And from code you fill placeholders with whatever you want.
For example:
In word document type ctrl + F9
Right click on field and Edit field
Choose MergeField
On field name type FirstName
Add code:
.
var document = new Document("document.docx");
var sqlCommand = "SELECT TOP 1 userName FirstName FROM Users";
var table = GetTable(sqlCommand, String.Empty);
document.MailMerge.Execute(table);
I've been using the PrintDocument and PrintPreview objects. That use the the Graphics class. When print is called you get an "PrintEventArgs e" object. Then you can use e.Graphics to have access to things like e.Graphics.DrawString, .DrawImage etc.
I built a whole print objects class that overrides print. So I have a detail box that has different fonts, or a logo, a header, leagal jargon etc. Each one of these has it's own class. I put them all in a big list and I call printThis(List); and it will take each print function and the coordinates and make me a form.
Inherited object
class formHdr : printObject
{
private string headerText;
public formHdr(string hText)
: base()
{
headerText = hText;
}
public override void printThis(System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics;
g.DrawString(headerText, FRHEADER, Brushes.Black, BaseX, BaseY);
}
}
Base class
abstract class printObject
{
protected Font FTHEADER;
protected Font NRML;
protected Font DETAIL;
protected Font FRHEADER;
protected Font DETHEADER;
protected Font LEGAL;
protected Font LEGAL2;
public int baseX, baseY;
public int boxSX, boxSY;
public printObject()
{
baseX = 0;
baseY = 0;
boxSX = 0;
boxSY = 0;
FTHEADER = new Font("Arial", 12, FontStyle.Bold);
NRML = new Font("Calibri", 10);
DETAIL = new Font("Consolas", 8);
FRHEADER = new Font("Arial", 16, FontStyle.Bold);
DETHEADER = new Font("Calibri", 10, FontStyle.Bold);
LEGAL = new Font("Arial", 8);
LEGAL2 = new Font("Arial", 10);
}
public virtual void printThis(PrintPageEventArgs e) { }
Object creation
mainHead = new formHdr("Bill of Lading/Weigh slip Original");
mainHead.BaseX = 225;
mainHead.BaseY = 20;
bol.Add(mainHead);
Maybe this can get you started? I'm still tweaking it and will be interested in other responses.

Categories