Xamarin forms how to use custom ui in Xaml - c#

I have extended the label class to create a slightly different piece of UI and would rather add it to my page with XAML rather than C# code. How can I do this?
Code:
namespace M.Helpers
{
public class LinkingLabel: Label
{
public LinkingLabel(Uri uri, String labelText = null)
{
Text = labelText ?? uri.ToString();
TextColor = Color.Blue;
GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => Device.OpenUri(uri)) });
}
}
}
How can I simply write <LinkingLabel Uri="" Text=""></LinkingLabel> inside of my pages XAML. I am getting errors but no intellisense to help me import.

First add namespace declaration attribute to the root tag in the XAML file:
xmlns:controls="clr-namespace:M.Helpers"
And, use it while declaring your custom control:
<controls:LinkingLabel Uri="" Text="">
...
</controls:LinkingLabel>
Also, because you don't have a default constructor in your custom control, you will need to pass in the arguments as parameters. More details here.

Related

defining custom DataTemplates and assign them to the ListView ItemTemplate

I'm trying to get into Xamarin development and followed Microsofts video tutorial
https://www.youtube.com/watch?v=OPXVqdRXZms&list=PLdo4fOcmZ0oU10SXt2W58pu2L0v2dOW-1&index=9
Currently I would like to populate my ListView with some basic labels. So first the following code works fine for me. I created a custom ViewCell and assign it to the ListView as the ItemTemplate
public class MasterPage : ContentPage
{
public ListView MasterPageNavigationItemsView { get; }
public MasterPage()
{
// ...
MasterPageNavigationItemsView = new ListView()
{
ItemTemplate = new DataTemplate(() => new MasterPageItemViewCell()),
SeparatorVisibility = SeparatorVisibility.None
};
MasterPageNavigationItemsView.SetBinding(ListView.ItemsSourceProperty, nameof(MasterViewModel.MasterPageItemsCollection));
// ...
}
}
internal class MasterPageItemViewCell : ViewCell
{
public MasterPageItemViewCell()
{
Label label = new Label();
label.SetBinding(Label.TextProperty, nameof(MasterPageItem.Title));
View = label;
}
}
I would prefer to create a custom DataTemplate as they did in the video tutorial. I found the code on Github
https://github.com/codemillmatt/xamarin-101/blob/8271814c7ebdd41387e20ed33b3dfbdcd54409be/coded-ui-navigation/CodedUINav/Views/MainPage.cs#L88-L112
So instead of doing ItemTemplate = new DataTemplate(() => new MasterPageItemViewCell()), I would like to do ItemTemplate = new MasterPageItemTemplate(),
which results in the class
internal class MasterPageItemTemplate : DataTemplate
{
public MasterPageItemTemplate() : base(LoadTemplate)
{
}
private static Label LoadTemplate()
{
Label titleLabel = new Label();
titleLabel.SetBinding(Label.TextProperty, nameof(MasterPageItem.Title));
return titleLabel;
}
}
So I took the code from Github and modified it a little bit. When I run the code the labels content is empty and when I click on it the application crashes.
How can I fix the MasterPageItemTemplate?
Update
I found another sample that makes use of view cells
https://github.com/xamarin/xamarin-forms-samples/tree/master/WorkingWithListview/WorkingWithListview/Custom
so I think I should follow this and use this code for now
ItemTemplate = new DataTemplate(typeof(MasterPageItemViewCell)),
Data items in a ListView are called cells. Each cell corresponds to a row of data. There are built-in cells to choose from, or you can define your own custom cell. Both built-in and custom cells can be used/defined in XAML or code.The child of an inline DataTemplate must be of, or derive from, type Cell.Here in your first link sample, the ListView.ItemTemplate property is set to a DataTemplate that's created from a custom type that defines the cell appearance. The custom type derive from type ViewCell,but in your codes custom DataTemplate return a Label,it will not work.
you could refer to Creating DataTemplate
And in the sample of your second link,it use CollectionView.You could nest markup inside a DataTemplate tag to create a View.
Note :When using CollectionView, never set the root element of your DataTemplate objects to a ViewCell. This will result in an exception being thrown because CollectionView has no concept of cells.

Create WPF Function to Hidden Images Controls

I'm currently developing a WPF C# Application that contains some textbox validations. If field is valid it must show a ok validation image if not valid it must show a wrong validation image, like an image below.
My Problem is how to set visibility = visibility.Hidden for all images if I click on cancelar button or another button. I know set img1.visibility = visibility.Hidden;, img2.visibility = visibility.Hidden;, img3.visibility = visibility.Hidden;... Works but i need to create a function to do it. I believe that I create a List of Images and pass this List of parameter to a function works fine and I can use this function for other validations. So how can I do it?
Please check this article : Data Binding
If you implement data binding then you have just to bind properties:
<Image Source="..." Visibility="{Binding Img1Visibility}"/>
Implement ViewModel class via INotifyPropertyChanged
And then simply work with your Properties in code.
UPD
If you want to simply create function to work with your images then move your img1.visibility = visibility.Hidden;, img2.visibility = visibility.Hidden;, img3.visibility = visibility.Hidden; in separate function inside your MainWindow.xaml.cs file, you don't have to pass it as arguments as you work in one MainWindow class.
So simply:
private void Fun()
{
img1.visibility = visibility.Hidden;
img2.visibility = visibility.Hidden;
img3.visibility = visibility.Hidden;
}
And request your Fun() method from ClickButton handler.
Create an array of the image controls and iterate over it.
List<Image> _images = new List<Image>
{
img1,
img2,
...
};
void Cancelar()
{
foreach (var image in _images)
{
image.Visibility = Visibility.Hidden;
}
}
But still, the code is awful. Witness me SO.

How to expose a label in a user control with c#

I have made a user control with a pic box and a blank label. How do I expose the label so I can update the text value from my main .net application. I have not written any c# code in about 10 years, and was just thrown a project. All I have for code is:
namespace RHeader1
{
public partial class RHeader : UserControl
{
public RHeader()
{
InitializeComponent();
}
}
}
Please for give my stupidity. I know I need to do a get/set but?????
I presume you mean because controls are not public, the proper way to access them are via a property (which I agree with) - so you can just expose a property which updates the label directly - I'm presuming this is winforms
public string Label
{
get { return label1.Text; }
set { label1.Text = value; }
}
Use this:
Label lbl= (Label)myUserControl.FindName("yourlabelname");
This way you can find and update your label control settled in the UserControl.
You could change the Label's modifier property to public, this will result in the labels properties been visible from the UC's property window and also allow you to do something like
uc.label.Text = "foo";
if you haven't delclared the label:
label1 = new label();
then
label1.text = "some text";
where you can replace "Some text" with any string value.

Access to a Label on the Form by my Custom control

I have created a WindowsFormControlLibrary porject. It works fine, I can drop it on the forms,call its methods,etc ...
but now as a property of it, I am passing the name of a Label to it. and I want this custom control to be able to use that label name and for example change its font to bold .
so the question is that if I have a WinForm and I have a Label on that form and my custom control on that form, then how can I tell my custom control to do something with that label which I am passing its name to it?
Instead of sending in the name of the label, send in a reference to the actual label and then the custom control can both read the name if it needs to and change the label's font and other properties.
Be careful though, it can quickly get messy to keep track of what's happening if various forms and controls change controls on other forms etc.
Edit: Added code to do what you ask for in the comments
Code isn't tested so it might not be completely correct, but something similar to this should work.
foreach (Control c in Parent.Controls)
{
if (c is Label)
{
Label l = (Label)c;
// do stuff to label l
}       
}
First, if you wish to access a Control from your UserControl, you will need to use the FindForm() method.
Second, you will be required to expose your TextBox control, for example, through a property of your form.
Then, you would need to know the type of this Form returned by this FindForm() method.
Once you know it, you need to type-cast this result to the correct type.
So, here a sample untested pseudo-code to give you the idea:
public partial class MyMainForm {
private TextBox textBox1;
public MyMainForm() {
textBox1 = new Textbox();
textBox1.Name = #"textBox1";
textBox1.Location = new Point(10, 10);
textBox1.Size = new Size(150, 23);
this.Controls.Add(textBox1);
}
public Font MyTextBoxFont {
get {
return textBox1.Font;
} set {
if (value == null) return;
textbox1.Font = value;
}
}
}
Then, assuming you have dropped your control on your form, your UserControl could have a property like so:
public partial class MyUserControl {
private Form GetContainerForm {
get {
return this.FindForm();
}
}
// And later on, where you need to set your TextBox's font:
private void SetContainerInputFieldFont(Font f) {
if (GetContainerForm == null) return; // Or throw, depending on what you need to do.
((MyMainForm)GetContainerForm).MyTextBoxFont = f
}
}
cool :) I just added a get set public property of type Label... it automatically lists all the label on the form.

Validating Form Fields in an ITemplate

I have a custom control which includes a property of the following definition:
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate Template {
get { return template; }
set { template = value; }
}
The control overrides CreateChildControls(), and adds several HtmlGenericControls and an asp:Panel control.
The actual actual implementation of the control looks something like this:
<user:Frame runat="server">
<Template>
<asp:Literal runat="server" ID="SomeControl" Text="SomeValue" />
</Template>
</user:Frame>
While the page renders as intended, it has a number of consequences of varying severity, including:
Controls enclosed within the Template cannot be referenced directly, and FindControl is required. This is fine.
I've been unable to use validation controls on them.
Is there a better way to design my custom control? Or perhaps just a way to get validation working?
By default the framework assumes that you may have more than one template in a control, like say in a Repeater. In your case you have to tell it that you intend to have a single template by using the TemplateInstance property. E.g.
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public ITemplate Template {
get { return template; }
set { template = value; }
}
This will allow you to reference the templated controls directly, and should fix your validation problems as well.
One way to get validation to work in this case is to add the validation controls programatically. For example:
var c = parentControl.FindControl("id");
parentControl.Controls.AddAt(
parentControl.Controls.IndexOf(c) + 1,
new RequiredFieldValidator() { ControlToValidate = c.D });

Categories

Resources