Can I "include" a XAML file? [duplicate] - xamarin

I am trying a new approach i.e. XAML to make application in xamarin.forms. At this time i am facing an issue to reuse my stack layout which is having a image and label. How i can reuse my layout in different pages using XAML.

You can actually define your custom component in a separate XAML file and then just link the component wherever you need it.
For example a label with image can be grouped together in a dedicated XAML file:
<?xml version="1.0" encoding="utf-8" ?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="UserControls.ImageWithTitle"
VerticalOptions="Center" HorizontalOptions="Center" >
<Label HorizontalOptions="Center"
x:Name="TitleLabel" />
<Image Source="noimage.png" />
</StackLayout>
On the .cs file I've defined a binding for the TitleLabel
public string TitleName
{
get { return TitleLabel.Text; }
set { TitleLabel.Text = value; }
}
So when you include the component on another layout, you can assign the label value directly (or via a binding):
<usercontrols:ImageWithTitle TitleName="Home"/>

Related

Xamarin.Forms.Map is not working for UWP platform. How to make it work?

I'm trying to load street map using Xamarin.Forms.Map plugin in my project for UWP app. For that I have also get the token from MSDN. Here is what I have done:
MapePage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:Map_POC.ViewModels"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
xmlns:local="clr-namespace:Map_POC.CustomControls"
x:Class="Map_POC.Views.MapePage">
<ContentPage.BindingContext>
<vm:MapePageViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<maps:Map
x:Name="MyMap"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
MapType="Street" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
MapePage.xaml.cs
public MapePage()
{
InitializeComponent();
Position position = new Position(-37.8141, 144.9633);
var pin = new Pin
{
Type = PinType.Place,
Position = position,
Label = "I'm a Pin",
};
MyMap.Pins.Add(pin);
MyMap.MoveToRegion(
MapSpan.FromCenterAndRadius(
position, Distance.FromMiles(1)));
}
MainPage.xaml.cs (In UWP Solution)
public sealed partial class MainPage
{
public MainPage()
{
this.InitializeComponent();
Xamarin.FormsMaps.Init(Keys.UWPMapToken);
Windows.Services.Maps.MapService.ServiceToken = Keys.UWPMapToken;
LoadApplication(new Map_POC.App());
}
}
Output: With hybrid map it shows map but not showing pin and locations properly.
Other thing apart from this it not works in offline mode, can we cache map for offline mode?
Can we draw a polygon and coordinates covered inside the polygon can be clicked individually or not?
Any help on this will be highly appreciated.

Xamarin - Binding to a Property of a child control inside a custom control

I am working on a Xamarin App. I am making a custom control with a Label control, a DatePicker control and an Entry control. I had to create quite a few BindableProperties for the Date Control in the Custom Control such as MaximumDate, MinimumDate Property among many other properties. As far as I understand, the reason I have to create these BindableProperty members in my Custom control are because I have no access to the properties of the child controls when the custom control is used on a view. Is there a way to access the properties of the child control that is embedded in a custom control? I could save a lot of lines of code defining the BindableProperties and their CLR properties and other things.
Here is my Custom control XAML (I have removed all the elements except for a Label element in the posted code to make the code more readable and for brevity.
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DPSReminders.Controls.CustomLabel"
xmlns:controls="clr-namespace:DPSReminders.Controls"
xmlns:sfLayout="clr-namespace:Syncfusion.XForms.TextInputLayout;assembly=Syncfusion.Core.XForms"
xmlns:sfPicker="clr-namespace:Syncfusion.XForms.Pickers;assembly=Syncfusion.SfPicker.XForms"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:fai="clr-namespace:FontAwesome">
<StackLayout.Resources>
<ResourceDictionary>
</ResourceDictionary>
</StackLayout.Resources>
<StackLayout Orientation="Horizontal" Margin="10">
<Label x:Name="myLabel"
Text=""
FontFamily="FASolid"
VerticalOptions="Center"
HorizontalOptions="Start"
Margin="10">
</Label>
</StackLayout>
The code behind file:
public class CustomLabel : StackLayout
{
public static readonly BindableProperty LabelTextProperty =
BindableProperty.Create(nameof(LabelText), typeof(string), typeof(CustomLabel),
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: LabelTextPropertyChanged);
public string LabelText
{
get => GetValue(LabelTextProperty)?.ToString();
set => SetValue(LabelTextProperty, value);
}
private static void LabelTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = bindable as CustomLabel;
control.myLabel.Text = newValue?.ToString();
}
public CustomLabel()
{
InitializeComponent();
}
}
Here is the page where I am trying to use the custom control.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DPSReminders.Views.DateTimeTest"
xmlns:fai="clr-namespace:FontAwesome"
xmlns:vm="clr-namespace:DPSReminders.ViewModels"
xmlns:controls="clr-namespace:DPSReminders.Controls"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
>
<controls:CustomLabel LabelText = "{Binding MyLabelText}"/>
</ContentPage>
I am wondering if I could do a line like this in my label, that would make my life much easier.
<controls:CustomLabel:myLabel.Text = "{Binding MyLabelText}"/>
Then, I can remove all the code creating the BindableProperties and the supporting CLR properties etc. when a built-in bindable property for the same purpose is already available in the child control. Is this something we can do?
Try using template instead.
Xamarin.Forms control templates enable you to define the visual structure of ContentView derived custom controls, and ContentPage derived pages. Control templates separate the user interface (UI) for a custom control, or page, from the logic that implements the control or page. Additional content can also be inserted into the templated custom control, or templated page, at a pre-defined location.
Doc link:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/control-template

Xamarin Forms Search Bar with Picker

I have a xamarin forms app and I would like to use the search bar control that upon focus will pull up a picker. Is there anyway I can extend the search bar to provide this functionality? In other words I don’t want the user to enter text in the search bar box, rather it’s selected from the pick list. Any examples would be appreciated.
You can look at using the XFX Controls for Xamarin Forms.
https://github.com/XamFormsExtended/Xfx.Controls
In the top of your page add a namespace reference to :
xmlns:xfx="clr-namespace:Xfx;assembly=Xfx.Controls"
Then you use the control as follows:
<!-- XfxComboBox-->
<xfx:XfxComboBox
Placeholder="Select make"
SelectedItem="{Binding SelectedVehicleMake}"
Text="{Binding Description}"
ItemsSource="{Binding AssetMakes}"/>
This control allows to bind to a item source and a selected Item
Picker dialog is shown when you call Focus() on the element, so you could just place a hidden Picker and call the method from the Click Handler of the ToolbarItem.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Views.MyPage"
Title="My Page Title"
x:Name="MyPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="ShowPicker" Clicked="ShowPicker">
</ToolbarItem>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<DatePicker x:Name="MyPicker" IsVisible="false" />
</ContentPage.Content>
</ContentPage>
namespace MyApp.Views
{
public partial class MyPage : ContentPage
{
public ItemsPage()
{
InitializeComponent();
}
void ShowPicker(object sender, EventArgs e)
{
MyPicker.Focus();
}
}
}

Xamarin.Forms XAML Image as root element

I am new to XAML and everywhere I read about it one would usually use some sort of container as the root view (StackLayout, ContentPage, ContentView, RelativeLayout etc).
But, I run into this XAML that uses Image as its root. Why would we do that?
<?xml version="1.0" encoding="utf-8" ?>
<Image
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:r="clr-namespace:My.Resources;assembly=My.Resources"
x:Class="My.Views.Buttons.MyView"
Source="MyImage.png"/>
I would like to replace this Image with FFImageLoading.CachedImage but for that I need to add FFImageLoading xmlns namespace but I cannot since namespaces are inside the Image tag, not outside.
You can specify the namespace in root tag and use it in root tag itself in XAML.
For e.g.:
<ffimageloading:CachedImage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SomeAppNameSpace.CustomCachedImage"
Source="http://loremflickr.com/600/600/nature?filename=simple.jpg">
</ffimageloading:CachedImage>
Just make sure you derive from the right class in code behind:
namespace SomeAppNameSpace
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomCachedImage : CachedImage
{
public CustomCachedImage()
{
InitializeComponent();
}
}
}

Wrapping an MPVolumeView inside 2 Stack Layouts (Xamarin.IOS)

I am creating a control based on a generic View that works with a custom renderer based on an iOS MPVolumeView, which is the simple control that allows you to select an alternate output route for audio in your app (i.e. Bluetooth Speaker). The code works just fine if I wrap inside a single stack layout, but not if it's inside two stack layouts. My XAML looks like this... very basic:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DABApp.DabTestPage" xmlns:local="clr-namespace:DABApp;assembly=DABApp">
<ContentPage.Content>
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Red">
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand" VerticalOptions="FillAndExpand">
<local:AudioOutputView />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
And here's the guts of my custom renderer:
[assembly: ExportRenderer(typeof(AudioOutputView), typeof(iosAudioOutputViewRenderer))]
namespace DABApp.iOS
{
public class iosAudioOutputViewRenderer: ViewRenderer<AudioOutputView, UIView>
{
MPVolumeView view;
protected override void OnElementChanged(ElementChangedEventArgs<AudioOutputView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
view = new MPVolumeView()
{
ShowsRouteButton = true,
ShowsVolumeSlider = false,
};
SetNativeControl(view);
}
}
}
}
With this XAML and code, when I push the page onto the nav stack async, the page won't even show. If I remove one of the StackLayouts, it works fine.
I changed my IOS control in the CustomRenderer to a simple UILabel and this works fine... so it looks like it has something to do with putting the MPVolumeView inside 2 StackLayouts. I need to be able to do this because of the layout requirements of my app, and it doesn't make any sense why 1 StackLayout is fine, but 2 isn't, and only for this native control.
Any ideas?

Resources