Xamarin custom renderer take photo - xamarin

I want to take photo using Xamarin form custom renderer.
I use Custom Renderer Sample and I add a Button named 'btnTakePicture' in Xaml , but I don't have any idea how to take photo on Button click event.
I want to show camera in part of screen.
Also I checked Xam.Media.Plugin and I couldn't take photo.
Xaml Code
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
x:Class="CustomRenderer.frmCamera"
Title="Main Page">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="7*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Label Text="Camera Preview"/>
</Grid>
<Grid Grid.Row="1">
<local:CameraPreview Camera="Rear" x:Name="cmrPreview"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" Background="black"/>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnChangeCamera" Text="Switch Camera" Clicked="btnChangeCamera_Clicked"/>
<Button x:Name="btnTakePicture" Text="Take" Grid.Column="1" Clicked="btnTakePicture_Clicked"/>
</Grid>
<Frame></Frame>
</Grid>
</ContentPage>
C# Code
using System.IO;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace CustomRenderer
{
public partial class frmCamera : ContentPage
{
public frmCamera()
{
InitializeComponent();
}
private void btnChangeCamera_Clicked(object sender, System.EventArgs e)
{
if (cmrPreview.Camera == CameraOptions.Rear)
cmrPreview.Camera = CameraOptions.Front;
else
cmrPreview.Camera = CameraOptions.Rear;
}
bool blnIsFlashLight = false;
private void btnFlashLight_Clicked(object sender, System.EventArgs e)
{
if (blnIsFlashLight)
{
Flashlight.TurnOffAsync();
blnIsFlashLight = false;
}
else
{
Flashlight.TurnOnAsync();
blnIsFlashLight = true;
}
}
private void btnTakePhoto_Clicked(object sender, System.EventArgs e)
{
}
}
}
here is my project Screenshot

Related

FindByName control inside another control on ContentPage in Xamarin

I want to set focus on SearchBar when he appears. The problem is that SearchBar is placed inside of popup view and I need to access him from ViewModel.
In standard way I would use
Xamarin.Forms.SearchBar tmp_SearchBar = this.Page.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
but that's not working anymore.
Here is XAML
<sfPopup:SfPopupLayout x:Name="fro_Popup_NewItem" Opened="fro_Popup_NewItem_Opened" Grid.Row="1" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Black">
<sfPopup:SfPopupLayout.PopupView>
<sfPopup:PopupView BackgroundColor="Black" WidthRequest ="400" HeightRequest ="100" ShowFooter="False" ShowHeader="False">
<sfPopup:PopupView.ContentTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--Search bar-->
<Grid Grid.Row="0" HorizontalOptions="Center" VerticalOptions="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<SearchBar x:Name="fro_SearchBar_NewItem"
Grid.Column="0"
Text="{Binding SearchText_Popup, Mode=TwoWay}"
SearchCommand="{Binding SearchCommand}"
Placeholder="Find"
CancelButtonColor="White"
TextColor="White"
PlaceholderColor="Gray"/>
</Grid>
</Grid>
</DataTemplate>
</sfPopup:PopupView.ContentTemplate>
</sfPopup:PopupView>
</sfPopup:SfPopupLayout.PopupView>
</sfPopup:SfPopupLayout>
Nested FindByName doesn't work either.
Syncfusion.XForms.PopupLayout.SfPopupLayout tmp_Popup = _Page.FindByName("fro_Popup_NewItem") as Syncfusion.XForms.PopupLayout.SfPopupLayout;
Xamarin.Forms.SearchBar tmp_SearchBar = tmp_Popup.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
Thanks
You can use Task to open a new thread to complete this operation in code-behind.
Xaml:
<SearchBar x:Name="fro_SearchBar_NewItem" Placeholder="...." BackgroundColor="White"/>
Code behind:
public partial class PagePop : Popup
{
public PagePop()
{
InitializeComponent();
Task.Run(() => myTask());//Create and start the thread
}
private void myTask()
{
Thread.Sleep(300);
fro_SearchBar_NewItem.Focus();
}
}
It seems that this wasn't so far from right direction, neither of the comments actually.
Syncfusion.XForms.PopupLayout.SfPopupLayout tmp_Popup = _Page.FindByName("fro_Popup_NewItem") as Syncfusion.XForms.PopupLayout.SfPopupLayout;
Xamarin.Forms.SearchBar tmp_SearchBar = tmp_Popup.FindByName("fro_SearchBar_NewItem") as Xamarin.Forms.SearchBar;
but I found the one which works and I don't have to create separate XAML for Popup.
private void fro_Popup_NewItem_Opened(object sender, EventArgs e)
{
try
{
var nativeObject = (object)fro_Popup_NewItem.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("NativeObject")).GetValue(fro_Popup_NewItem);
var formsPopupviewContentTemplate = nativeObject.GetType().GetRuntimeFields().FirstOrDefault(x => x.Name.Equals("formsPopupViewContentTemplate")).GetValue(nativeObject);
var SearchBar = (formsPopupviewContentTemplate as Grid).FindByName<SearchBar>("fro_SearchBar_NewItem");
SearchBar?.Focus();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Thanks for help, everyone.

How to return values from controls in popup and add them to the main page?

The main page has a button for adding new items. When the user presses it, a popup window appears.
I used this code for popup.xaml:
<xct:Popup xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MReport.popup01"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
Size="300,400">
<ScrollView>
<StackLayout Orientation="Vertical" Spacing="10">
<Label Text="From Time:" Padding="5,5,0,0" TextColor="Black"
HorizontalTextAlignment="Start" />
<TimePicker HorizontalOptions="Center" Time="00:00" />
<Label Text="To Time" Padding="5,5,0,0" TextColor="Black"
HorizontalTextAlignment="Start" />
<TimePicker HorizontalOptions="Center"/>
<Label Text="Your Activities:" Padding="5,5,0,0" TextColor="Black" />
<Editor x:Name="editor_value" VerticalOptions="CenterAndExpand" HeightRequest="200" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="1" Text="Add" Clicked="Button_Clicked_1" />
<Button Grid.Column="0" Text="Cancel" Clicked="Button_Clicked" />
</Grid>
</StackLayout>
</ScrollView>
</xct:Popup>
For popup.xaml.cs:
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace MReport
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class popup01 : Popup
{
public popup01()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
Dismiss("Cancelled");
}
private void Button_Clicked_1(object sender, EventArgs e)
{
}
}
}
For TabbedPage:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MReport.TabbedMainPage">
<!--Pages can be added as references or inline-->
<ContentPage Title="New Report" IconImageSource="NewReport.png" BackgroundImageSource="blue_windows.jpg">
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ScrollView>
<StackLayout>
<Label x:Name="lbl01" />
</StackLayout>
</ScrollView>
<Button Grid.Row="1" Text="Add New Item" Clicked="Button_Clicked"/>
</Grid>
<Button Grid.Row="1" Text="Send Report" />
</StackLayout>
</ContentPage>
<ContentPage Title="Report History" IconImageSource="History.png" BackgroundImageSource="blue_windows.jpg" />
<ContentPage Title="Messages" IconImageSource="Message.png" BackgroundImageSource="blue_windows.jpg"/>
</TabbedPage>
For TabbedPage.xaml.cs:
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
using Xamarin.Forms.Xaml;
using Xamarin.CommunityToolkit.Extensions;
namespace MReport
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TabbedMainPage : Xamarin.Forms.TabbedPage
{
public TabbedMainPage()
{
InitializeComponent();
On<Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
On<Android>().SetIsSmoothScrollEnabled(false);
}
private void Button_Clicked(object sender, EventArgs e)
{
Navigation.ShowPopup(new popup01());
}
}
}
I use CommunityToolKit for the popup.
The popup has two buttons. The ADD button will add the information entered in the popup to the main page.
I want the output to be like the image I've provided.
These frame boxes and their texts are added each time the user presses the add button in the popup. Those frame boxes are expanded based on the text volume inside them. What code should be written for the ADD button?
Please help me.
ShowPopupAsync can return a value to the caller
var result = await Navigation.ShowPopupAsync(popup);
whatever parameter is passed to Dismiss() will be returned to the caller

Telerik Calendar doesn't appear

I have this (copied from the examples)...
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MyApp" x:Class="MyApp.MainPage" xmlns:telerikInput="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout Padding="5">
<Label Text="Select a view mode" />
<Picker x:Name="viewModePicker" />
</StackLayout>
<telerikInput:RadCalendar x:Name="calendar" NativeControlLoaded="CalendarLoaded" Grid.Row="1"/>
</Grid>
</ContentPage>
And...
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
calendar.DisplayDate = new DateTime(2017, 4, 12);
viewModePicker.ItemsSource = Enum.GetValues(typeof(CalendarViewMode));
viewModePicker.SelectedItem = CalendarViewMode.Day;
viewModePicker.SelectedIndexChanged += ViewModeChanged;
}
private void ViewModeChanged(object sender, EventArgs e)
{
calendar.TrySetViewMode((CalendarViewMode)viewModePicker.SelectedItem);
}
private void CalendarLoaded(object sender, System.EventArgs e)
{
calendar.TrySetViewMode((CalendarViewMode)viewModePicker.SelectedItem);
}
}
Everything works, including the calendar instance existing, except I can't see it! I'm using an iOS app.
This rendered fine for me:
StartPage.xaml.cs
using System;
using Telerik.XamarinForms.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TelerikXamarinApp1
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StartPage : ContentPage
{
public StartPage()
{
InitializeComponent();
calendar.DisplayDate = new DateTime(2017, 4, 12);
viewModePicker.ItemsSource = Enum.GetValues(typeof(CalendarViewMode));
viewModePicker.SelectedItem = CalendarViewMode.Day;
viewModePicker.SelectedIndexChanged += ViewModeChanged;
}
private void ViewModeChanged(object sender, EventArgs e)
{
calendar.TrySetViewMode((CalendarViewMode)viewModePicker.SelectedItem);
}
private void CalendarLoaded(object sender, EventArgs e)
{
calendar.TrySetViewMode((CalendarViewMode)viewModePicker.SelectedItem);
}
}
}
StartPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:telerikInput="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input"
x:Class="TelerikXamarinApp1.StartPage">
<ContentView.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout Padding="5">
<Label Text="Select a view mode" />
<Picker x:Name="viewModePicker" />
</StackLayout>
<telerikInput:RadCalendar x:Name="calendar" NativeControlLoaded="CalendarLoaded" Grid.Row="1" />
</Grid>
</ContentView.Content>
</ContentPage>
I reinstalled the DLLs from the Telerik Nuget server. Must have missed something, and I didn't realise that one can log on to their server using one's regular Telerik website credentials.
This resulted in the calendar appearing on my iPhone but not in the simulator. I copied my solution over to Mac OS and used Visual Studio Mac to build and deploy and now the calendar appears in the simulator too.
Also, the build and deploy time seems about twice as fast. Was using Windows on Parallels before, though.

How to add swipe/drag view from bottom in windows 8.1 phone

Hey I want to do in my windows 8.1 phone app a View that I can swipe from the bottom of the window (Images below explain it better). The view must allow to swipe/drag it to the bottom again. Any idea or tip of how can I do that? Thank you in advance.
This is what I want to have initially
Use the Windows phone Bottom App Bar.This will give you the desired functionality.But you Cannot Customize the bottom app bar e.g. you cannot add the radio button or checkbox to it.It has its own predefined buttons called as AppBarButton & AppBarToggleButtons.
For more information you can visit the following link :
Windows Phone 8.1 for Developers – Application bar
I hope this will help you.
Try this:
MainPage.xaml
<Page x:Name="page"
x:Class="MyApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Canvas Background="Red">
<Grid>
<!--Your layout-->
</Grid>
<Grid x:Name="swipingContent" Canvas.Left="0" Background="Black" Width="{Binding ActualWidth, ElementName=page, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Thumb x:Name="thumb" Height="35" ManipulationMode="TranslateY" IsEnabled="True" ManipulationDelta="Thumb_ManipulationDelta"/>
<TextBlock Foreground="Black" FontSize="22" Text="Heading" VerticalAlignment="Center"/>
<CheckBox Grid.Row="1" IsChecked="True" Content="Some CheckBox"/>
<!--and other layout-->
</Grid>
</Canvas>
</Page>
MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.SizeChanged += MainPage_SizeChanged;
}
private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
swipingContent.SetValue(Canvas.TopProperty, e.NewSize.Height - thumb.ActualHeight);
}
private void Thumb_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var maxSwipedHeight = swipingContent.Height;
var currentPosition = (double)swipingContent.GetValue(Canvas.TopProperty);
var distanceFromBottom = this.ActualHeight - currentPosition;
var targetDistance = distanceFromBottom - e.Delta.Translation.Y;
double targetPosition;
if (targetDistance <= thumb.ActualHeight)
{
targetPosition = this.ActualHeight - thumb.ActualHeight;
}
else if (targetDistance >= maxSwipedHeight)
{
targetPosition = this.ActualHeight - maxSwipedHeight;
}
else
{
targetPosition = this.ActualHeight - targetDistance;
}
swipingContent.SetValue(Canvas.TopProperty, targetPosition);
}
}

Xamarin Forms XAML Label Rotation

I've got a problem with Xamarin.Forms and Label.
I'm trying to set a label on a grid column.
The first image here shows the expected result, which is written in AXML on Android.
The second image here is written in XAML in Xamarin.Forms.
The code in the XAML file is as follows:
<Grid
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400*"/>
<ColumnDefinition Width="75*"/>
</Grid.ColumnDefinitions>
<WebView Source="{Binding ContentSource}" />
<!--<ProgressBar IsVisible="{Binding IsLoading}"
Progress="{Binding Progress}"/>-->
<Grid Grid.Column="1"
BackgroundColor="#EE7F00"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Label
Text="{Binding DocumentIndex}"
LineBreakMode="NoWrap"
HorizontalOptions="Center"
Rotation="-90"
VerticalOptions="Center" />
</Grid>
</Grid>
How can I expand the height or width of the label to equal to the text length?
Thank you so far
Remove the Grid container for label and place a Box view instead, and set the Grid Row and Column same for both the box view and label. like this
<Grid
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<WebView Grid.Row="0" Grid.Column="0" Source="{Binding ContentSource}" />
<!--<ProgressBar IsVisible="{Binding IsLoading}"
Progress="{Binding Progress}"/>-->
<BoxView Grid.Row="0" Grid.Column="1" BackgroundColor="#EE7F00" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding DocumentIndex}"
LineBreakMode="NoWrap"
HorizontalOptions="Center"
Rotation="-90"
VerticalOptions="Center" />
</Grid>
I hope this will solve your label length problem after rotation.
I solved this with a custom renderer. In your Forms project:
public class RotatedText : View
{
public static BindableProperty TitleValueProperty = BindableProperty.Create(nameof(TitleValue), typeof(string), typeof(string), null, BindingMode.TwoWay, null,
(bindable, oldValue, newValue) =>
{
});
public string TitleValue
{
get => (string)GetValue(TitleValueProperty);
set => SetValue(TitleValueProperty, value);
}
}
And in your Android project:
[assembly: ExportRenderer(typeof(RotatedText), typeof(RotatedTextRenderer))]
namespace MyNamespace
{
public class RotatedTextRenderer : ViewRenderer
{
private Context _context;
public RotatedTextRenderer(Context c) : base(c)
{
_context = c;
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (e.NewElement is RotatedText)
{
string title = ((RotatedText)e.NewElement).TitleValue;
SetNativeControl(new RotatedTextView(_context, title));
}
}
}
public class RotatedTextView : Android.Views.View
{
private int DEFAULT_TEXT_SIZE = 30;
private string _text;
private TextPaint _textPaint;
public RotatedTextView(Context c, string title) : base(c)
{
_text = title;
initLabelView();
}
private void initLabelView()
{
this._textPaint = new TextPaint();
this._textPaint.AntiAlias = true;
this._textPaint.TextAlign = Paint.Align.Center;
this._textPaint.TextSize = DEFAULT_TEXT_SIZE;
this._textPaint.Color = new Android.Graphics.Color(0, 0, 0);
}
public override void Draw(Canvas canvas)
{
base.Draw(canvas);
if (!string.IsNullOrEmpty(this._text))
{
float x = (Width / 2) - DEFAULT_TEXT_SIZE/3;
float y = (Height / 2);
canvas.Rotate(90);
canvas.DrawText(this._text, y, -x, this._textPaint);
}
}
}
}
Then just set TitleValue where ever you use RotatedText. It's a little ugly but I couldn't find a better way.

Resources