How to select an image from gallery in xamarin forms? - c#

I'm trying to pick an image from gallery and i've done everything that is in this doc, but i'm getting an error with the "image" object in my .cs implementation.
My .cs code:
public partial class MyProfilePage : ContentPage
{
public MyProfilePage()
{
InitializeComponent();
BindingContext = new MyProfileViewModel();
}
async void ImageButton_Clicked(object sender, EventArgs e)
{
//(sender as Button).IsEnabled = true;
Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
if (stream != null)
{
image = ImageSource.FromStream(() => stream);
}
(sender as Button).IsEnabled = true;
}
}

Welcome to SO!
but i'm getting an error with the "image" object in my .cs implementation.
You can check the Xaml file that whether contain the x:Name="image".
Such as follows:
<ContentPage Title="Photo Picker"
Icon="monkeyicon.png">
<StackLayout Margin="20,35,20,20" >
<Label Text="Photo Picker"
FontAttributes="Bold"
HorizontalOptions="Center" />
<Button Text="Pick Photo"
Clicked="OnPickPhotoButtonClicked" />
<Image x:Name="image" />
</StackLayout>
</ContentPage>
If not works , you can refer to following steps:
First, you need to share the detail error logs here, and explain this occurs in iOS or
Android.
Second, you also can refer to this official sample Xamarin.Forms - Dependency Service to check where problem is.

Related

Using Xamarin Essentials, how do I attach screenshot (stream)to an e-mail?

Using Xamarin Essentials : "Email" and "Screenshot" (see Youtube links below) I want to make a screenshot and send it as an attachment in an e-mail. James says in the screenshot-video that you can but not how and I've been trying but to no avail.
C#
public ImageSource test { get; set; }
private async void TakeScreenshot_Clicked(object sender, EventArgs e)
{
ScreenshotResult screenshot = await Screenshot.CaptureAsync();
var stream = await screenshot.OpenReadAsync();
var test = ImageSource.FromStream(() => stream);
this.test= test;
// ImageScreenshot.Source = ImageSource.FromStream(() => stream);
}
private async void Button_Clicked(object sender, EventArgs e)
{
var message = new EmailMessage(EntrySubject.Text, "", EntryEmail.Text);
var filePath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData), test.ToString());
message.Attachments.Add(new EmailAttachment(filePath));
message.BodyFormat = EmailBodyFormat.Html;
await Email.ComposeAsync(message);
}
XAML
<Button x:Name="TakeScreenshot" Text="Take screenshot" Clicked="TakeScreenshot_Clicked" />
<Image x:Name="ImageScreenshot" VerticalOptions="FillAndExpand" MinimumHeightRequest="400" MinimumWidthRequest="400"/>
<Entry x:Name="EntryEmail" Text="" Placeholder="E-mail address"/>
<Entry x:Name="EntrySubject" Text="" Placeholder="Subject"/>
<Button Text="Take screenshot" Clicked="Button_Clicked" />
The problem I encounter is that for the email attachment <message.Attachments.Add> wants me to give it a string. However, because the screenshot I make is a "stream", you can't see where it's being saved. With the code for filePath it determines where's it's being saved and I tried telling the progmram to go wherever the screenshot is being saved as a path but that also didn't work. The maker (or one of the makers) even casually mentions in the screenshot video that this is possible, so I don't know what I'm doing wrong. Any suggestions?
Email: https://www.youtube.com/watch?v=YZ-Yw9CRxAY&t=269s Screenshot: https://www.youtube.com/watch?v=o2r4Ym1IExQ&t=229s

Xamarin UWP + Android ContentPage Navigation PushAsync

I'm converting an UWP application to Xamarin in the aim to use it on both Android and Windows devices.
I never used Xamarin before and I assume i'm doing a beginer mistake.
On my MainPage everything is OK :
But when I'm clicking on the "Options" Button it didn't load a new page exept a grey banner in the upper part of the window :
To navigate from one page to another I followed this explanation : Microsoft doc navigation
There's my code to change page in the MainPage.xaml.cs :
async void ButtonOptions_Click(object sender, EventArgs args)
{
try
{
button_options.Source = "Assets/Option_Icon_1.png";
Application.Current.MainPage = new NavigationPage(new MainPage());
var OptionsView = new OptionsView();
await Device.InvokeOnMainThreadAsync(() => Navigation.PushAsync(OptionsView, true));
//this.Frame.Navigate(typeof(StorageView1));
}
catch (Exception ex) { InterpretException("MainPage.ButtonStorage_Click()", ex); }
}
And my OptionsView.xaml :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Stock_Manager_Xamarin.OptionsView"
Title="Second Page">
<ContentPage.Content>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<StackLayout Orientation="Horizontal">
<Label Text="Name:" HorizontalOptions="FillAndExpand" />
<Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" />
</StackLayout>
<Button x:Name="navigateButton" Text="Previous Page"/>
</StackLayout>
</ContentPage.Content>
I tried different version of the xaml code without any change and I can't find a working sample.
Could someone can explain me where I'm doing a mistake ?
Wrap current page inside navigation stack in App.cs, and set it as MainPage, so that we can do the navigation operation .
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
As Jason mentioned , it is no need to set MainPage again , just navigate directly , modify your code as below .
void ButtonOptions_Click(object sender, EventArgs args)
{
try
{
button_options.Source = "Assets/Option_Icon_1.png";
var OptionsView = new OptionsView();
Navigation.PushAsync(OptionsView, true);
}
catch (Exception ex) { InterpretException("MainPage.ButtonStorage_Click()", ex); }
}

How to print Generated Barcode ZXING in xamarin forms

I managed to generate a Barcode using ZXING library, now I want to print the generated barcode as it is from the ZXingBarcodeImageView with the same size ,how can I do that
private async Task<Item> getItem()
{
HttpResponseMessage _response = await _client.GetAsync(url + txt_Barcode.Text);
if (_response.IsSuccessStatusCode)
{
string itemDetailes = await _response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Item>(itemDetailes);
}
return new Item();
}
private async void Btn_GetInfo(object sender, EventArgs e)
{
var selected_item = await getItem();
// Item_barcode.Text = selected_item.Value;
Item_Description.Text = selected_item.Description;
Item_name.Text = selected_item.Name;
Item_price.Text = selected_item.Price.ToString();
item_barcode.BarcodeValue = selected_item.Value;
}
xaml code
<!--<Image HeightRequest="300" WidthRequest="300" Margin="1" x:Name="img_barcode"></Image>-->
<zxing:ZXingBarcodeImageView x:Name="item_barcode" HeightRequest="20" WidthRequest="100" BarcodeFormat="CODE_39" BarcodeValue="Place Barcode" >
<zxing:ZXingBarcodeImageView.BarcodeOptions>
<zxingcomon:EncodingOptions Height="80" Width="1000"></zxingcomon:EncodingOptions>
</zxing:ZXingBarcodeImageView.BarcodeOptions>
</zxing:ZXingBarcodeImageView>
<StackLayout Orientation="Horizontal" Spacing="20" >
<Label TextColor="Black" x:Name="Item_Description"></Label>
<Label TextColor="Black" x:Name="Item_price"></Label>
</StackLayout>
<StackLayout x:Name="SLPrint" BackgroundColor="GhostWhite" VerticalOptions="FillAndExpand">
<Button Text="print" BackgroundColor="Black" TextColor="White"></Button>
</StackLayout>
</StackLayout>
</StackLayout>
The best and easiest option to do this is show the barcode inside webview.
here is a library which u can use Link
you can copy the script in asset folder. create a html file import the script
Now from xamarin side Evalute javascript in webview where you would send the barcode data to webview
here is how you can do it.
Link
note : you dont need to do any custom rendering
with this you can remove the zxing and can make your app size small

Issue displaying images with FlowListView & FFImageLoading in Xamarin.Forms

In XAML & C# using Xamarin.Forms (iOS Project) I'm trying to create a gallery where the user can add photos to it. Currently I can show a list that does have the photo data binded to each entry because the user can click on an item in the list and the correct image will show up.. However I have not been successful in actually displaying a smaller version of the pictures in my FlowListView. I know it has to be something with the binding and I'm trying to grab the image uri from each object to display it but I'm still pretty new to this, especially to xaml and haven't been successful with this part yet.
If you could point me in the right direction that would be sweet!
Expected Result
To display images in 2 columns using FlowListView and FFImageLoading
Actual Result
I currently an able to display a 2 column list that has the right objects tied to each item but the only way I can actually see if anything is there is if I add a frame or add a text label to each item.
The user can click on each label currently and the correct image will show.
This is part of my TicketPageModel
private void AddItems()
{
public void UpdatePhotosData()
{
//get the notes and set the source for the list to them.
photos = NLTicketPhotos.Get(_ticket).OrderByDescending(x => x.PhotoCreatedAt).ToList();
}
foreach (var i in photos)
{
Items.Add(i);
}
}
private ObservableCollection<NLTicketPhoto> _items = new ObservableCollection<NLTicketPhoto>();
public ObservableCollection<NLTicketPhoto> Items
{
get
{
return _items;
}
set
{
if (_items != value)
{
_items = value;
OnPropertyChanged(nameof(Items));
}
}
}
My XAML
<flv:FlowListView FlowColumnCount="2" SeparatorVisibility="Default" HasUnevenRows="True" FlowItemTapped="OnImageTapped" FlowItemsSource="{Binding Items}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<StackLayout Padding="10" Spacing="0" AutomationProperties.Name="Too Cool">
<ff:CachedImage Aspect="AspectFill" HeightRequest="30">
<ff:CachedImage.Source>
<UriImageSource Uri="{Binding Items.PhotoFileUrl}"/>
</ff:CachedImage.Source>
</ff:CachedImage>
<StackLayout Orientation="Horizontal" Padding="10" Spacing="0">
<Label HorizontalOptions="Fill" VerticalOptions="Fill" TextColor="Black" XAlign="Center" YAlign="Center" Text="Too Cool For School"/>
</StackLayout>
</StackLayout>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
My Code Behind
void OnImageTapped(object sender, ItemTappedEventArgs e)
{
NLTicketPhoto photo = (NLTicketPhoto)e.Item;
//listPhotos.SelectedItem = null; //deselect the item
switch (photo.PhotoFileType)
{
case "mov":
if (photo.PhotoIsOnServer)
{
Device.OpenUri(new Uri(photo.PhotoFileName));
}
else
{
//Only watch videos after sync
DisplayAlert("Video Unavailable", string.Format("This video will be viewable after it is synced to the server."), "OK");
}
break;
case "jpg":
//View image
NLPageViewPhoto preview = new NLPageViewPhoto(photo);
Navigation.PushAsync(preview);
break;
default:
DisplayAlert("Photo Unavailable", string.Format("The photo format .{0} is currently not viewable", photo.PhotoFileType), "OK");
break;
}
}
Once I implemented INotifyPropertyChanged to my NLTicketPhoto model and tweaked my PhotoUrl and PhotoDescription properties to use OnPropertyChanged() I was able to get my list to display properly.
Following this example helped me. https://www.c-sharpcorner.com/article/grid-view-in-xamarin-forms-using-flowlistview/

How to load the native camera when a user opens a xamarin forms app

hello I am working on a app that allows users to take pictures of notes and then send them to a friend. I am using xamarin forms do build this app and I am also using the media plugin to access the native camera but the user has to press a button to open the native camera so My question is how do I get the camera to load as soon as the user open's the app?
heres my xaml code:
<?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="SnapNote.CameraPage"
xmlns:local="clr-namespace:AppName;"
BackgroundColor="{x:Static local:Colors.BackgroundColor}">
<ContentPage.Padding>
<OnPlatform
x:TypeArguments="Thickness"
iOS="10,20,10,10"
Android="10,10,10,10" />
</ContentPage.Padding>
<StackLayout>
<Image Source="TakePhotoButton.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="Handle_Clicked" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="image"/>
<Image Source="SendNoteButton.png">
</Image>
</StackLayout>
</ContentPage>
and heres the code behind:
using System;
using System.Collections.Generic;
using Plugin.Media;
using Plugin.Media.Abstractions;
using Xamarin.Forms;
namespace AppName
{
public partial class CameraPage : ContentPage
{
public CameraPage()
{
InitializeComponent();
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "MyPhoto",
Name = "Nextflow.jpg",
SaveToAlbum = true
});
if (file == null)
return;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}
}
}
any help would be amazing!
Thanks in advance!
Just move your camera logic into the page's OnAppearing event
public override void OnAppearing() {
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "MyPhoto",
Name = "Nextflow.jpg",
SaveToAlbum = true
});
if (file == null)
return;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
}

Categories

Resources